summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/Kconfig108
-rw-r--r--arch/alpha/Kconfig16
-rw-r--r--arch/alpha/include/asm/page.h2
-rw-r--r--arch/alpha/kernel/smp.c5
-rw-r--r--arch/arc/Kconfig4
-rw-r--r--arch/arc/include/asm/cachetype.h9
-rw-r--r--arch/arc/include/uapi/asm/page.h6
-rw-r--r--arch/arc/kernel/smp.c5
-rw-r--r--arch/arm/Kconfig8
-rw-r--r--arch/arm/Kconfig.debug5
-rw-r--r--arch/arm/Makefile4
-rw-r--r--arch/arm/boot/compressed/misc.c2
-rw-r--r--arch/arm/boot/compressed/misc.h2
-rw-r--r--arch/arm/boot/dts/allwinner/sun8i-r40-feta40i.dtsi7
-rw-r--r--arch/arm/boot/dts/amlogic/meson.dtsi6
-rw-r--r--arch/arm/boot/dts/amlogic/meson8.dtsi1
-rw-r--r--arch/arm/boot/dts/amlogic/meson8b.dtsi1
-rw-r--r--arch/arm/boot/dts/arm/arm-realview-pb1176.dts2
-rw-r--r--arch/arm/boot/dts/arm/integratorap-im-pd1.dts3
-rw-r--r--arch/arm/boot/dts/arm/versatile-ab.dts3
-rw-r--r--arch/arm/boot/dts/arm/vexpress-v2p-ca9.dts4
-rw-r--r--arch/arm/boot/dts/broadcom/bcm47622.dtsi14
-rw-r--r--arch/arm/boot/dts/broadcom/bcm63138.dtsi7
-rw-r--r--arch/arm/boot/dts/broadcom/bcm63148.dtsi14
-rw-r--r--arch/arm/boot/dts/broadcom/bcm63178.dtsi14
-rw-r--r--arch/arm/boot/dts/broadcom/bcm6756.dtsi14
-rw-r--r--arch/arm/boot/dts/broadcom/bcm6846.dtsi14
-rw-r--r--arch/arm/boot/dts/broadcom/bcm6855.dtsi14
-rw-r--r--arch/arm/boot/dts/broadcom/bcm6878.dtsi14
-rw-r--r--arch/arm/boot/dts/broadcom/bcm947622.dts10
-rw-r--r--arch/arm/boot/dts/broadcom/bcm963138.dts10
-rw-r--r--arch/arm/boot/dts/broadcom/bcm963138dvt.dts14
-rw-r--r--arch/arm/boot/dts/broadcom/bcm963148.dts10
-rw-r--r--arch/arm/boot/dts/broadcom/bcm963178.dts10
-rw-r--r--arch/arm/boot/dts/broadcom/bcm96756.dts10
-rw-r--r--arch/arm/boot/dts/broadcom/bcm96846.dts10
-rw-r--r--arch/arm/boot/dts/broadcom/bcm96855.dts10
-rw-r--r--arch/arm/boot/dts/broadcom/bcm96878.dts10
-rw-r--r--arch/arm/boot/dts/gemini/gemini-dlink-dir-685.dts30
-rw-r--r--arch/arm/boot/dts/gemini/gemini-dlink-dns-313.dts4
-rw-r--r--arch/arm/boot/dts/gemini/gemini-sl93512r.dts16
-rw-r--r--arch/arm/boot/dts/gemini/gemini-sq201.dts16
-rw-r--r--arch/arm/boot/dts/gemini/gemini-wbd111.dts6
-rw-r--r--arch/arm/boot/dts/gemini/gemini-wbd222.dts6
-rw-r--r--arch/arm/boot/dts/marvell/armada-385-clearfog-gtr-l8.dts38
-rw-r--r--arch/arm/boot/dts/marvell/armada-385-clearfog-gtr-s4.dts2
-rw-r--r--arch/arm/boot/dts/marvell/armada-385-clearfog-gtr.dtsi84
-rw-r--r--arch/arm/boot/dts/marvell/armada-388-clearfog.dts5
-rw-r--r--arch/arm/boot/dts/marvell/dove-cubox.dts4
-rw-r--r--arch/arm/boot/dts/marvell/mmp2-brownstone.dts2
-rw-r--r--arch/arm/boot/dts/microchip/Makefile2
-rw-r--r--arch/arm/boot/dts/microchip/at91-sama7g54_curiosity.dts482
-rw-r--r--arch/arm/boot/dts/microchip/at91sam9g25-gardena-smart-gateway.dts2
-rw-r--r--arch/arm/boot/dts/microchip/at91sam9x5ek.dtsi2
-rw-r--r--arch/arm/boot/dts/microchip/sam9x60.dtsi64
-rw-r--r--arch/arm/boot/dts/microchip/sama7g5.dtsi56
-rw-r--r--arch/arm/boot/dts/nvidia/Makefile2
-rw-r--r--arch/arm/boot/dts/nvidia/tegra124-nyan.dtsi1
-rw-r--r--arch/arm/boot/dts/nvidia/tegra124-venice2.dts1
-rw-r--r--arch/arm/boot/dts/nvidia/tegra30-asus-nexus7-grouper-common.dtsi3
-rw-r--r--arch/arm/boot/dts/nvidia/tegra30-lg-p880.dts489
-rw-r--r--arch/arm/boot/dts/nvidia/tegra30-lg-p895.dts496
-rw-r--r--arch/arm/boot/dts/nvidia/tegra30-lg-x3.dtsi1812
-rw-r--r--arch/arm/boot/dts/nxp/imx/Makefile6
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx1-apf9328.dts2
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx1.dtsi2
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx27.dtsi2
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx31.dtsi2
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx35.dtsi2
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx51.dtsi2
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx53-qsb-hdmi.dtso87
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6dl-sielaff.dts533
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi25
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6q-apalis-eval-v1.2.dts200
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6q-apalis-eval.dts108
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6q-apalis-eval.dtsi120
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-hummingboard.dtsi7
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-hummingboard2.dtsi5
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl-skov-cpu.dtsi10
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi2
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6sl-tolino-shine2hd.dts6
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6sl.dtsi2
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6sx.dtsi2
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi2
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts2
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6uldev.dtsi2
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ul.dtsi18
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ull-dhcom-som-cfg-sdcard.dtsi4
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ull-dhcom-som.dtsi4
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ull-dhcor-som.dtsi7
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx6ull.dtsi2
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx7-mba7.dtsi325
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx7-tqma7.dtsi144
-rw-r--r--arch/arm/boot/dts/nxp/imx/imx7d-mba7.dts94
-rw-r--r--arch/arm/boot/dts/nxp/ls/ls1021a.dtsi2
-rw-r--r--arch/arm/boot/dts/nxp/mxs/imx28-evk.dts2
-rw-r--r--arch/arm/boot/dts/qcom/Makefile1
-rw-r--r--arch/arm/boot/dts/qcom/qcom-apq8026-lg-lenok.dts38
-rw-r--r--arch/arm/boot/dts/qcom/qcom-apq8026-samsung-matisse-wifi.dts452
-rw-r--r--arch/arm/boot/dts/qcom/qcom-apq8064.dtsi70
-rw-r--r--arch/arm/boot/dts/qcom/qcom-apq8084.dtsi13
-rw-r--r--arch/arm/boot/dts/qcom/qcom-ipq4019-ap.dk01.1.dtsi138
-rw-r--r--arch/arm/boot/dts/qcom/qcom-ipq4019.dtsi35
-rw-r--r--arch/arm/boot/dts/qcom/qcom-ipq8064.dtsi12
-rw-r--r--arch/arm/boot/dts/qcom/qcom-msm8226-samsung-matisse-common.dtsi457
-rw-r--r--arch/arm/boot/dts/qcom/qcom-msm8226.dtsi734
-rw-r--r--arch/arm/boot/dts/qcom/qcom-msm8660.dtsi17
-rw-r--r--arch/arm/boot/dts/qcom/qcom-msm8926-htc-memul.dts15
-rw-r--r--arch/arm/boot/dts/qcom/qcom-msm8926-samsung-matisselte.dts37
-rw-r--r--arch/arm/boot/dts/qcom/qcom-msm8960-pins.dtsi21
-rw-r--r--arch/arm/boot/dts/qcom/qcom-msm8960-samsung-expressatt.dts71
-rw-r--r--arch/arm/boot/dts/qcom/qcom-msm8960.dtsi48
-rw-r--r--arch/arm/boot/dts/qcom/qcom-msm8974.dtsi33
-rw-r--r--arch/arm/boot/dts/qcom/qcom-sdx55.dtsi32
-rw-r--r--arch/arm/boot/dts/qcom/qcom-sdx65.dtsi48
-rw-r--r--arch/arm/boot/dts/renesas/r8a73a4-ape6evm.dts12
-rw-r--r--arch/arm/boot/dts/renesas/r8a73a4.dtsi23
-rw-r--r--arch/arm/boot/dts/renesas/r8a7740.dtsi2
-rw-r--r--arch/arm/boot/dts/renesas/r8a7778.dtsi11
-rw-r--r--arch/arm/boot/dts/renesas/r8a7779.dtsi9
-rw-r--r--arch/arm/boot/dts/rockchip/rk3128-xpi-3128.dts29
-rw-r--r--arch/arm/boot/dts/rockchip/rk3128.dtsi60
-rw-r--r--arch/arm/boot/dts/rockchip/rk322x.dtsi16
-rw-r--r--arch/arm/boot/dts/rockchip/rk3288.dtsi16
-rw-r--r--arch/arm/boot/dts/rockchip/rv1126-sonoff-ihost.dtsi10
-rw-r--r--arch/arm/boot/dts/samsung/exynos4412-i9300.dts2
-rw-r--r--arch/arm/boot/dts/samsung/exynos4412-i9305.dts2
-rw-r--r--arch/arm/boot/dts/samsung/exynos4412-n710x.dts2
-rw-r--r--arch/arm/boot/dts/samsung/exynos4412-p4note.dtsi53
-rw-r--r--arch/arm/boot/dts/samsung/exynos5420-galaxy-tab-common.dtsi34
-rw-r--r--arch/arm/boot/dts/samsung/exynos5420-peach-pit.dts1
-rw-r--r--arch/arm/boot/dts/samsung/exynos5422-odroidxu3-common.dtsi16
-rw-r--r--arch/arm/boot/dts/samsung/exynos5800-peach-pi.dts1
-rw-r--r--arch/arm/boot/dts/st/Makefile1
-rw-r--r--arch/arm/boot/dts/st/stih407-pinctrl.dtsi8
-rw-r--r--arch/arm/boot/dts/st/stm32f769-disco-mb1166-reva09.dts13
-rw-r--r--arch/arm/boot/dts/st/stm32f769-disco.dts70
-rw-r--r--arch/arm/boot/dts/st/stm32f769.dtsi20
-rw-r--r--arch/arm/boot/dts/st/stm32mp131.dtsi7
-rw-r--r--arch/arm/boot/dts/st/stm32mp135f-dk.dts8
-rw-r--r--arch/arm/boot/dts/st/stm32mp157.dtsi2
-rw-r--r--arch/arm/boot/dts/st/stm32mp157a-dk1-scmi.dts2
-rw-r--r--arch/arm/boot/dts/st/stm32mp157c-dk2-scmi.dts2
-rw-r--r--arch/arm/boot/dts/st/stm32mp157c-ed1-scmi.dts2
-rw-r--r--arch/arm/boot/dts/st/stm32mp157c-ev1-scmi.dts2
-rw-r--r--arch/arm/boot/dts/st/stm32mp157c-lxa-tac-gen2.dts2
-rw-r--r--arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi6
-rw-r--r--arch/arm/boot/dts/ti/davinci/da850.dtsi4
-rw-r--r--arch/arm/boot/dts/ti/keystone/keystone-clocks.dtsi2
-rw-r--r--arch/arm/boot/dts/ti/keystone/keystone-k2e-clocks.dtsi2
-rw-r--r--arch/arm/boot/dts/ti/keystone/keystone-k2e-evm.dts2
-rw-r--r--arch/arm/boot/dts/ti/keystone/keystone-k2e-netcp.dtsi2
-rw-r--r--arch/arm/boot/dts/ti/keystone/keystone-k2e.dtsi2
-rw-r--r--arch/arm/boot/dts/ti/keystone/keystone-k2g-evm.dts2
-rw-r--r--arch/arm/boot/dts/ti/keystone/keystone-k2g-ice.dts2
-rw-r--r--arch/arm/boot/dts/ti/keystone/keystone-k2g-netcp.dtsi2
-rw-r--r--arch/arm/boot/dts/ti/keystone/keystone-k2g.dtsi2
-rw-r--r--arch/arm/boot/dts/ti/keystone/keystone-k2hk-clocks.dtsi2
-rw-r--r--arch/arm/boot/dts/ti/keystone/keystone-k2hk-evm.dts2
-rw-r--r--arch/arm/boot/dts/ti/keystone/keystone-k2hk-netcp.dtsi2
-rw-r--r--arch/arm/boot/dts/ti/keystone/keystone-k2hk.dtsi2
-rw-r--r--arch/arm/boot/dts/ti/keystone/keystone-k2l-clocks.dtsi2
-rw-r--r--arch/arm/boot/dts/ti/keystone/keystone-k2l-evm.dts2
-rw-r--r--arch/arm/boot/dts/ti/keystone/keystone-k2l-netcp.dtsi2
-rw-r--r--arch/arm/boot/dts/ti/keystone/keystone-k2l.dtsi2
-rw-r--r--arch/arm/boot/dts/ti/keystone/keystone.dtsi2
-rw-r--r--arch/arm/boot/dts/ti/omap/am335x-baltos-ir2110.dts2
-rw-r--r--arch/arm/boot/dts/ti/omap/am335x-baltos-ir3220.dts2
-rw-r--r--arch/arm/boot/dts/ti/omap/am335x-baltos-ir5221.dts2
-rw-r--r--arch/arm/boot/dts/ti/omap/am335x-baltos-leds.dtsi2
-rw-r--r--arch/arm/boot/dts/ti/omap/am335x-baltos.dtsi2
-rw-r--r--arch/arm/boot/dts/ti/omap/am335x-base0033.dts2
-rw-r--r--arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi4
-rw-r--r--arch/arm/boot/dts/ti/omap/am335x-cm-t335.dts2
-rw-r--r--arch/arm/boot/dts/ti/omap/am335x-evmsk.dts2
-rw-r--r--arch/arm/boot/dts/ti/omap/am335x-guardian.dts4
-rw-r--r--arch/arm/boot/dts/ti/omap/am335x-icev2.dts2
-rw-r--r--arch/arm/boot/dts/ti/omap/am335x-igep0033.dtsi2
-rw-r--r--arch/arm/boot/dts/ti/omap/am335x-myirtech-myc.dtsi2
-rw-r--r--arch/arm/boot/dts/ti/omap/am335x-myirtech-myd.dts2
-rw-r--r--arch/arm/boot/dts/ti/omap/am335x-nano.dts2
-rw-r--r--arch/arm/boot/dts/ti/omap/am335x-netcan-plus-1xx.dts2
-rw-r--r--arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts2
-rw-r--r--arch/arm/boot/dts/ti/omap/am335x-netcom-plus-8xx.dts2
-rw-r--r--arch/arm/boot/dts/ti/omap/am335x-pdu001.dts2
-rw-r--r--arch/arm/boot/dts/ti/omap/am335x-sancloud-bbe-extended-wifi.dts2
-rw-r--r--arch/arm/boot/dts/ti/omap/am335x-sancloud-bbe-lite.dts2
-rw-r--r--arch/arm/boot/dts/ti/omap/am335x-sbc-t335.dts2
-rw-r--r--arch/arm/boot/dts/ti/omap/am335x-sl50.dts3
-rw-r--r--arch/arm/boot/dts/ti/omap/am33xx-clocks.dtsi39
-rw-r--r--arch/arm/boot/dts/ti/omap/am33xx.dtsi9
-rw-r--r--arch/arm/boot/dts/ti/omap/am3517.dtsi11
-rw-r--r--arch/arm/boot/dts/ti/omap/am35xx-clocks.dtsi18
-rw-r--r--arch/arm/boot/dts/ti/omap/am4372.dtsi6
-rw-r--r--arch/arm/boot/dts/ti/omap/am437x-cm-t43.dts2
-rw-r--r--arch/arm/boot/dts/ti/omap/am437x-sbc-t43.dts2
-rw-r--r--arch/arm/boot/dts/ti/omap/am5729-beagleboneai.dts2
-rw-r--r--arch/arm/boot/dts/ti/omap/am57xx-cl-som-am57x.dts2
-rw-r--r--arch/arm/boot/dts/ti/omap/am57xx-sbc-am57x.dts2
-rw-r--r--arch/arm/boot/dts/ti/omap/compulab-sb-som.dtsi2
-rw-r--r--arch/arm/boot/dts/ti/omap/dra7-l4.dtsi2
-rw-r--r--arch/arm/boot/dts/ti/omap/dra7.dtsi17
-rw-r--r--arch/arm/boot/dts/ti/omap/dra74x-p.dtsi2
-rw-r--r--arch/arm/boot/dts/ti/omap/dra7xx-clocks.dtsi2
-rw-r--r--arch/arm/boot/dts/ti/omap/omap3430es1-clocks.dtsi52
-rw-r--r--arch/arm/boot/dts/ti/omap/omap34xx-omap36xx-clocks.dtsi86
-rw-r--r--arch/arm/boot/dts/ti/omap/omap34xx.dtsi11
-rw-r--r--arch/arm/boot/dts/ti/omap/omap36xx-am35xx-omap3430es2plus-clocks.dtsi28
-rw-r--r--arch/arm/boot/dts/ti/omap/omap36xx-clocks.dtsi7
-rw-r--r--arch/arm/boot/dts/ti/omap/omap36xx-omap3430es2plus-clocks.dtsi46
-rw-r--r--arch/arm/boot/dts/ti/omap/omap36xx.dtsi9
-rw-r--r--arch/arm/boot/dts/ti/omap/omap3xxx-clocks.dtsi510
-rw-r--r--arch/arm/boot/dts/ti/omap/omap4-epson-embt2ws.dts1
-rw-r--r--arch/arm/boot/dts/ti/omap/omap4-panda-common.dtsi1
-rw-r--r--arch/arm/boot/dts/ti/omap/omap4-sdp.dts2
-rw-r--r--arch/arm/boot/dts/ti/omap/omap4.dtsi9
-rw-r--r--arch/arm/boot/dts/ti/omap/omap5-igep0050.dts2
-rw-r--r--arch/arm/boot/dts/ti/omap/omap5.dtsi9
-rw-r--r--arch/arm/boot/dts/ti/omap/twl4030.dtsi2
-rw-r--r--arch/arm/boot/dts/ti/omap/twl6030.dtsi4
-rw-r--r--arch/arm/configs/aspeed_g4_defconfig2
-rw-r--r--arch/arm/configs/aspeed_g5_defconfig2
-rw-r--r--arch/arm/configs/exynos_defconfig3
-rw-r--r--arch/arm/configs/imx_v6_v7_defconfig2
-rw-r--r--arch/arm/configs/multi_v7_defconfig21
-rw-r--r--arch/arm/configs/shmobile_defconfig2
-rw-r--r--arch/arm/crypto/sha256_glue.c13
-rw-r--r--arch/arm/crypto/sha512-glue.c12
-rw-r--r--arch/arm/include/asm/cachetype.h2
-rw-r--r--arch/arm/include/asm/current.h8
-rw-r--r--arch/arm/include/asm/elf.h1
-rw-r--r--arch/arm/include/asm/mman.h14
-rw-r--r--arch/arm/include/asm/page.h2
-rw-r--r--arch/arm/include/asm/pgtable-2level.h1
-rw-r--r--arch/arm/include/asm/pgtable-3level.h1
-rw-r--r--arch/arm/include/asm/pgtable.h2
-rw-r--r--arch/arm/include/asm/ptdump.h6
-rw-r--r--arch/arm/include/asm/ptrace.h5
-rw-r--r--arch/arm/include/asm/vdso_datapage.h26
-rw-r--r--arch/arm/include/asm/word-at-a-time.h3
-rw-r--r--arch/arm/include/debug/brcmstb.S8
-rw-r--r--arch/arm/kernel/Makefile3
-rw-r--r--arch/arm/kernel/asm-offsets.c4
-rw-r--r--arch/arm/kernel/iwmmxt.S51
-rw-r--r--arch/arm/kernel/machine_kexec.c7
-rw-r--r--arch/arm/kernel/pj4-cp0.c135
-rw-r--r--arch/arm/kernel/setup.c4
-rw-r--r--arch/arm/kernel/traps.c2
-rw-r--r--arch/arm/kernel/unwind.c2
-rw-r--r--arch/arm/kernel/vdso.c4
-rw-r--r--arch/arm/kernel/vmcore_info.c10
-rw-r--r--arch/arm/mach-bcm/Kconfig1
-rw-r--r--arch/arm/mach-imx/mmdc.c6
-rw-r--r--arch/arm/mach-omap1/Kconfig1
-rw-r--r--arch/arm/mach-omap2/am33xx-restart.c5
-rw-r--r--arch/arm/mach-omap2/board-generic.c6
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c2
-rw-r--r--arch/arm/mach-omap2/clockdomain.c4
-rw-r--r--arch/arm/mach-omap2/cm33xx.c2
-rw-r--r--arch/arm/mach-omap2/cminst44xx.c2
-rw-r--r--arch/arm/mach-omap2/omap-secure.c4
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c9
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_common_data.c6
-rw-r--r--arch/arm/mach-omap2/pmic-cpcap.c24
-rw-r--r--arch/arm/mach-omap2/powerdomain.c2
-rw-r--r--arch/arm/mach-omap2/prm-regbits-33xx.h1
-rw-r--r--arch/arm/mach-omap2/prm.h1
-rw-r--r--arch/arm/mach-omap2/prm33xx.c22
-rw-r--r--arch/arm/mach-omap2/prm44xx.c2
-rw-r--r--arch/arm/mach-omap2/prm_common.c10
-rw-r--r--arch/arm/mach-omap2/wd_timer.c4
-rw-r--r--arch/arm/mach-qcom/Kconfig41
-rw-r--r--arch/arm/mach-s3c/cpu.h2
-rw-r--r--arch/arm/mach-s3c/s3c6410.c2
-rw-r--r--arch/arm/mach-s3c/s3c64xx.c2
-rw-r--r--arch/arm/mach-s5pv210/pm.c2
-rw-r--r--arch/arm/mach-zynq/slcr.c5
-rw-r--r--arch/arm/mm/dump.c4
-rw-r--r--arch/arm/mm/fault.c8
-rw-r--r--arch/arm/mm/flush.c3
-rw-r--r--arch/arm/mm/init.c4
-rw-r--r--arch/arm/mm/ioremap.c8
-rw-r--r--arch/arm/mm/mmu.c2
-rw-r--r--arch/arm64/Kconfig110
-rw-r--r--arch/arm64/Makefile4
-rw-r--r--arch/arm64/boot/dts/allwinner/Makefile2
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts2
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h6-tanix.dtsi2
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi7
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1-manta.dts2
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi4
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-pi.dts2
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi155
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi75
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts144
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts23
-rw-r--r--arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts356
-rw-r--r--arch/arm64/boot/dts/amlogic/Makefile6
-rw-r--r--arch/arm64/boot/dts/amlogic/amlogic-c3.dtsi7
-rw-r--r--arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi12
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-a1-ad402.dts2
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-a1.dtsi2
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-axg-jethome-jethub-j1xx.dtsi30
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-axg-s400.dts16
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-axg.dtsi8
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi3
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-g12a-fbx8am-brcm.dtso31
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-g12a-fbx8am-realtek.dtso21
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-g12a-fbx8am.dts462
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts12
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts14
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts16
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts14
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi2
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-g12b-odroid.dtsi20
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-g12b-w400.dtsi10
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gx-libretech-pc.dtsi12
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi8
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts6
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts8
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts4
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi6
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi8
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi8
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxl-s805x-libretech-ac.dts8
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxl-s805x-p241.dts8
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxl-s905w-jethome-jethub-j80.dts8
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts6
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc-v2.dts12
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts6
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts6
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi8
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts8
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxm-s912-libretech-pc.dts2
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-khadas-vim3.dtsi16
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-libretech-cottonwood.dtsi6
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi10
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-sm1-bananapi.dtsi14
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-sm1-odroid-hc4.dts4
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi20
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts12
-rw-r--r--arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-netgear-r8000p.dts5
-rw-r--r--arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-tplink-archer-c2300-v1.dts5
-rw-r--r--arch/arm64/boot/dts/broadcom/bcmbca/bcm4908-asus-gt-ac5300.dts19
-rw-r--r--arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi7
-rw-r--r--arch/arm64/boot/dts/broadcom/bcmbca/bcm4912.dtsi14
-rw-r--r--arch/arm64/boot/dts/broadcom/bcmbca/bcm63146.dtsi14
-rw-r--r--arch/arm64/boot/dts/broadcom/bcmbca/bcm63158.dtsi14
-rw-r--r--arch/arm64/boot/dts/broadcom/bcmbca/bcm6813.dtsi14
-rw-r--r--arch/arm64/boot/dts/broadcom/bcmbca/bcm6856.dtsi14
-rw-r--r--arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi14
-rw-r--r--arch/arm64/boot/dts/broadcom/bcmbca/bcm94908.dts10
-rw-r--r--arch/arm64/boot/dts/broadcom/bcmbca/bcm94912.dts10
-rw-r--r--arch/arm64/boot/dts/broadcom/bcmbca/bcm963146.dts10
-rw-r--r--arch/arm64/boot/dts/broadcom/bcmbca/bcm963158.dts10
-rw-r--r--arch/arm64/boot/dts/broadcom/bcmbca/bcm96813.dts10
-rw-r--r--arch/arm64/boot/dts/broadcom/bcmbca/bcm96856.dts10
-rw-r--r--arch/arm64/boot/dts/broadcom/bcmbca/bcm96858.dts10
-rw-r--r--arch/arm64/boot/dts/exynos/exynos850.dtsi64
-rw-r--r--arch/arm64/boot/dts/exynos/google/gs101-oriole.dts24
-rw-r--r--arch/arm64/boot/dts/exynos/google/gs101-pinctrl.dtsi2
-rw-r--r--arch/arm64/boot/dts/exynos/google/gs101.dtsi131
-rw-r--r--arch/arm64/boot/dts/freescale/Makefile8
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi10
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi1
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi6
-rw-r--r--arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi32
-rw-r--r--arch/arm64/boot/dts/freescale/imx8-apalis-eval-v1.1.dtsi26
-rw-r--r--arch/arm64/boot/dts/freescale/imx8-apalis-eval-v1.2.dtsi124
-rw-r--r--arch/arm64/boot/dts/freescale/imx8-apalis-eval.dtsi22
-rw-r--r--arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi1
-rw-r--r--arch/arm64/boot/dts/freescale/imx8-ss-audio.dtsi330
-rw-r--r--arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi63
-rw-r--r--arch/arm64/boot/dts/freescale/imx8-ss-gpu0.dtsi27
-rw-r--r--arch/arm64/boot/dts/freescale/imx8dxl-evk.dts101
-rw-r--r--arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi77
-rw-r--r--arch/arm64/boot/dts/freescale/imx8dxl.dtsi1
-rw-r--r--arch/arm64/boot/dts/freescale/imx8dxp-tqma8xdp-mba8xx.dts16
-rw-r--r--arch/arm64/boot/dts/freescale/imx8dxp-tqma8xdp.dtsi24
-rw-r--r--arch/arm64/boot/dts/freescale/imx8dxp.dtsi24
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi69
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts294
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts38
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi567
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-kontron-sl.dtsi4
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts14
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi40
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts14
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mn-beacon-kit.dts2
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi36
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mn-rve-gateway.dts2
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx-usbotg.dtso64
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx.dts5
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mn.dtsi2
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi71
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts82
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-evk.dts33
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts107
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi1
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-venice-gw71xx.dtsi10
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi3
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mp.dtsi12
-rw-r--r--arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dts24
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qm-apalis-eval-v1.2.dts16
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qm-apalis-eval.dts2
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qm-apalis-v1.1-eval-v1.2.dts26
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qm-apalis-v1.1-eval.dts2
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qm-mek.dts26
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi5
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qm-ss-dma.dtsi55
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qm.dtsi41
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qxp-tqma8xqp-mba8xx.dts16
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qxp-tqma8xqp.dtsi14
-rw-r--r--arch/arm64/boot/dts/freescale/imx8qxp.dtsi8
-rw-r--r--arch/arm64/boot/dts/freescale/imx8ulp-evk.dts2
-rw-r--r--arch/arm64/boot/dts/freescale/imx93-phyboard-segin.dts117
-rw-r--r--arch/arm64/boot/dts/freescale/imx93-phycore-som.dtsi126
-rw-r--r--arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi4
-rw-r--r--arch/arm64/boot/dts/freescale/imx93-var-som-symphony.dts351
-rw-r--r--arch/arm64/boot/dts/freescale/imx93-var-som.dtsi110
-rw-r--r--arch/arm64/boot/dts/freescale/imx93.dtsi4
-rw-r--r--arch/arm64/boot/dts/freescale/mba8mx.dtsi21
-rw-r--r--arch/arm64/boot/dts/freescale/mba8xx.dtsi554
-rw-r--r--arch/arm64/boot/dts/freescale/tqma8xx.dtsi265
-rw-r--r--arch/arm64/boot/dts/intel/socfpga_agilex5.dtsi4
-rw-r--r--arch/arm64/boot/dts/marvell/ac5-98dx25xx.dtsi31
-rw-r--r--arch/arm64/boot/dts/marvell/ac5-98dx35xx-rd.dts4
-rw-r--r--arch/arm64/boot/dts/marvell/armada-37xx.dtsi10
-rw-r--r--arch/arm64/boot/dts/marvell/armada-ap807.dtsi3
-rw-r--r--arch/arm64/boot/dts/marvell/armada-cp11x.dtsi10
-rw-r--r--arch/arm64/boot/dts/mediatek/Makefile14
-rw-r--r--arch/arm64/boot/dts/mediatek/mt2712-evb.dts4
-rw-r--r--arch/arm64/boot/dts/mediatek/mt2712e.dtsi2
-rw-r--r--arch/arm64/boot/dts/mediatek/mt6797.dtsi8
-rw-r--r--arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts13
-rw-r--r--arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts25
-rw-r--r--arch/arm64/boot/dts/mediatek/mt7981b-xiaomi-ax3000t.dts15
-rw-r--r--arch/arm64/boot/dts/mediatek/mt7981b.dtsi105
-rw-r--r--arch/arm64/boot/dts/mediatek/mt7986a-acelink-ew-7886cax.dts173
-rw-r--r--arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3-nand.dtso2
-rw-r--r--arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts2
-rw-r--r--arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts31
-rw-r--r--arch/arm64/boot/dts/mediatek/mt7986a.dtsi180
-rw-r--r--arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts31
-rw-r--r--arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts11
-rw-r--r--arch/arm64/boot/dts/mediatek/mt7988a.dtsi136
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dts2
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi3
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8173-evb.dts2
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8173.dtsi19
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dtsi4
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi4
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi4
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi5
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts2
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8183.dtsi11
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8186-corsola-krabby.dtsi129
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8186-corsola-magneton-sku393216.dts39
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8186-corsola-magneton-sku393217.dts39
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8186-corsola-magneton-sku393218.dts26
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8186-corsola-rusty-sku196608.dts26
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8186-corsola-steelix-sku131072.dts18
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8186-corsola-steelix-sku131073.dts18
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8186-corsola-steelix.dtsi199
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8186-corsola-tentacool-sku327681.dts57
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8186-corsola-tentacool-sku327683.dts24
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8186-corsola-tentacruel-sku262144.dts44
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8186-corsola-tentacruel-sku262148.dts26
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi1681
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8186.dtsi93
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi5
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8192.dtsi10
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r1.dts4
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r2.dts4
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r3.dts4
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi27
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8195-demo.dts18
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8195-evb.dts12
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8195.dtsi128
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8395-genio-1200-evk.dts17
-rw-r--r--arch/arm64/boot/dts/mediatek/mt8395-radxa-nio-12l.dts825
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra132-norrin.dts1
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi50
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra194-p2972-0000.dts51
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra194-p3668.dtsi27
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra234-p3701.dtsi1953
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts1
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra234-p3767-0000.dtsi14
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra234-p3767-0005.dtsi14
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra234-p3767.dtsi86
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra234-p3768-0000+p3767-0000.dts7
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra234-p3768-0000+p3767-0005.dts12
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra234-sim-vdk.dts1
-rw-r--r--arch/arm64/boot/dts/nvidia/tegra234.dtsi2138
-rw-r--r--arch/arm64/boot/dts/qcom/Makefile6
-rw-r--r--arch/arm64/boot/dts/qcom/apq8016-sbc-d3-camera-mezzanine.dts8
-rw-r--r--arch/arm64/boot/dts/qcom/ipq5332.dtsi8
-rw-r--r--arch/arm64/boot/dts/qcom/ipq6018.dtsi159
-rw-r--r--arch/arm64/boot/dts/qcom/ipq8074.dtsi16
-rw-r--r--arch/arm64/boot/dts/qcom/ipq9574.dtsi12
-rw-r--r--arch/arm64/boot/dts/qcom/msm8216-samsung-fortuna3g.dts11
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-samsung-fortuna-common.dtsi203
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-samsung-gprimeltecan.dts27
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-samsung-grandprimelte.dts16
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-samsung-rossa-common.dtsi16
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916-samsung-rossa.dts16
-rw-r--r--arch/arm64/boot/dts/qcom/msm8916.dtsi9
-rw-r--r--arch/arm64/boot/dts/qcom/msm8939.dtsi11
-rw-r--r--arch/arm64/boot/dts/qcom/msm8953.dtsi155
-rw-r--r--arch/arm64/boot/dts/qcom/msm8994-msft-lumia-octagon.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/msm8994.dtsi4
-rw-r--r--arch/arm64/boot/dts/qcom/msm8996.dtsi18
-rw-r--r--arch/arm64/boot/dts/qcom/msm8998.dtsi26
-rw-r--r--arch/arm64/boot/dts/qcom/pm4125.dtsi (renamed from arch/arm64/boot/dts/qcom/pm2250.dtsi)38
-rw-r--r--arch/arm64/boot/dts/qcom/pm6150.dtsi46
-rw-r--r--arch/arm64/boot/dts/qcom/pmi632.dtsi39
-rw-r--r--arch/arm64/boot/dts/qcom/qcm2290.dtsi7
-rw-r--r--arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts56
-rw-r--r--arch/arm64/boot/dts/qcom/qcm6490-idp.dts39
-rw-r--r--arch/arm64/boot/dts/qcom/qcs404.dtsi16
-rw-r--r--arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts23
-rw-r--r--arch/arm64/boot/dts/qcom/qrb2210-rb1.dts96
-rw-r--r--arch/arm64/boot/dts/qcom/qrb4210-rb2.dts50
-rw-r--r--arch/arm64/boot/dts/qcom/sa8295p-adp.dts68
-rw-r--r--arch/arm64/boot/dts/qcom/sa8540p-ride.dts4
-rw-r--r--arch/arm64/boot/dts/qcom/sa8540p.dtsi3
-rw-r--r--arch/arm64/boot/dts/qcom/sa8775p.dtsi119
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi3
-rw-r--r--arch/arm64/boot/dts/qcom/sc7180.dtsi86
-rw-r--r--arch/arm64/boot/dts/qcom/sc7280-chrome-common.dtsi28
-rw-r--r--arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi1
-rw-r--r--arch/arm64/boot/dts/qcom/sc7280-idp-ec-h1.dtsi1
-rw-r--r--arch/arm64/boot/dts/qcom/sc7280.dtsi125
-rw-r--r--arch/arm64/boot/dts/qcom/sc8180x.dtsi141
-rw-r--r--arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts39
-rw-r--r--arch/arm64/boot/dts/qcom/sc8280xp-pmics.dtsi39
-rw-r--r--arch/arm64/boot/dts/qcom/sc8280xp.dtsi601
-rw-r--r--arch/arm64/boot/dts/qcom/sda660-inforce-ifc6560.dts5
-rw-r--r--arch/arm64/boot/dts/qcom/sdm450-motorola-ali.dts2
-rw-r--r--arch/arm64/boot/dts/qcom/sdm450.dtsi14
-rw-r--r--arch/arm64/boot/dts/qcom/sdm630-sony-xperia-nile.dtsi16
-rw-r--r--arch/arm64/boot/dts/qcom/sdm630.dtsi62
-rw-r--r--arch/arm64/boot/dts/qcom/sdm632.dtsi8
-rw-r--r--arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts6
-rw-r--r--arch/arm64/boot/dts/qcom/sdm670.dtsi14
-rw-r--r--arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi1
-rw-r--r--arch/arm64/boot/dts/qcom/sdm845-db845c.dts2
-rw-r--r--arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi8
-rw-r--r--arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts2
-rw-r--r--arch/arm64/boot/dts/qcom/sdm845.dtsi63
-rw-r--r--arch/arm64/boot/dts/qcom/sm4450.dtsi2
-rw-r--r--arch/arm64/boot/dts/qcom/sm6115.dtsi95
-rw-r--r--arch/arm64/boot/dts/qcom/sm6125.dtsi17
-rw-r--r--arch/arm64/boot/dts/qcom/sm6350.dtsi597
-rw-r--r--arch/arm64/boot/dts/qcom/sm6375.dtsi12
-rw-r--r--arch/arm64/boot/dts/qcom/sm7125-xiaomi-common.dtsi26
-rw-r--r--arch/arm64/boot/dts/qcom/sm7125-xiaomi-curtana.dts16
-rw-r--r--arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts61
-rw-r--r--arch/arm64/boot/dts/qcom/sm8150.dtsi115
-rw-r--r--arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi3
-rw-r--r--arch/arm64/boot/dts/qcom/sm8250.dtsi107
-rw-r--r--arch/arm64/boot/dts/qcom/sm8350.dtsi87
-rw-r--r--arch/arm64/boot/dts/qcom/sm8450-hdk.dts6
-rw-r--r--arch/arm64/boot/dts/qcom/sm8450.dtsi81
-rw-r--r--arch/arm64/boot/dts/qcom/sm8550-hdk.dts1306
-rw-r--r--arch/arm64/boot/dts/qcom/sm8550-mtp.dts11
-rw-r--r--arch/arm64/boot/dts/qcom/sm8550-qrd.dts53
-rw-r--r--arch/arm64/boot/dts/qcom/sm8550.dtsi189
-rw-r--r--arch/arm64/boot/dts/qcom/sm8650-mtp.dts155
-rw-r--r--arch/arm64/boot/dts/qcom/sm8650-qrd.dts439
-rw-r--r--arch/arm64/boot/dts/qcom/sm8650.dtsi83
-rw-r--r--arch/arm64/boot/dts/qcom/x1e80100-crd.dts450
-rw-r--r--arch/arm64/boot/dts/qcom/x1e80100-qcp.dts175
-rw-r--r--arch/arm64/boot/dts/qcom/x1e80100.dtsi1777
-rw-r--r--arch/arm64/boot/dts/renesas/Makefile8
-rw-r--r--arch/arm64/boot/dts/renesas/r8a774a1.dtsi11
-rw-r--r--arch/arm64/boot/dts/renesas/r8a774b1.dtsi11
-rw-r--r--arch/arm64/boot/dts/renesas/r8a774c0.dtsi11
-rw-r--r--arch/arm64/boot/dts/renesas/r8a774e1.dtsi11
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77951.dtsi11
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77960.dtsi11
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77961.dtsi11
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77965.dtsi11
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77970.dtsi11
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77980.dtsi17
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77990.dtsi11
-rw-r--r--arch/arm64/boot/dts/renesas/r8a77995.dtsi11
-rw-r--r--arch/arm64/boot/dts/renesas/r8a779a0.dtsi21
-rw-r--r--arch/arm64/boot/dts/renesas/r8a779f0.dtsi17
-rw-r--r--arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-cpu.dts13
-rw-r--r--arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-cpu.dtsi368
-rw-r--r--arch/arm64/boot/dts/renesas/r8a779g0-white-hawk.dts58
-rw-r--r--arch/arm64/boot/dts/renesas/r8a779g0.dtsi105
-rw-r--r--arch/arm64/boot/dts/renesas/r8a779g2-white-hawk-single.dts26
-rw-r--r--arch/arm64/boot/dts/renesas/r8a779g2.dtsi12
-rw-r--r--arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts230
-rw-r--r--arch/arm64/boot/dts/renesas/r8a779h0.dtsi664
-rw-r--r--arch/arm64/boot/dts/renesas/r9a07g043u.dtsi81
-rw-r--r--arch/arm64/boot/dts/renesas/r9a07g043u11-smarc-cru-csi-ov5645.dtso21
-rw-r--r--arch/arm64/boot/dts/renesas/r9a07g044.dtsi68
-rw-r--r--arch/arm64/boot/dts/renesas/r9a07g054.dtsi69
-rw-r--r--arch/arm64/boot/dts/renesas/r9a08g045.dtsi27
-rw-r--r--arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi14
-rw-r--r--arch/arm64/boot/dts/renesas/rzg2lc-smarc.dtsi14
-rw-r--r--arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi9
-rw-r--r--arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi53
-rw-r--r--arch/arm64/boot/dts/renesas/ulcb-kf.dtsi75
-rw-r--r--arch/arm64/boot/dts/renesas/white-hawk-common.dtsi65
-rw-r--r--arch/arm64/boot/dts/renesas/white-hawk-cpu-common.dtsi375
-rw-r--r--arch/arm64/boot/dts/renesas/white-hawk-csi-dsi.dtsi (renamed from arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-csi-dsi.dtsi)2
-rw-r--r--arch/arm64/boot/dts/renesas/white-hawk-ethernet.dtsi (renamed from arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-ethernet.dtsi)2
-rw-r--r--arch/arm64/boot/dts/rockchip/Makefile11
-rw-r--r--arch/arm64/boot/dts/rockchip/px30-ringneck-haikou.dts1
-rw-r--r--arch/arm64/boot/dts/rockchip/px30-ringneck.dtsi6
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts4
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3328.dtsi11
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts3
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts3
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4a.dts2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b.dts2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4c.dts2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3399.dtsi82
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg-arc-d.dts60
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg-arc-s.dts19
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg-arc.dtsi237
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353x.dtsi74
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg503.dts74
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-anbernic-rgxx3.dtsi74
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-pinetab2-v0.1.dts28
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-pinetab2-v2.0.dts48
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-pinetab2.dtsi943
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rgb10max3.dts87
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rgb30.dts18
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rk2023.dts18
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rk2023.dtsi18
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts2
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3568-qnap-ts433.dts86
-rw-r--r--arch/arm64/boot/dts/rockchip/rk356x.dtsi3
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-common.dtsi466
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-io.dts10
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-io.dtsi232
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-wifi.dtso56
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a.dtsi25
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6b-io.dts76
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6b.dtsi383
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts31
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts1
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts1
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts8
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dts266
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-tiger.dtsi690
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts688
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts8
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6c.dts14
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6s.dts764
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts1
-rw-r--r--arch/arm64/boot/dts/rockchip/rk3588s.dtsi24
-rw-r--r--arch/arm64/boot/dts/st/stm32mp251.dtsi12
-rw-r--r--arch/arm64/boot/dts/st/stm32mp255.dtsi17
-rw-r--r--arch/arm64/boot/dts/tesla/fsd.dtsi2
-rw-r--r--arch/arm64/boot/dts/ti/Makefile55
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62-main.dtsi30
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi5
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62-thermal.dtsi5
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi1
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi1
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62-verdin-mallow.dtsi10
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi1
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi59
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi38
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62.dtsi4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am625-beagleplay-csi2-ov5640.dtso4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am625-beagleplay-csi2-tevi-ov5640.dtso4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts54
-rw-r--r--arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts6
-rw-r--r--arch/arm64/boot/dts/ti/k3-am625-sk.dts4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am625.dtsi4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62a-main.dtsi80
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62a-mcu.dtsi4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62a-thermal.dtsi5
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62a.dtsi4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62a7-sk.dts123
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62a7.dtsi4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62p-main.dtsi154
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62p-mcu.dtsi6
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62p-thermal.dtsi5
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi5
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62p.dtsi6
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62p5-sk.dts11
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62p5.dtsi4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra-gpio-fan.dtso50
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi8
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62x-sk-csi2-imx219.dtso4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62x-sk-csi2-ov5640.dtso4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62x-sk-csi2-tevi-ov5640.dtso4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am62x-sk-hdmi-audio.dtso4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am64-main.dtsi69
-rw-r--r--arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am64-phycore-som.dtsi13
-rw-r--r--arch/arm64/boot/dts/ti/k3-am64-thermal.dtsi5
-rw-r--r--arch/arm64/boot/dts/ti/k3-am64.dtsi4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso79
-rw-r--r--arch/arm64/boot/dts/ti/k3-am642-evm.dts119
-rw-r--r--arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-pcie.dtso45
-rw-r--r--arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-usb3.dtso44
-rw-r--r--arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts292
-rw-r--r--arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-rdk.dts30
-rw-r--r--arch/arm64/boot/dts/ti/k3-am642-sk.dts14
-rw-r--r--arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi594
-rw-r--r--arch/arm64/boot/dts/ti/k3-am642-tqma64xxl-mbax4xxl.dts1
-rw-r--r--arch/arm64/boot/dts/ti/k3-am642.dtsi4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am65-iot2050-arduino-connector.dtsi768
-rw-r--r--arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg1.dtsi7
-rw-r--r--arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg2.dtsi27
-rw-r--r--arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi887
-rw-r--r--arch/arm64/boot/dts/ti/k3-am65-iot2050-dp.dtsi98
-rw-r--r--arch/arm64/boot/dts/ti/k3-am65-iot2050-usb3.dtsi27
-rw-r--r--arch/arm64/boot/dts/ti/k3-am65-main.dtsi44
-rw-r--r--arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am65.dtsi4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am652.dtsi4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-common.dtsi8
-rw-r--r--arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-pg2.dts4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic.dts7
-rw-r--r--arch/arm64/boot/dts/ti/k3-am654-base-board-rocktech-rk101-panel.dtso4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am654-base-board.dts8
-rw-r--r--arch/arm64/boot/dts/ti/k3-am654-icssg2.dtso4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am654-idk.dtso4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am654-industrial-thermal.dtsi5
-rw-r--r--arch/arm64/boot/dts/ti/k3-am654-pcie-usb2.dtso59
-rw-r--r--arch/arm64/boot/dts/ti/k3-am654-pcie-usb3.dtso61
-rw-r--r--arch/arm64/boot/dts/ti/k3-am654.dtsi4
-rw-r--r--arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-common.dtsi2
-rw-r--r--arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts22
-rw-r--r--arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-pg2.dts12
-rw-r--r--arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-sm.dts189
-rw-r--r--arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced.dts3
-rw-r--r--arch/arm64/boot/dts/ti/k3-am68-sk-base-board.dts54
-rw-r--r--arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi20
-rw-r--r--arch/arm64/boot/dts/ti/k3-am69-sk.dts253
-rw-r--r--arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts109
-rw-r--r--arch/arm64/boot/dts/ti/k3-j7200-evm-quad-port-eth-exp.dtso4
-rw-r--r--arch/arm64/boot/dts/ti/k3-j7200-main.dtsi315
-rw-r--r--arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi57
-rw-r--r--arch/arm64/boot/dts/ti/k3-j7200-som-p0.dtsi47
-rw-r--r--arch/arm64/boot/dts/ti/k3-j7200-thermal.dtsi5
-rw-r--r--arch/arm64/boot/dts/ti/k3-j7200.dtsi4
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts26
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts4
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721e-evm-gesi-exp-board.dtso4
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721e-evm-pcie0-ep.dtso4
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721e-evm-quad-port-eth-exp.dtso4
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721e-main.dtsi149
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi8
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721e-sk-csi2-dual-imx219.dtso165
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721e-sk.dts45
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721e-som-p0.dtsi22
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721e-thermal.dtsi5
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721e.dtsi4
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts31
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721s2-evm-gesi-exp-board.dtso4
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721s2-evm-pcie1-ep.dtso4
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi143
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi6
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721s2-som-p0.dtsi20
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721s2-thermal.dtsi5
-rw-r--r--arch/arm64/boot/dts/ti/k3-j721s2.dtsi4
-rw-r--r--arch/arm64/boot/dts/ti/k3-j722s-evm.dts383
-rw-r--r--arch/arm64/boot/dts/ti/k3-j722s.dtsi89
-rw-r--r--arch/arm64/boot/dts/ti/k3-j784s4-evm.dts32
-rw-r--r--arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi215
-rw-r--r--arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi6
-rw-r--r--arch/arm64/boot/dts/ti/k3-j784s4-thermal.dtsi5
-rw-r--r--arch/arm64/boot/dts/ti/k3-j784s4.dtsi6
-rw-r--r--arch/arm64/boot/dts/ti/k3-pinctrl.h7
-rw-r--r--arch/arm64/boot/dts/ti/k3-serdes.h4
-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.dtso36
-rw-r--r--arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dtso37
-rw-r--r--arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm015-dc1.dts2
-rw-r--r--arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts2
-rw-r--r--arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm019-dc5.dts4
-rw-r--r--arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts2
-rw-r--r--arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts6
-rw-r--r--arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revA.dts2
-rw-r--r--arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revC.dts2
-rw-r--r--arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts6
-rw-r--r--arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts4
-rw-r--r--arch/arm64/boot/dts/xilinx/zynqmp-zcu1275-revA.dts2
-rw-r--r--arch/arm64/boot/dts/xilinx/zynqmp.dtsi85
-rw-r--r--arch/arm64/configs/defconfig36
-rw-r--r--arch/arm64/configs/virt.config4
-rw-r--r--arch/arm64/crypto/Kconfig1
-rw-r--r--arch/arm64/crypto/aes-ce-ccm-core.S265
-rw-r--r--arch/arm64/crypto/aes-ce-ccm-glue.c154
-rw-r--r--arch/arm64/crypto/aes-glue.c1
-rw-r--r--arch/arm64/hyperv/hv_core.c14
-rw-r--r--arch/arm64/hyperv/mshyperv.c22
-rw-r--r--arch/arm64/include/asm/archrandom.h2
-rw-r--r--arch/arm64/include/asm/assembler.h59
-rw-r--r--arch/arm64/include/asm/brk-imm.h2
-rw-r--r--arch/arm64/include/asm/cpu.h4
-rw-r--r--arch/arm64/include/asm/cpufeature.h114
-rw-r--r--arch/arm64/include/asm/crash_reserve.h (renamed from arch/arm64/include/asm/crash_core.h)4
-rw-r--r--arch/arm64/include/asm/elf.h10
-rw-r--r--arch/arm64/include/asm/esr.h13
-rw-r--r--arch/arm64/include/asm/exception.h2
-rw-r--r--arch/arm64/include/asm/fixmap.h2
-rw-r--r--arch/arm64/include/asm/fpsimd.h4
-rw-r--r--arch/arm64/include/asm/hw_breakpoint.h1
-rw-r--r--arch/arm64/include/asm/hwcap.h15
-rw-r--r--arch/arm64/include/asm/hyperv-tlfs.h45
-rw-r--r--arch/arm64/include/asm/io.h12
-rw-r--r--arch/arm64/include/asm/kasan.h2
-rw-r--r--arch/arm64/include/asm/kernel-pgtable.h103
-rw-r--r--arch/arm64/include/asm/kexec.h2
-rw-r--r--arch/arm64/include/asm/kvm_arm.h6
-rw-r--r--arch/arm64/include/asm/kvm_emulate.h13
-rw-r--r--arch/arm64/include/asm/kvm_host.h100
-rw-r--r--arch/arm64/include/asm/kvm_hyp.h2
-rw-r--r--arch/arm64/include/asm/kvm_mmu.h46
-rw-r--r--arch/arm64/include/asm/kvm_nested.h1
-rw-r--r--arch/arm64/include/asm/kvm_pgtable.h2
-rw-r--r--arch/arm64/include/asm/memory.h33
-rw-r--r--arch/arm64/include/asm/mmu.h40
-rw-r--r--arch/arm64/include/asm/mmu_context.h53
-rw-r--r--arch/arm64/include/asm/mshyperv.h4
-rw-r--r--arch/arm64/include/asm/page-def.h2
-rw-r--r--arch/arm64/include/asm/patching.h2
-rw-r--r--arch/arm64/include/asm/pgalloc.h52
-rw-r--r--arch/arm64/include/asm/pgtable-hwdef.h33
-rw-r--r--arch/arm64/include/asm/pgtable-prot.h20
-rw-r--r--arch/arm64/include/asm/pgtable-types.h6
-rw-r--r--arch/arm64/include/asm/pgtable.h666
-rw-r--r--arch/arm64/include/asm/processor.h4
-rw-r--r--arch/arm64/include/asm/ptdump.h7
-rw-r--r--arch/arm64/include/asm/scs.h36
-rw-r--r--arch/arm64/include/asm/setup.h3
-rw-r--r--arch/arm64/include/asm/sysreg.h5
-rw-r--r--arch/arm64/include/asm/tlb.h3
-rw-r--r--arch/arm64/include/asm/tlbflush.h13
-rw-r--r--arch/arm64/include/asm/word-at-a-time.h3
-rw-r--r--arch/arm64/include/uapi/asm/hwcap.h15
-rw-r--r--arch/arm64/include/uapi/asm/kvm.h15
-rw-r--r--arch/arm64/include/uapi/asm/sigcontext.h8
-rw-r--r--arch/arm64/include/uapi/asm/sve_context.h11
-rw-r--r--arch/arm64/kernel/Makefile15
-rw-r--r--arch/arm64/kernel/asm-offsets.c2
-rw-r--r--arch/arm64/kernel/cpufeature.c287
-rw-r--r--arch/arm64/kernel/cpuinfo.c19
-rw-r--r--arch/arm64/kernel/efi.c4
-rw-r--r--arch/arm64/kernel/entry-common.c36
-rw-r--r--arch/arm64/kernel/fpsimd.c18
-rw-r--r--arch/arm64/kernel/head.S491
-rw-r--r--arch/arm64/kernel/hw_breakpoint.c3
-rw-r--r--arch/arm64/kernel/image-vars.h35
-rw-r--r--arch/arm64/kernel/kaslr.c4
-rw-r--r--arch/arm64/kernel/machine_kexec.c2
-rw-r--r--arch/arm64/kernel/machine_kexec_file.c10
-rw-r--r--arch/arm64/kernel/module.c2
-rw-r--r--arch/arm64/kernel/mte.c2
-rw-r--r--arch/arm64/kernel/patching.c75
-rw-r--r--arch/arm64/kernel/pi/.gitignore3
-rw-r--r--arch/arm64/kernel/pi/Makefile27
-rw-r--r--arch/arm64/kernel/pi/idreg-override.c (renamed from arch/arm64/kernel/idreg-override.c)78
-rw-r--r--arch/arm64/kernel/pi/kaslr_early.c78
-rw-r--r--arch/arm64/kernel/pi/map_kernel.c253
-rw-r--r--arch/arm64/kernel/pi/map_range.c105
-rw-r--r--arch/arm64/kernel/pi/patch-scs.c (renamed from arch/arm64/kernel/patch-scs.c)36
-rw-r--r--arch/arm64/kernel/pi/pi.h36
-rw-r--r--arch/arm64/kernel/pi/relacheck.c130
-rw-r--r--arch/arm64/kernel/pi/relocate.c64
-rw-r--r--arch/arm64/kernel/probes/kprobes.c21
-rw-r--r--arch/arm64/kernel/probes/kprobes_trampoline.S78
-rw-r--r--arch/arm64/kernel/process.c3
-rw-r--r--arch/arm64/kernel/ptrace.c55
-rw-r--r--arch/arm64/kernel/setup.c27
-rw-r--r--arch/arm64/kernel/signal.c98
-rw-r--r--arch/arm64/kernel/sleep.S3
-rw-r--r--arch/arm64/kernel/stacktrace.c26
-rw-r--r--arch/arm64/kernel/syscall.c5
-rw-r--r--arch/arm64/kernel/vdso.c5
-rw-r--r--arch/arm64/kernel/vmcore_info.c (renamed from arch/arm64/kernel/crash_core.c)3
-rw-r--r--arch/arm64/kernel/vmlinux.lds.S17
-rw-r--r--arch/arm64/kvm/Kconfig4
-rw-r--r--arch/arm64/kvm/arch_timer.c2
-rw-r--r--arch/arm64/kvm/arm.c23
-rw-r--r--arch/arm64/kvm/debug.c3
-rw-r--r--arch/arm64/kvm/emulate-nested.c231
-rw-r--r--arch/arm64/kvm/fpsimd.c3
-rw-r--r--arch/arm64/kvm/guest.c9
-rw-r--r--arch/arm64/kvm/hyp/aarch32.c4
-rw-r--r--arch/arm64/kvm/hyp/include/hyp/switch.h130
-rw-r--r--arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h24
-rw-r--r--arch/arm64/kvm/hyp/nvhe/debug-sr.c12
-rw-r--r--arch/arm64/kvm/hyp/nvhe/host.S2
-rw-r--r--arch/arm64/kvm/hyp/nvhe/mm.c4
-rw-r--r--arch/arm64/kvm/hyp/nvhe/tlb.c3
-rw-r--r--arch/arm64/kvm/hyp/pgtable.c47
-rw-r--r--arch/arm64/kvm/hyp/vhe/sysreg-sr.c2
-rw-r--r--arch/arm64/kvm/hyp/vhe/tlb.c3
-rw-r--r--arch/arm64/kvm/inject_fault.c2
-rw-r--r--arch/arm64/kvm/mmu.c35
-rw-r--r--arch/arm64/kvm/nested.c274
-rw-r--r--arch/arm64/kvm/pmu-emul.c15
-rw-r--r--arch/arm64/kvm/sys_regs.c263
-rw-r--r--arch/arm64/kvm/sys_regs.h2
-rw-r--r--arch/arm64/kvm/vgic/vgic-debug.c2
-rw-r--r--arch/arm64/kvm/vgic/vgic-init.c10
-rw-r--r--arch/arm64/kvm/vgic/vgic-its.c63
-rw-r--r--arch/arm64/kvm/vgic/vgic-v3.c3
-rw-r--r--arch/arm64/kvm/vgic/vgic.c62
-rw-r--r--arch/arm64/kvm/vgic/vgic.h15
-rw-r--r--arch/arm64/mm/Makefile1
-rw-r--r--arch/arm64/mm/contpte.c408
-rw-r--r--arch/arm64/mm/fault.c42
-rw-r--r--arch/arm64/mm/fixmap.c43
-rw-r--r--arch/arm64/mm/hugetlbpage.c47
-rw-r--r--arch/arm64/mm/init.c4
-rw-r--r--arch/arm64/mm/kasan_init.c165
-rw-r--r--arch/arm64/mm/mmap.c4
-rw-r--r--arch/arm64/mm/mmu.c275
-rw-r--r--arch/arm64/mm/pageattr.c6
-rw-r--r--arch/arm64/mm/pgd.c17
-rw-r--r--arch/arm64/mm/proc.S116
-rw-r--r--arch/arm64/mm/ptdump.c88
-rw-r--r--arch/arm64/mm/trans_pgd.c6
-rw-r--r--arch/arm64/net/bpf_jit_comp.c290
-rw-r--r--arch/arm64/tools/cpucaps3
-rw-r--r--arch/arm64/tools/sysreg88
-rw-r--r--arch/csky/Kconfig2
-rw-r--r--arch/csky/include/asm/cachetype.h9
-rw-r--r--arch/csky/include/asm/page.h7
-rw-r--r--arch/csky/include/asm/vdso.h5
-rw-r--r--arch/csky/kernel/smp.c4
-rw-r--r--arch/csky/kernel/vdso.c14
-rw-r--r--arch/hexagon/Kconfig36
-rw-r--r--arch/hexagon/include/asm/page.h12
-rw-r--r--arch/hexagon/kernel/smp.c4
-rw-r--r--arch/hexagon/kernel/vmlinux.lds.S1
-rw-r--r--arch/loongarch/Kconfig30
-rw-r--r--arch/loongarch/Kconfig.debug11
-rw-r--r--arch/loongarch/Makefile24
-rw-r--r--arch/loongarch/boot/dts/loongson-2k1000.dtsi7
-rw-r--r--arch/loongarch/boot/dts/loongson-2k2000-ref.dts33
-rw-r--r--arch/loongarch/boot/dts/loongson-2k2000.dtsi24
-rw-r--r--arch/loongarch/crypto/crc32-loongarch.c2
-rw-r--r--arch/loongarch/include/asm/Kbuild3
-rw-r--r--arch/loongarch/include/asm/addrspace.h1
-rw-r--r--arch/loongarch/include/asm/bug.h1
-rw-r--r--arch/loongarch/include/asm/cacheflush.h3
-rw-r--r--arch/loongarch/include/asm/exception.h2
-rw-r--r--arch/loongarch/include/asm/io.h22
-rw-r--r--arch/loongarch/include/asm/kfence.h9
-rw-r--r--arch/loongarch/include/asm/module.h7
-rw-r--r--arch/loongarch/include/asm/orc_header.h18
-rw-r--r--arch/loongarch/include/asm/orc_lookup.h31
-rw-r--r--arch/loongarch/include/asm/orc_types.h58
-rw-r--r--arch/loongarch/include/asm/page.h39
-rw-r--r--arch/loongarch/include/asm/percpu.h7
-rw-r--r--arch/loongarch/include/asm/pgtable.h3
-rw-r--r--arch/loongarch/include/asm/qspinlock.h18
-rw-r--r--arch/loongarch/include/asm/stackframe.h3
-rw-r--r--arch/loongarch/include/asm/thread_info.h2
-rw-r--r--arch/loongarch/include/asm/unwind.h20
-rw-r--r--arch/loongarch/include/asm/unwind_hints.h28
-rw-r--r--arch/loongarch/include/uapi/asm/kvm.h2
-rw-r--r--arch/loongarch/kernel/Makefile4
-rw-r--r--arch/loongarch/kernel/entry.S5
-rw-r--r--arch/loongarch/kernel/fpu.S7
-rw-r--r--arch/loongarch/kernel/genex.S6
-rw-r--r--arch/loongarch/kernel/lbt.S3
-rw-r--r--arch/loongarch/kernel/mcount_dyn.S6
-rw-r--r--arch/loongarch/kernel/module.c22
-rw-r--r--arch/loongarch/kernel/relocate_kernel.S7
-rw-r--r--arch/loongarch/kernel/rethook_trampoline.S1
-rw-r--r--arch/loongarch/kernel/setup.c6
-rw-r--r--arch/loongarch/kernel/stacktrace.c41
-rw-r--r--arch/loongarch/kernel/traps.c42
-rw-r--r--arch/loongarch/kernel/unwind_orc.c528
-rw-r--r--arch/loongarch/kernel/vdso.c6
-rw-r--r--arch/loongarch/kernel/vmlinux.lds.S3
-rw-r--r--arch/loongarch/kvm/Kconfig2
-rw-r--r--arch/loongarch/kvm/mmu.c2
-rw-r--r--arch/loongarch/kvm/switch.S15
-rw-r--r--arch/loongarch/kvm/timer.c43
-rw-r--r--arch/loongarch/kvm/vcpu.c33
-rw-r--r--arch/loongarch/lib/clear_user.S3
-rw-r--r--arch/loongarch/lib/copy_user.S3
-rw-r--r--arch/loongarch/lib/memcpy.S3
-rw-r--r--arch/loongarch/lib/memset.S3
-rw-r--r--arch/loongarch/mm/mmap.c4
-rw-r--r--arch/loongarch/mm/pgtable.c4
-rw-r--r--arch/loongarch/mm/tlb.c27
-rw-r--r--arch/loongarch/mm/tlbex.S9
-rw-r--r--arch/loongarch/vdso/Makefile1
-rw-r--r--arch/m68k/Kconfig4
-rw-r--r--arch/m68k/Kconfig.cpu2
-rw-r--r--arch/m68k/amiga/config.c2
-rw-r--r--arch/m68k/configs/amiga_defconfig3
-rw-r--r--arch/m68k/configs/apollo_defconfig3
-rw-r--r--arch/m68k/configs/atari_defconfig3
-rw-r--r--arch/m68k/configs/bvme6000_defconfig3
-rw-r--r--arch/m68k/configs/hp300_defconfig3
-rw-r--r--arch/m68k/configs/mac_defconfig3
-rw-r--r--arch/m68k/configs/multi_defconfig3
-rw-r--r--arch/m68k/configs/mvme147_defconfig3
-rw-r--r--arch/m68k/configs/mvme16x_defconfig3
-rw-r--r--arch/m68k/configs/q40_defconfig3
-rw-r--r--arch/m68k/configs/sun3_defconfig3
-rw-r--r--arch/m68k/configs/sun3x_defconfig3
-rw-r--r--arch/m68k/emu/nfblock.c10
-rw-r--r--arch/m68k/hp300/config.c6
-rw-r--r--arch/m68k/include/asm/cachetype.h9
-rw-r--r--arch/m68k/include/asm/page.h6
-rw-r--r--arch/microblaze/Kconfig1
-rw-r--r--arch/microblaze/include/asm/page.h2
-rw-r--r--arch/mips/Kbuild1
-rw-r--r--arch/mips/Kbuild.platforms1
-rw-r--r--arch/mips/Kconfig217
-rw-r--r--arch/mips/Makefile46
-rw-r--r--arch/mips/alchemy/common/clock.c2
-rw-r--r--arch/mips/boot/compressed/uart-16550.c2
-rw-r--r--arch/mips/boot/compressed/uart-alchemy.c2
-rw-r--r--arch/mips/boot/compressed/uart-prom.c2
-rw-r--r--arch/mips/boot/dts/Makefile1
-rw-r--r--arch/mips/boot/dts/mobileye/Makefile4
-rw-r--r--arch/mips/boot/dts/mobileye/eyeq5-epm5.dts23
-rw-r--r--arch/mips/boot/dts/mobileye/eyeq5-fixed-clocks.dtsi292
-rw-r--r--arch/mips/boot/dts/mobileye/eyeq5.dtsi124
-rw-r--r--arch/mips/boot/dts/ralink/mt7621.dtsi47
-rw-r--r--arch/mips/configs/eyeq5_defconfig108
-rw-r--r--arch/mips/generic/Makefile6
-rw-r--r--arch/mips/include/asm/addrspace.h5
-rw-r--r--arch/mips/include/asm/asmmacro.h22
-rw-r--r--arch/mips/include/asm/cachetype.h9
-rw-r--r--arch/mips/include/asm/cdmm.h2
-rw-r--r--arch/mips/include/asm/mach-generic/spaces.h4
-rw-r--r--arch/mips/include/asm/mips-cm.h21
-rw-r--r--arch/mips/include/asm/mips_mt.h2
-rw-r--r--arch/mips/include/asm/mipsmtregs.h256
-rw-r--r--arch/mips/include/asm/mipsregs.h278
-rw-r--r--arch/mips/include/asm/page.h16
-rw-r--r--arch/mips/include/asm/regdef.h91
-rw-r--r--arch/mips/include/asm/smp-cps.h9
-rw-r--r--arch/mips/include/asm/vdso.h5
-rw-r--r--arch/mips/include/uapi/asm/kvm.h2
-rw-r--r--arch/mips/kernel/cps-vec.S54
-rw-r--r--arch/mips/kernel/mips-cm.c10
-rw-r--r--arch/mips/kernel/mips-mt.c14
-rw-r--r--arch/mips/kernel/pm-cps.c134
-rw-r--r--arch/mips/kernel/rtlx-mt.c8
-rw-r--r--arch/mips/kernel/setup.c17
-rw-r--r--arch/mips/kernel/smp-cps.c141
-rw-r--r--arch/mips/kernel/traps.c13
-rw-r--r--arch/mips/kernel/vdso.c2
-rw-r--r--arch/mips/kernel/vpe-mt.c4
-rw-r--r--arch/mips/kvm/Kconfig3
-rw-r--r--arch/mips/kvm/entry.c431
-rw-r--r--arch/mips/loongson64/init.c2
-rw-r--r--arch/mips/mm/page.c202
-rw-r--r--arch/mips/mm/tlbex.c214
-rw-r--r--arch/mips/mobileye/Makefile1
-rw-r--r--arch/mips/mobileye/Platform15
-rw-r--r--arch/mips/mobileye/board-epm5.its.S24
-rw-r--r--arch/mips/mobileye/vmlinux.its.S32
-rw-r--r--arch/mips/pci/fixup-ath79.c2
-rw-r--r--arch/mips/pci/fixup-lantiq.c9
-rw-r--r--arch/mips/pci/ops-tx4927.c18
-rw-r--r--arch/mips/ralink/timer.c11
-rw-r--r--arch/mips/sgi-ip22/ip22-gio.c4
-rw-r--r--arch/mips/sibyte/common/sb_tbprof.c21
-rw-r--r--arch/mips/txx9/generic/setup.c2
-rw-r--r--arch/nios2/Kconfig2
-rw-r--r--arch/nios2/include/asm/cachetype.h10
-rw-r--r--arch/nios2/include/asm/page.h2
-rw-r--r--arch/nios2/include/asm/pgtable.h2
-rw-r--r--arch/nios2/kernel/prom.c6
-rw-r--r--arch/openrisc/Kconfig1
-rw-r--r--arch/openrisc/include/asm/fixmap.h31
-rw-r--r--arch/openrisc/include/asm/page.h7
-rw-r--r--arch/openrisc/kernel/setup.c6
-rw-r--r--arch/openrisc/kernel/smp.c4
-rw-r--r--arch/parisc/Kconfig10
-rw-r--r--arch/parisc/include/asm/assembly.h18
-rw-r--r--arch/parisc/include/asm/cachetype.h9
-rw-r--r--arch/parisc/include/asm/checksum.h10
-rw-r--r--arch/parisc/include/asm/mman.h14
-rw-r--r--arch/parisc/include/asm/page.h10
-rw-r--r--arch/parisc/include/asm/parisc-device.h2
-rw-r--r--arch/parisc/kernel/drivers.c2
-rw-r--r--arch/parisc/kernel/irq.c4
-rw-r--r--arch/parisc/kernel/unaligned.c34
-rw-r--r--arch/parisc/math-emu/dfsqrt.c4
-rw-r--r--arch/parisc/math-emu/fcnvff.c8
-rw-r--r--arch/parisc/math-emu/fcnvfu.c16
-rw-r--r--arch/parisc/math-emu/fcnvfut.c16
-rw-r--r--arch/parisc/math-emu/fcnvfx.c16
-rw-r--r--arch/parisc/math-emu/fcnvfxt.c16
-rw-r--r--arch/parisc/math-emu/fcnvuf.c16
-rw-r--r--arch/parisc/math-emu/fcnvxf.c16
-rw-r--r--arch/parisc/math-emu/frnd.c8
-rw-r--r--arch/parisc/math-emu/sfsqrt.c4
-rw-r--r--arch/powerpc/Kconfig38
-rw-r--r--arch/powerpc/Makefile36
-rw-r--r--arch/powerpc/boot/dts/akebono.dts6
-rw-r--r--arch/powerpc/boot/simple_alloc.c7
-rw-r--r--arch/powerpc/configs/40x.config2
-rw-r--r--arch/powerpc/configs/44x.config2
-rw-r--r--arch/powerpc/configs/85xx-32bit.config1
-rw-r--r--arch/powerpc/configs/8xx.config2
-rw-r--r--arch/powerpc/configs/ps3_defconfig1
-rw-r--r--arch/powerpc/crypto/Kconfig20
-rw-r--r--arch/powerpc/crypto/Makefile20
-rw-r--r--arch/powerpc/crypto/aes.c134
-rw-r--r--arch/powerpc/crypto/aes_cbc.c133
-rw-r--r--arch/powerpc/crypto/aes_ctr.c149
-rw-r--r--arch/powerpc/crypto/aes_xts.c162
-rw-r--r--arch/powerpc/crypto/aesp8-ppc.h30
-rw-r--r--arch/powerpc/crypto/aesp8-ppc.pl3889
-rw-r--r--arch/powerpc/crypto/ghash.c185
-rw-r--r--arch/powerpc/crypto/ghashp8-ppc.pl243
-rw-r--r--arch/powerpc/crypto/vmx.c77
-rw-r--r--arch/powerpc/include/asm/backlight.h5
-rw-r--r--arch/powerpc/include/asm/book3s/64/hash.h2
-rw-r--r--arch/powerpc/include/asm/book3s/64/pgtable-64k.h4
-rw-r--r--arch/powerpc/include/asm/book3s/64/pgtable.h36
-rw-r--r--arch/powerpc/include/asm/book3s/64/radix.h2
-rw-r--r--arch/powerpc/include/asm/cputable.h14
-rw-r--r--arch/powerpc/include/asm/ibmebus.h2
-rw-r--r--arch/powerpc/include/asm/interrupt.h2
-rw-r--r--arch/powerpc/include/asm/kexec.h98
-rw-r--r--arch/powerpc/include/asm/machdep.h1
-rw-r--r--arch/powerpc/include/asm/macio.h4
-rw-r--r--arch/powerpc/include/asm/mmu.h10
-rw-r--r--arch/powerpc/include/asm/mpic.h2
-rw-r--r--arch/powerpc/include/asm/paca.h4
-rw-r--r--arch/powerpc/include/asm/page.h2
-rw-r--r--arch/powerpc/include/asm/pgtable.h30
-rw-r--r--arch/powerpc/include/asm/ppc_asm.h26
-rw-r--r--arch/powerpc/include/asm/reg.h2
-rw-r--r--arch/powerpc/include/asm/reg_fsl_emb.h25
-rw-r--r--arch/powerpc/include/asm/set_memory.h7
-rw-r--r--arch/powerpc/include/asm/smp.h1
-rw-r--r--arch/powerpc/include/asm/switch_to.h4
-rw-r--r--arch/powerpc/include/asm/tlb.h2
-rw-r--r--arch/powerpc/include/asm/trace.h3
-rw-r--r--arch/powerpc/include/asm/vdso/gettimeofday.h3
-rw-r--r--arch/powerpc/include/asm/vio.h2
-rw-r--r--arch/powerpc/include/asm/vmalloc.h4
-rw-r--r--arch/powerpc/include/asm/word-at-a-time.h4
-rw-r--r--arch/powerpc/include/uapi/asm/kvm.h45
-rw-r--r--arch/powerpc/kernel/Makefile1
-rw-r--r--arch/powerpc/kernel/asm-offsets.c2
-rw-r--r--arch/powerpc/kernel/cpu_specs_book3s_64.h34
-rw-r--r--arch/powerpc/kernel/dt_cpu_ftrs.c10
-rw-r--r--arch/powerpc/kernel/irq.c5
-rw-r--r--arch/powerpc/kernel/isa-bridge.c4
-rw-r--r--arch/powerpc/kernel/kprobes.c10
-rw-r--r--arch/powerpc/kernel/prom.c34
-rw-r--r--arch/powerpc/kernel/prom_init.c10
-rw-r--r--arch/powerpc/kernel/secure_boot.c8
-rw-r--r--arch/powerpc/kernel/setup-common.c62
-rw-r--r--arch/powerpc/kernel/smp.c10
-rw-r--r--arch/powerpc/kernel/syscall.c2
-rw-r--r--arch/powerpc/kernel/traps.c4
-rw-r--r--arch/powerpc/kexec/Makefile4
-rw-r--r--arch/powerpc/kexec/core.c32
-rw-r--r--arch/powerpc/kexec/elf_64.c4
-rw-r--r--arch/powerpc/kexec/file_load_64.c269
-rw-r--r--arch/powerpc/kexec/ranges.c8
-rw-r--r--arch/powerpc/kexec/relocate_32.S2
-rw-r--r--arch/powerpc/kexec/vmcore_info.c32
-rw-r--r--arch/powerpc/kvm/Kconfig1
-rw-r--r--arch/powerpc/kvm/book3s_64_mmu_radix.c12
-rw-r--r--arch/powerpc/kvm/book3s_hv.c1
-rw-r--r--arch/powerpc/kvm/book3s_hv_nested.c2
-rw-r--r--arch/powerpc/kvm/powerpc.c3
-rw-r--r--arch/powerpc/lib/Makefile2
-rw-r--r--arch/powerpc/lib/copypage_power7.S12
-rw-r--r--arch/powerpc/lib/copyuser_power7.S12
-rw-r--r--arch/powerpc/lib/memcpy_power7.S10
-rw-r--r--arch/powerpc/lib/sstep.c23
-rw-r--r--arch/powerpc/mm/book3s32/mmu.c7
-rw-r--r--arch/powerpc/mm/book3s64/hash_hugepage.c15
-rw-r--r--arch/powerpc/mm/book3s64/hash_utils.c3
-rw-r--r--arch/powerpc/mm/book3s64/pgtable.c4
-rw-r--r--arch/powerpc/mm/book3s64/radix_pgtable.c30
-rw-r--r--arch/powerpc/mm/drmem.c10
-rw-r--r--arch/powerpc/mm/hugetlbpage.c6
-rw-r--r--arch/powerpc/mm/mmu_decl.h16
-rw-r--r--arch/powerpc/mm/nohash/8xx.c33
-rw-r--r--arch/powerpc/mm/nohash/e500.c10
-rw-r--r--arch/powerpc/mm/nohash/kaslr_booke.c4
-rw-r--r--arch/powerpc/mm/numa.c6
-rw-r--r--arch/powerpc/mm/pageattr.c28
-rw-r--r--arch/powerpc/mm/pgtable.c11
-rw-r--r--arch/powerpc/mm/pgtable_32.c51
-rw-r--r--arch/powerpc/mm/pgtable_64.c11
-rw-r--r--arch/powerpc/mm/ptdump/ptdump.c21
-rw-r--r--arch/powerpc/perf/core-book3s.c4
-rw-r--r--arch/powerpc/perf/hv-gpci.c29
-rw-r--r--arch/powerpc/perf/internal.h1
-rw-r--r--arch/powerpc/perf/power10-pmu.c27
-rw-r--r--arch/powerpc/platforms/40x/ppc40x_simple.c9
-rw-r--r--arch/powerpc/platforms/44x/warp.c1
-rw-r--r--arch/powerpc/platforms/512x/mpc512x_generic.c4
-rw-r--r--arch/powerpc/platforms/52xx/efika.c4
-rw-r--r--arch/powerpc/platforms/52xx/lite5200.c10
-rw-r--r--arch/powerpc/platforms/52xx/mpc5200_simple.c10
-rw-r--r--arch/powerpc/platforms/83xx/mpc830x_rdb.c10
-rw-r--r--arch/powerpc/platforms/83xx/mpc831x_rdb.c10
-rw-r--r--arch/powerpc/platforms/83xx/mpc837x_rdb.c10
-rw-r--r--arch/powerpc/platforms/83xx/suspend.c3
-rw-r--r--arch/powerpc/platforms/85xx/bsc913x_qds.c2
-rw-r--r--arch/powerpc/platforms/85xx/bsc913x_rdb.c2
-rw-r--r--arch/powerpc/platforms/85xx/corenet_generic.c2
-rw-r--r--arch/powerpc/platforms/85xx/ge_imp3a.c2
-rw-r--r--arch/powerpc/platforms/85xx/sgy_cts1000.c6
-rw-r--r--arch/powerpc/platforms/85xx/tqm85xx.c10
-rw-r--r--arch/powerpc/platforms/amigaone/setup.c8
-rw-r--r--arch/powerpc/platforms/embedded6xx/linkstation.c3
-rw-r--r--arch/powerpc/platforms/embedded6xx/mpc10x.h3
-rw-r--r--arch/powerpc/platforms/pasemi/gpio_mdio.c6
-rw-r--r--arch/powerpc/platforms/pasemi/pci.c4
-rw-r--r--arch/powerpc/platforms/powermac/Kconfig2
-rw-r--r--arch/powerpc/platforms/powermac/backlight.c26
-rw-r--r--arch/powerpc/platforms/powermac/feature.c2
-rw-r--r--arch/powerpc/platforms/powernv/opal-core.c2
-rw-r--r--arch/powerpc/platforms/powernv/opal-prd.c5
-rw-r--r--arch/powerpc/platforms/powernv/smp.c2
-rw-r--r--arch/powerpc/platforms/ps3/Kconfig1
-rw-r--r--arch/powerpc/platforms/ps3/hvcall.S298
-rw-r--r--arch/powerpc/platforms/pseries/ibmebus.c4
-rw-r--r--arch/powerpc/platforms/pseries/lparcfg.c6
-rw-r--r--arch/powerpc/platforms/pseries/msi.c11
-rw-r--r--arch/powerpc/platforms/pseries/papr_platform_attributes.c8
-rw-r--r--arch/powerpc/platforms/pseries/papr_scm.c6
-rw-r--r--arch/powerpc/platforms/pseries/setup.c12
-rw-r--r--arch/powerpc/platforms/pseries/vio.c61
-rw-r--r--arch/powerpc/sysdev/fsl_msi.c6
-rw-r--r--arch/powerpc/sysdev/mpic.c2
-rw-r--r--arch/powerpc/sysdev/pmi.c6
-rw-r--r--arch/powerpc/xmon/xmon.c12
-rw-r--r--arch/riscv/Kbuild1
-rw-r--r--arch/riscv/Kconfig103
-rw-r--r--arch/riscv/Kconfig.socs32
-rw-r--r--arch/riscv/Makefile7
-rw-r--r--arch/riscv/boot/dts/Makefile2
-rw-r--r--arch/riscv/boot/dts/canaan/Makefile2
-rw-r--r--arch/riscv/boot/dts/microchip/Makefile1
-rw-r--r--arch/riscv/boot/dts/microchip/mpfs.dtsi6
-rw-r--r--arch/riscv/boot/dts/renesas/r9a07g043f.dtsi8
-rw-r--r--arch/riscv/boot/dts/sifive/Makefile1
-rw-r--r--arch/riscv/boot/dts/sophgo/sg2042.dtsi9
-rw-r--r--arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts11
-rw-r--r--arch/riscv/boot/dts/starfive/jh7100-common.dtsi108
-rw-r--r--arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts22
-rw-r--r--arch/riscv/boot/dts/starfive/jh7100.dtsi49
-rw-r--r--arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi71
-rw-r--r--arch/riscv/boot/dts/starfive/jh7110.dtsi76
-rw-r--r--arch/riscv/configs/defconfig3
-rw-r--r--arch/riscv/configs/nommu_k210_defconfig2
-rw-r--r--arch/riscv/configs/nommu_k210_sdcard_defconfig2
-rw-r--r--arch/riscv/crypto/Kconfig93
-rw-r--r--arch/riscv/crypto/Makefile23
-rw-r--r--arch/riscv/crypto/aes-macros.S156
-rw-r--r--arch/riscv/crypto/aes-riscv64-glue.c637
-rw-r--r--arch/riscv/crypto/aes-riscv64-zvkned-zvbb-zvkg.S312
-rw-r--r--arch/riscv/crypto/aes-riscv64-zvkned-zvkb.S146
-rw-r--r--arch/riscv/crypto/aes-riscv64-zvkned.S339
-rw-r--r--arch/riscv/crypto/chacha-riscv64-glue.c101
-rw-r--r--arch/riscv/crypto/chacha-riscv64-zvkb.S294
-rw-r--r--arch/riscv/crypto/ghash-riscv64-glue.c168
-rw-r--r--arch/riscv/crypto/ghash-riscv64-zvkg.S72
-rw-r--r--arch/riscv/crypto/sha256-riscv64-glue.c137
-rw-r--r--arch/riscv/crypto/sha256-riscv64-zvknha_or_zvknhb-zvkb.S225
-rw-r--r--arch/riscv/crypto/sha512-riscv64-glue.c133
-rw-r--r--arch/riscv/crypto/sha512-riscv64-zvknhb-zvkb.S203
-rw-r--r--arch/riscv/crypto/sm3-riscv64-glue.c112
-rw-r--r--arch/riscv/crypto/sm3-riscv64-zvksh-zvkb.S123
-rw-r--r--arch/riscv/crypto/sm4-riscv64-glue.c107
-rw-r--r--arch/riscv/crypto/sm4-riscv64-zvksed-zvkb.S117
-rw-r--r--arch/riscv/errata/andes/errata.c10
-rw-r--r--arch/riscv/include/asm/asm.h10
-rw-r--r--arch/riscv/include/asm/atomic.h17
-rw-r--r--arch/riscv/include/asm/barrier.h21
-rw-r--r--arch/riscv/include/asm/bitops.h138
-rw-r--r--arch/riscv/include/asm/cfi.h17
-rw-r--r--arch/riscv/include/asm/cmpxchg.h5
-rw-r--r--arch/riscv/include/asm/compat.h19
-rw-r--r--arch/riscv/include/asm/cpufeature.h31
-rw-r--r--arch/riscv/include/asm/crash_reserve.h (renamed from arch/riscv/include/asm/crash_core.h)4
-rw-r--r--arch/riscv/include/asm/elf.h11
-rw-r--r--arch/riscv/include/asm/errata_list.h13
-rw-r--r--arch/riscv/include/asm/fence.h10
-rw-r--r--arch/riscv/include/asm/ftrace.h14
-rw-r--r--arch/riscv/include/asm/hwcap.h1
-rw-r--r--arch/riscv/include/asm/io.h8
-rw-r--r--arch/riscv/include/asm/membarrier.h50
-rw-r--r--arch/riscv/include/asm/mmio.h5
-rw-r--r--arch/riscv/include/asm/mmiowb.h2
-rw-r--r--arch/riscv/include/asm/page.h2
-rw-r--r--arch/riscv/include/asm/pgalloc.h67
-rw-r--r--arch/riscv/include/asm/pgtable-64.h2
-rw-r--r--arch/riscv/include/asm/pgtable.h42
-rw-r--r--arch/riscv/include/asm/processor.h31
-rw-r--r--arch/riscv/include/asm/ptdump.h22
-rw-r--r--arch/riscv/include/asm/simd.h4
-rw-r--r--arch/riscv/include/asm/suspend.h3
-rw-r--r--arch/riscv/include/asm/sync_core.h29
-rw-r--r--arch/riscv/include/asm/syscall_wrapper.h54
-rw-r--r--arch/riscv/include/asm/tlb.h18
-rw-r--r--arch/riscv/include/asm/uaccess.h4
-rw-r--r--arch/riscv/include/asm/vector.h11
-rw-r--r--arch/riscv/include/asm/vendorid_list.h2
-rw-r--r--arch/riscv/include/asm/word-at-a-time.h3
-rw-r--r--arch/riscv/include/uapi/asm/auxvec.h2
-rw-r--r--arch/riscv/include/uapi/asm/kvm.h3
-rw-r--r--arch/riscv/kernel/Makefile6
-rw-r--r--arch/riscv/kernel/alternative.c2
-rw-r--r--arch/riscv/kernel/cfi.c53
-rw-r--r--arch/riscv/kernel/compat_vdso/Makefile2
-rw-r--r--arch/riscv/kernel/cpufeature.c256
-rw-r--r--arch/riscv/kernel/elf_kexec.c9
-rw-r--r--arch/riscv/kernel/entry.S3
-rw-r--r--arch/riscv/kernel/mcount.S10
-rw-r--r--arch/riscv/kernel/patch.c8
-rw-r--r--arch/riscv/kernel/pi/Makefile3
-rw-r--r--arch/riscv/kernel/process.c5
-rw-r--r--arch/riscv/kernel/ptrace.c6
-rw-r--r--arch/riscv/kernel/signal.c15
-rw-r--r--arch/riscv/kernel/smpboot.c5
-rw-r--r--arch/riscv/kernel/suspend.c49
-rw-r--r--arch/riscv/kernel/sys_hwprobe.c13
-rw-r--r--arch/riscv/kernel/tests/Kconfig.debug2
-rw-r--r--arch/riscv/kernel/traps.c19
-rw-r--r--arch/riscv/kernel/traps_misaligned.c17
-rw-r--r--arch/riscv/kernel/unaligned_access_speed.c281
-rw-r--r--arch/riscv/kernel/vdso.c10
-rw-r--r--arch/riscv/kernel/vdso/Makefile1
-rw-r--r--arch/riscv/kernel/vmcore_info.c (renamed from arch/riscv/kernel/crash_core.c)3
-rw-r--r--arch/riscv/kvm/Kconfig1
-rw-r--r--arch/riscv/kvm/aia_aplic.c37
-rw-r--r--arch/riscv/kvm/vcpu_insn.c13
-rw-r--r--arch/riscv/kvm/vcpu_onereg.c6
-rw-r--r--arch/riscv/lib/csum.c7
-rw-r--r--arch/riscv/lib/uaccess_vector.S1
-rw-r--r--arch/riscv/mm/cacheflush.c4
-rw-r--r--arch/riscv/mm/context.c2
-rw-r--r--arch/riscv/mm/init.c11
-rw-r--r--arch/riscv/mm/pgtable.c2
-rw-r--r--arch/riscv/mm/ptdump.c12
-rw-r--r--arch/riscv/mm/tlbflush.c4
-rw-r--r--arch/riscv/net/bpf_jit.h136
-rw-r--r--arch/riscv/net/bpf_jit_comp32.c2
-rw-r--r--arch/riscv/net/bpf_jit_comp64.c245
-rw-r--r--arch/riscv/net/bpf_jit_core.c9
-rw-r--r--arch/s390/Kconfig24
-rw-r--r--arch/s390/Makefile11
-rw-r--r--arch/s390/boot/.gitignore1
-rw-r--r--arch/s390/boot/Makefile25
-rw-r--r--arch/s390/boot/boot.h6
-rw-r--r--arch/s390/boot/startup.c75
-rw-r--r--arch/s390/boot/vmem.c4
-rw-r--r--arch/s390/boot/vmlinux.lds.S48
-rw-r--r--arch/s390/configs/debug_defconfig4
-rw-r--r--arch/s390/configs/defconfig1
-rw-r--r--arch/s390/crypto/chacha-glue.c4
-rw-r--r--arch/s390/crypto/chacha-s390.S2
-rw-r--r--arch/s390/crypto/crc32-vx.c11
-rw-r--r--arch/s390/crypto/crc32-vx.h12
-rw-r--r--arch/s390/crypto/crc32be-vx.c (renamed from arch/s390/crypto/crc32be-vx.S)177
-rw-r--r--arch/s390/crypto/crc32le-vx.c (renamed from arch/s390/crypto/crc32le-vx.S)249
-rw-r--r--arch/s390/crypto/paes_s390.c16
-rw-r--r--arch/s390/hypfs/hypfs_diag0c.c3
-rw-r--r--arch/s390/hypfs/hypfs_sprp.c4
-rw-r--r--arch/s390/include/asm/access-regs.h38
-rw-r--r--arch/s390/include/asm/appldata.h4
-rw-r--r--arch/s390/include/asm/asm-prototypes.h2
-rw-r--r--arch/s390/include/asm/atomic.h44
-rw-r--r--arch/s390/include/asm/atomic_ops.h22
-rw-r--r--arch/s390/include/asm/bug.h4
-rw-r--r--arch/s390/include/asm/ccwdev.h3
-rw-r--r--arch/s390/include/asm/checksum.h29
-rw-r--r--arch/s390/include/asm/cio.h9
-rw-r--r--arch/s390/include/asm/diag.h15
-rw-r--r--arch/s390/include/asm/dma-types.h103
-rw-r--r--arch/s390/include/asm/eadm.h5
-rw-r--r--arch/s390/include/asm/entry-common.h5
-rw-r--r--arch/s390/include/asm/fcx.h13
-rw-r--r--arch/s390/include/asm/fpu-insn-asm.h (renamed from arch/s390/include/asm/vx-insn-asm.h)71
-rw-r--r--arch/s390/include/asm/fpu-insn.h486
-rw-r--r--arch/s390/include/asm/fpu-types.h51
-rw-r--r--arch/s390/include/asm/fpu.h295
-rw-r--r--arch/s390/include/asm/fpu/api.h126
-rw-r--r--arch/s390/include/asm/fpu/internal.h67
-rw-r--r--arch/s390/include/asm/fpu/types.h38
-rw-r--r--arch/s390/include/asm/ftrace.h2
-rw-r--r--arch/s390/include/asm/idals.h176
-rw-r--r--arch/s390/include/asm/kvm_host.h5
-rw-r--r--arch/s390/include/asm/lowcore.h2
-rw-r--r--arch/s390/include/asm/page.h32
-rw-r--r--arch/s390/include/asm/pai.h3
-rw-r--r--arch/s390/include/asm/pci.h3
-rw-r--r--arch/s390/include/asm/pgalloc.h4
-rw-r--r--arch/s390/include/asm/pgtable.h22
-rw-r--r--arch/s390/include/asm/physmem_info.h1
-rw-r--r--arch/s390/include/asm/preempt.h36
-rw-r--r--arch/s390/include/asm/processor.h13
-rw-r--r--arch/s390/include/asm/ptdump.h14
-rw-r--r--arch/s390/include/asm/ptrace.h6
-rw-r--r--arch/s390/include/asm/qdio.h17
-rw-r--r--arch/s390/include/asm/scsw.h7
-rw-r--r--arch/s390/include/asm/stacktrace.h1
-rw-r--r--arch/s390/include/asm/switch_to.h49
-rw-r--r--arch/s390/include/asm/tlb.h30
-rw-r--r--arch/s390/include/asm/vdso/data.h1
-rw-r--r--arch/s390/include/asm/vx-insn.h19
-rw-r--r--arch/s390/include/asm/word-at-a-time.h3
-rw-r--r--arch/s390/include/uapi/asm/kvm.h315
-rw-r--r--arch/s390/kernel/Makefile1
-rw-r--r--arch/s390/kernel/cache.c1
-rw-r--r--arch/s390/kernel/compat_signal.c22
-rw-r--r--arch/s390/kernel/crash_dump.c2
-rw-r--r--arch/s390/kernel/diag.c31
-rw-r--r--arch/s390/kernel/early.c3
-rw-r--r--arch/s390/kernel/entry.S93
-rw-r--r--arch/s390/kernel/entry.h1
-rw-r--r--arch/s390/kernel/fpu.c372
-rw-r--r--arch/s390/kernel/ipl.c3
-rw-r--r--arch/s390/kernel/kexec_elf.c2
-rw-r--r--arch/s390/kernel/kexec_image.c2
-rw-r--r--arch/s390/kernel/machine_kexec.c18
-rw-r--r--arch/s390/kernel/machine_kexec_file.c10
-rw-r--r--arch/s390/kernel/nmi.c168
-rw-r--r--arch/s390/kernel/os_info.c6
-rw-r--r--arch/s390/kernel/perf_pai_crypto.c93
-rw-r--r--arch/s390/kernel/perf_pai_ext.c62
-rw-r--r--arch/s390/kernel/perf_regs.c10
-rw-r--r--arch/s390/kernel/process.c31
-rw-r--r--arch/s390/kernel/ptrace.c101
-rw-r--r--arch/s390/kernel/setup.c12
-rw-r--r--arch/s390/kernel/signal.c20
-rw-r--r--arch/s390/kernel/smp.c3
-rw-r--r--arch/s390/kernel/sysinfo.c29
-rw-r--r--arch/s390/kernel/text_amode31.S2
-rw-r--r--arch/s390/kernel/time.c6
-rw-r--r--arch/s390/kernel/traps.c12
-rw-r--r--arch/s390/kernel/uprobes.c1
-rw-r--r--arch/s390/kernel/vdso.c5
-rw-r--r--arch/s390/kernel/vdso32/Makefile2
-rw-r--r--arch/s390/kernel/vdso32/vdso32.lds.S1
-rw-r--r--arch/s390/kernel/vdso64/Makefile3
-rw-r--r--arch/s390/kernel/vdso64/vdso64.lds.S1
-rw-r--r--arch/s390/kernel/vmcore_info.c21
-rw-r--r--arch/s390/kernel/vmlinux.lds.S54
-rw-r--r--arch/s390/kernel/vtime.c4
-rw-r--r--arch/s390/kvm/Kconfig1
-rw-r--r--arch/s390/kvm/diag.c2
-rw-r--r--arch/s390/kvm/gaccess.c19
-rw-r--r--arch/s390/kvm/interrupt.c10
-rw-r--r--arch/s390/kvm/kvm-s390.c39
-rw-r--r--arch/s390/kvm/kvm-s390.h18
-rw-r--r--arch/s390/kvm/priv.c4
-rw-r--r--arch/s390/kvm/sigp.c2
-rw-r--r--arch/s390/kvm/vsie.c3
-rw-r--r--arch/s390/lib/Makefile1
-rw-r--r--arch/s390/lib/csum-partial.c91
-rw-r--r--arch/s390/mm/Makefile1
-rw-r--r--arch/s390/mm/dump_pagetables.c21
-rw-r--r--arch/s390/mm/extmem.c4
-rw-r--r--arch/s390/mm/fault.c4
-rw-r--r--arch/s390/mm/gmap.c52
-rw-r--r--arch/s390/mm/hugetlbpage.c6
-rw-r--r--arch/s390/mm/init.c5
-rw-r--r--arch/s390/mm/mmap.c19
-rw-r--r--arch/s390/mm/pageattr.c4
-rw-r--r--arch/s390/mm/pgalloc.c8
-rw-r--r--arch/s390/mm/pgtable.c12
-rw-r--r--arch/s390/mm/physaddr.c15
-rw-r--r--arch/s390/mm/vmem.c74
-rw-r--r--arch/s390/net/bpf_jit_comp.c46
-rw-r--r--arch/s390/pci/pci.c20
-rw-r--r--arch/s390/pci/pci_debug.c10
-rw-r--r--arch/s390/pci/pci_event.c15
-rw-r--r--arch/s390/pci/pci_sysfs.c70
-rw-r--r--arch/s390/tools/.gitignore1
-rw-r--r--arch/s390/tools/Makefile5
-rw-r--r--arch/s390/tools/relocs.c387
-rw-r--r--arch/sh/Kconfig1
-rw-r--r--arch/sh/boot/compressed/Makefile1
-rw-r--r--arch/sh/cchips/hd6446x/hd64461.c2
-rw-r--r--arch/sh/drivers/dma/dma-sysfs.c2
-rw-r--r--arch/sh/include/asm/cachetype.h9
-rw-r--r--arch/sh/include/asm/page.h13
-rw-r--r--arch/sh/include/asm/word-at-a-time.h2
-rw-r--r--arch/sh/kernel/Makefile1
-rw-r--r--arch/sh/kernel/machine_kexec.c14
-rw-r--r--arch/sh/kernel/setup.c2
-rw-r--r--arch/sh/kernel/vmcore_info.c15
-rw-r--r--arch/sh/mm/Kconfig42
-rw-r--r--arch/sparc/Kconfig15
-rw-r--r--arch/sparc/Kconfig.debug7
-rw-r--r--arch/sparc/include/asm/cachetype.h14
-rw-r--r--arch/sparc/include/asm/hypervisor.h6
-rw-r--r--arch/sparc/include/asm/ldc.h2
-rw-r--r--arch/sparc/include/asm/mmu_context_64.h4
-rw-r--r--arch/sparc/include/asm/page_32.h2
-rw-r--r--arch/sparc/include/asm/page_64.h3
-rw-r--r--arch/sparc/include/asm/parport.h259
-rw-r--r--arch/sparc/include/asm/parport_64.h256
-rw-r--r--arch/sparc/include/asm/pgtable_64.h10
-rw-r--r--arch/sparc/include/asm/switch_to_64.h2
-rw-r--r--arch/sparc/kernel/btext.c365
-rw-r--r--arch/sparc/kernel/chmc.c2
-rw-r--r--arch/sparc/kernel/ds.c2
-rw-r--r--arch/sparc/kernel/irq_32.c6
-rw-r--r--arch/sparc/kernel/irq_64.c2
-rw-r--r--arch/sparc/kernel/kernel.h8
-rw-r--r--arch/sparc/kernel/kgdb_32.c4
-rw-r--r--arch/sparc/kernel/kprobes.c2
-rw-r--r--arch/sparc/kernel/ldc.c2
-rw-r--r--arch/sparc/kernel/leon_pci_grpci1.c2
-rw-r--r--arch/sparc/kernel/leon_pci_grpci2.c4
-rw-r--r--arch/sparc/kernel/leon_smp.c6
-rw-r--r--arch/sparc/kernel/nmi.c2
-rw-r--r--arch/sparc/kernel/of_device_64.c2
-rw-r--r--arch/sparc/kernel/pci.c2
-rw-r--r--arch/sparc/kernel/pci_impl.h4
-rw-r--r--arch/sparc/kernel/pci_schizo.c4
-rw-r--r--arch/sparc/kernel/perf_event.c2
-rw-r--r--arch/sparc/kernel/prom_irqtrans.c2
-rw-r--r--arch/sparc/kernel/psycho_common.c2
-rw-r--r--arch/sparc/kernel/setup_32.c4
-rw-r--r--arch/sparc/kernel/signal_32.c2
-rw-r--r--arch/sparc/kernel/signal_64.c2
-rw-r--r--arch/sparc/kernel/smp_64.c4
-rw-r--r--arch/sparc/kernel/vio.c2
-rw-r--r--arch/sparc/lib/Makefile4
-rw-r--r--arch/sparc/lib/cmpdi2.c28
-rw-r--r--arch/sparc/lib/ucmpdi2.c20
-rw-r--r--arch/sparc/mm/init_64.c6
-rw-r--r--arch/sparc/mm/srmmu.c2
-rw-r--r--arch/sparc/mm/tsb.c2
-rw-r--r--arch/sparc/net/bpf_jit_comp_32.c6
-rw-r--r--arch/sparc/vdso/Makefile1
-rw-r--r--arch/sparc/vdso/vma.c7
-rw-r--r--arch/um/Kconfig1
-rw-r--r--arch/um/drivers/net_kern.c2
-rw-r--r--arch/um/drivers/ubd_kern.c135
-rw-r--r--arch/um/drivers/vector_kern.c2
-rw-r--r--arch/um/drivers/vector_user.c4
-rw-r--r--arch/um/include/asm/page.h2
-rw-r--r--arch/um/include/shared/user.h3
-rw-r--r--arch/um/kernel/dtb.c16
-rw-r--r--arch/um/os-Linux/drivers/ethertap_user.c2
-rw-r--r--arch/um/os-Linux/drivers/tuntap_user.c2
-rw-r--r--arch/um/os-Linux/umid.c6
-rw-r--r--arch/x86/Kbuild2
-rw-r--r--arch/x86/Kconfig131
-rw-r--r--arch/x86/Makefile23
-rw-r--r--arch/x86/boot/compressed/Makefile2
-rw-r--r--arch/x86/boot/compressed/acpi.c2
-rw-r--r--arch/x86/boot/compressed/cmdline.c2
-rw-r--r--arch/x86/boot/compressed/efi.c2
-rw-r--r--arch/x86/boot/compressed/efi.h9
-rw-r--r--arch/x86/boot/compressed/efi_mixed.S29
-rw-r--r--arch/x86/boot/compressed/ident_map_64.c8
-rw-r--r--arch/x86/boot/compressed/misc.c58
-rw-r--r--arch/x86/boot/compressed/misc.h3
-rw-r--r--arch/x86/boot/compressed/pgtable_64.c1
-rw-r--r--arch/x86/boot/compressed/sev.c10
-rw-r--r--arch/x86/boot/header.S4
-rw-r--r--arch/x86/coco/core.c94
-rw-r--r--arch/x86/configs/i386_defconfig2
-rw-r--r--arch/x86/configs/tiny.config1
-rw-r--r--arch/x86/entry/Makefile5
-rw-r--r--arch/x86/entry/calling.h115
-rw-r--r--arch/x86/entry/common.c10
-rw-r--r--arch/x86/entry/entry.S3
-rw-r--r--arch/x86/entry/entry_32.S6
-rw-r--r--arch/x86/entry/entry_64.S90
-rw-r--r--arch/x86/entry/entry_64_compat.S16
-rw-r--r--arch/x86/entry/entry_64_fred.S131
-rw-r--r--arch/x86/entry/entry_fred.c294
-rw-r--r--arch/x86/entry/syscall_32.c21
-rw-r--r--arch/x86/entry/syscall_64.c19
-rw-r--r--arch/x86/entry/syscall_x32.c10
-rw-r--r--arch/x86/entry/thunk_32.S34
-rw-r--r--arch/x86/entry/thunk_64.S33
-rw-r--r--arch/x86/entry/vdso/Makefile60
-rw-r--r--arch/x86/entry/vdso/vma.c57
-rw-r--r--arch/x86/entry/vsyscall/vsyscall_64.c2
-rw-r--r--arch/x86/events/amd/core.c42
-rw-r--r--arch/x86/events/amd/lbr.c22
-rw-r--r--arch/x86/events/amd/uncore.c2
-rw-r--r--arch/x86/events/intel/core.c1
-rw-r--r--arch/x86/events/intel/cstate.c2
-rw-r--r--arch/x86/events/intel/ds.c9
-rw-r--r--arch/x86/events/intel/uncore.c2
-rw-r--r--arch/x86/events/intel/uncore_nhmex.c4
-rw-r--r--arch/x86/events/intel/uncore_snb.c8
-rw-r--r--arch/x86/events/intel/uncore_snbep.c18
-rw-r--r--arch/x86/events/rapl.c2
-rw-r--r--arch/x86/hyperv/hv_init.c8
-rw-r--r--arch/x86/hyperv/hv_spinlock.c3
-rw-r--r--arch/x86/hyperv/hv_vtl.c24
-rw-r--r--arch/x86/include/asm/alternative.h4
-rw-r--r--arch/x86/include/asm/apic.h22
-rw-r--r--arch/x86/include/asm/asm-prototypes.h2
-rw-r--r--arch/x86/include/asm/asm.h14
-rw-r--r--arch/x86/include/asm/barrier.h2
-rw-r--r--arch/x86/include/asm/boot.h1
-rw-r--r--arch/x86/include/asm/coco.h11
-rw-r--r--arch/x86/include/asm/cpu.h10
-rw-r--r--arch/x86/include/asm/cpufeature.h8
-rw-r--r--arch/x86/include/asm/cpufeatures.h19
-rw-r--r--arch/x86/include/asm/cpuid.h36
-rw-r--r--arch/x86/include/asm/crash_reserve.h (renamed from arch/x86/include/asm/crash_core.h)8
-rw-r--r--arch/x86/include/asm/current.h9
-rw-r--r--arch/x86/include/asm/debugreg.h24
-rw-r--r--arch/x86/include/asm/desc.h3
-rw-r--r--arch/x86/include/asm/disabled-features.h29
-rw-r--r--arch/x86/include/asm/efi.h14
-rw-r--r--arch/x86/include/asm/elf.h1
-rw-r--r--arch/x86/include/asm/extable_fixup_types.h4
-rw-r--r--arch/x86/include/asm/fpu/sched.h10
-rw-r--r--arch/x86/include/asm/fred.h97
-rw-r--r--arch/x86/include/asm/fsgsbase.h2
-rw-r--r--arch/x86/include/asm/hardirq.h2
-rw-r--r--arch/x86/include/asm/hw_irq.h2
-rw-r--r--arch/x86/include/asm/hyperv-tlfs.h145
-rw-r--r--arch/x86/include/asm/ia32.h4
-rw-r--r--arch/x86/include/asm/idtentry.h90
-rw-r--r--arch/x86/include/asm/intel-family.h1
-rw-r--r--arch/x86/include/asm/io.h2
-rw-r--r--arch/x86/include/asm/io_apic.h1
-rw-r--r--arch/x86/include/asm/iommu.h1
-rw-r--r--arch/x86/include/asm/irq.h2
-rw-r--r--arch/x86/include/asm/irq_vectors.h2
-rw-r--r--arch/x86/include/asm/kexec.h1
-rw-r--r--arch/x86/include/asm/kvm-x86-ops.h2
-rw-r--r--arch/x86/include/asm/kvm-x86-pmu-ops.h4
-rw-r--r--arch/x86/include/asm/kvm_host.h29
-rw-r--r--arch/x86/include/asm/kvmclock.h2
-rw-r--r--arch/x86/include/asm/linkage.h16
-rw-r--r--arch/x86/include/asm/local.h16
-rw-r--r--arch/x86/include/asm/mem_encrypt.h23
-rw-r--r--arch/x86/include/asm/mmu.h2
-rw-r--r--arch/x86/include/asm/mpspec.h66
-rw-r--r--arch/x86/include/asm/mshyperv.h30
-rw-r--r--arch/x86/include/asm/msr-index.h96
-rw-r--r--arch/x86/include/asm/msr.h44
-rw-r--r--arch/x86/include/asm/nmi.h3
-rw-r--r--arch/x86/include/asm/nospec-branch.h93
-rw-r--r--arch/x86/include/asm/page.h6
-rw-r--r--arch/x86/include/asm/page_types.h2
-rw-r--r--arch/x86/include/asm/pci.h13
-rw-r--r--arch/x86/include/asm/percpu.h189
-rw-r--r--arch/x86/include/asm/perf_event_p4.h4
-rw-r--r--arch/x86/include/asm/pgalloc.h2
-rw-r--r--arch/x86/include/asm/pgtable-3level.h2
-rw-r--r--arch/x86/include/asm/pgtable.h55
-rw-r--r--arch/x86/include/asm/pgtable_64.h3
-rw-r--r--arch/x86/include/asm/pgtable_64_types.h2
-rw-r--r--arch/x86/include/asm/preempt.h2
-rw-r--r--arch/x86/include/asm/processor-flags.h2
-rw-r--r--arch/x86/include/asm/processor.h48
-rw-r--r--arch/x86/include/asm/prom.h4
-rw-r--r--arch/x86/include/asm/pti.h2
-rw-r--r--arch/x86/include/asm/ptrace.h104
-rw-r--r--arch/x86/include/asm/required-features.h3
-rw-r--r--arch/x86/include/asm/resctrl.h90
-rw-r--r--arch/x86/include/asm/setup.h2
-rw-r--r--arch/x86/include/asm/setup_data.h32
-rw-r--r--arch/x86/include/asm/sev.h57
-rw-r--r--arch/x86/include/asm/smp.h11
-rw-r--r--arch/x86/include/asm/spec-ctrl.h2
-rw-r--r--arch/x86/include/asm/special_insns.h13
-rw-r--r--arch/x86/include/asm/static_call.h2
-rw-r--r--arch/x86/include/asm/suspend_32.h10
-rw-r--r--arch/x86/include/asm/svm.h8
-rw-r--r--arch/x86/include/asm/switch_to.h8
-rw-r--r--arch/x86/include/asm/syscall.h11
-rw-r--r--arch/x86/include/asm/text-patching.h2
-rw-r--r--arch/x86/include/asm/thread_info.h12
-rw-r--r--arch/x86/include/asm/topology.h90
-rw-r--r--arch/x86/include/asm/trap_pf.h20
-rw-r--r--arch/x86/include/asm/trapnr.h12
-rw-r--r--arch/x86/include/asm/tsc.h3
-rw-r--r--arch/x86/include/asm/uaccess_64.h18
-rw-r--r--arch/x86/include/asm/vmx.h17
-rw-r--r--arch/x86/include/asm/vmxfeatures.h1
-rw-r--r--arch/x86/include/asm/word-at-a-time.h3
-rw-r--r--arch/x86/include/asm/x86_init.h15
-rw-r--r--arch/x86/include/asm/xen/hypervisor.h5
-rw-r--r--arch/x86/include/uapi/asm/bootparam.h73
-rw-r--r--arch/x86/include/uapi/asm/kvm.h308
-rw-r--r--arch/x86/include/uapi/asm/kvm_para.h3
-rw-r--r--arch/x86/include/uapi/asm/processor-flags.h7
-rw-r--r--arch/x86/include/uapi/asm/setup_data.h83
-rw-r--r--arch/x86/kernel/Makefile8
-rw-r--r--arch/x86/kernel/acpi/boot.c59
-rw-r--r--arch/x86/kernel/acpi/cppc.c2
-rw-r--r--arch/x86/kernel/acpi/cstate.c4
-rw-r--r--arch/x86/kernel/acpi/wakeup_64.S24
-rw-r--r--arch/x86/kernel/alternative.c25
-rw-r--r--arch/x86/kernel/amd_nb.c4
-rw-r--r--arch/x86/kernel/apic/apic.c207
-rw-r--r--arch/x86/kernel/apic/apic_common.c15
-rw-r--r--arch/x86/kernel/apic/apic_flat_64.c16
-rw-r--r--arch/x86/kernel/apic/apic_noop.c5
-rw-r--r--arch/x86/kernel/apic/apic_numachip.c19
-rw-r--r--arch/x86/kernel/apic/bigsmp_32.c20
-rw-r--r--arch/x86/kernel/apic/io_apic.c94
-rw-r--r--arch/x86/kernel/apic/local.h5
-rw-r--r--arch/x86/kernel/apic/probe_32.c9
-rw-r--r--arch/x86/kernel/apic/x2apic_cluster.c4
-rw-r--r--arch/x86/kernel/apic/x2apic_phys.c12
-rw-r--r--arch/x86/kernel/apic/x2apic_uv_x.c69
-rw-r--r--arch/x86/kernel/apm_32.c29
-rw-r--r--arch/x86/kernel/asm-offsets.c2
-rw-r--r--arch/x86/kernel/callthunks.c38
-rw-r--r--arch/x86/kernel/cpu/Makefile15
-rw-r--r--arch/x86/kernel/cpu/acrn.c4
-rw-r--r--arch/x86/kernel/cpu/amd.c189
-rw-r--r--arch/x86/kernel/cpu/bugs.c263
-rw-r--r--arch/x86/kernel/cpu/cacheinfo.c15
-rw-r--r--arch/x86/kernel/cpu/centaur.c4
-rw-r--r--arch/x86/kernel/cpu/common.c255
-rw-r--r--arch/x86/kernel/cpu/cpu.h13
-rw-r--r--arch/x86/kernel/cpu/cpuid-deps.c2
-rw-r--r--arch/x86/kernel/cpu/debugfs.c47
-rw-r--r--arch/x86/kernel/cpu/feat_ctl.c2
-rw-r--r--arch/x86/kernel/cpu/hygon.c129
-rw-r--r--arch/x86/kernel/cpu/intel.c25
-rw-r--r--arch/x86/kernel/cpu/intel_pconfig.c2
-rw-r--r--arch/x86/kernel/cpu/mce/amd.c4
-rw-r--r--arch/x86/kernel/cpu/mce/core.c32
-rw-r--r--arch/x86/kernel/cpu/mce/inject.c8
-rw-r--r--arch/x86/kernel/cpu/microcode/intel.c2
-rw-r--r--arch/x86/kernel/cpu/mshyperv.c118
-rw-r--r--arch/x86/kernel/cpu/mtrr/generic.c3
-rw-r--r--arch/x86/kernel/cpu/rdrand.c1
-rw-r--r--arch/x86/kernel/cpu/resctrl/core.c111
-rw-r--r--arch/x86/kernel/cpu/resctrl/ctrlmondata.c48
-rw-r--r--arch/x86/kernel/cpu/resctrl/internal.h76
-rw-r--r--arch/x86/kernel/cpu/resctrl/monitor.c501
-rw-r--r--arch/x86/kernel/cpu/resctrl/pseudo_lock.c15
-rw-r--r--arch/x86/kernel/cpu/resctrl/rdtgroup.c388
-rw-r--r--arch/x86/kernel/cpu/scattered.c2
-rw-r--r--arch/x86/kernel/cpu/topology.c582
-rw-r--r--arch/x86/kernel/cpu/topology.h67
-rw-r--r--arch/x86/kernel/cpu/topology_amd.c183
-rw-r--r--arch/x86/kernel/cpu/topology_common.c220
-rw-r--r--arch/x86/kernel/cpu/topology_ext.c130
-rw-r--r--arch/x86/kernel/cpu/zhaoxin.c4
-rw-r--r--arch/x86/kernel/crash.c4
-rw-r--r--arch/x86/kernel/devicetree.c28
-rw-r--r--arch/x86/kernel/dumpstack.c2
-rw-r--r--arch/x86/kernel/e820.c17
-rw-r--r--arch/x86/kernel/eisa.c3
-rw-r--r--arch/x86/kernel/espfix_64.c8
-rw-r--r--arch/x86/kernel/fpu/bugs.c2
-rw-r--r--arch/x86/kernel/fpu/xstate.c5
-rw-r--r--arch/x86/kernel/fpu/xstate.h14
-rw-r--r--arch/x86/kernel/fred.c59
-rw-r--r--arch/x86/kernel/ftrace.c3
-rw-r--r--arch/x86/kernel/head64.c175
-rw-r--r--arch/x86/kernel/head_32.S4
-rw-r--r--arch/x86/kernel/head_64.S151
-rw-r--r--arch/x86/kernel/hpet.c2
-rw-r--r--arch/x86/kernel/idt.c6
-rw-r--r--arch/x86/kernel/irq.c4
-rw-r--r--arch/x86/kernel/irqinit.c7
-rw-r--r--arch/x86/kernel/jailhouse.c30
-rw-r--r--arch/x86/kernel/kexec-bzimage64.c9
-rw-r--r--arch/x86/kernel/kprobes/common.h2
-rw-r--r--arch/x86/kernel/kprobes/core.c109
-rw-r--r--arch/x86/kernel/kprobes/opt.c2
-rw-r--r--arch/x86/kernel/kvm.c17
-rw-r--r--arch/x86/kernel/kvmclock.c4
-rw-r--r--arch/x86/kernel/ldt.c8
-rw-r--r--arch/x86/kernel/machine_kexec_64.c3
-rw-r--r--arch/x86/kernel/mpparse.c41
-rw-r--r--arch/x86/kernel/nmi.c74
-rw-r--r--arch/x86/kernel/probe_roms.c10
-rw-r--r--arch/x86/kernel/process.c99
-rw-r--r--arch/x86/kernel/process_32.c7
-rw-r--r--arch/x86/kernel/process_64.c74
-rw-r--r--arch/x86/kernel/reboot.c4
-rw-r--r--arch/x86/kernel/setup.c34
-rw-r--r--arch/x86/kernel/sev-shared.c139
-rw-r--r--arch/x86/kernel/sev.c85
-rw-r--r--arch/x86/kernel/sev_verify_cbit.S2
-rw-r--r--arch/x86/kernel/smp.c12
-rw-r--r--arch/x86/kernel/smpboot.c272
-rw-r--r--arch/x86/kernel/static_call.c2
-rw-r--r--arch/x86/kernel/step.c2
-rw-r--r--arch/x86/kernel/sys_x86_64.c7
-rw-r--r--arch/x86/kernel/traps.c78
-rw-r--r--arch/x86/kernel/tsc.c34
-rw-r--r--arch/x86/kernel/vmcore_info_32.c (renamed from arch/x86/kernel/crash_core_32.c)2
-rw-r--r--arch/x86/kernel/vmcore_info_64.c (renamed from arch/x86/kernel/crash_core_64.c)2
-rw-r--r--arch/x86/kernel/vmlinux.lds.S11
-rw-r--r--arch/x86/kernel/vsmp_64.c13
-rw-r--r--arch/x86/kernel/x86_init.c7
-rw-r--r--arch/x86/kvm/Kconfig7
-rw-r--r--arch/x86/kvm/Makefile3
-rw-r--r--arch/x86/kvm/cpuid.c42
-rw-r--r--arch/x86/kvm/debugfs.c3
-rw-r--r--arch/x86/kvm/emulate.c47
-rw-r--r--arch/x86/kvm/kvm_emulate.h4
-rw-r--r--arch/x86/kvm/lapic.c37
-rw-r--r--arch/x86/kvm/mmu/mmu.c49
-rw-r--r--arch/x86/kvm/mmu/mmu_internal.h2
-rw-r--r--arch/x86/kvm/mmu/page_track.c68
-rw-r--r--arch/x86/kvm/mmu/tdp_mmu.c124
-rw-r--r--arch/x86/kvm/mmu/tdp_mmu.h2
-rw-r--r--arch/x86/kvm/pmu.c163
-rw-r--r--arch/x86/kvm/pmu.h57
-rw-r--r--arch/x86/kvm/reverse_cpuid.h5
-rw-r--r--arch/x86/kvm/smm.c15
-rw-r--r--arch/x86/kvm/svm/nested.c2
-rw-r--r--arch/x86/kvm/svm/pmu.c22
-rw-r--r--arch/x86/kvm/svm/sev.c95
-rw-r--r--arch/x86/kvm/svm/svm.c44
-rw-r--r--arch/x86/kvm/svm/svm.h1
-rw-r--r--arch/x86/kvm/svm/vmenter.S4
-rw-r--r--arch/x86/kvm/trace.h19
-rw-r--r--arch/x86/kvm/vmx/nested.c4
-rw-r--r--arch/x86/kvm/vmx/pmu_intel.c220
-rw-r--r--arch/x86/kvm/vmx/vmenter.S2
-rw-r--r--arch/x86/kvm/vmx/vmx.c171
-rw-r--r--arch/x86/kvm/vmx/vmx.h2
-rw-r--r--arch/x86/kvm/x86.c233
-rw-r--r--arch/x86/kvm/x86.h7
-rw-r--r--arch/x86/kvm/xen.c315
-rw-r--r--arch/x86/kvm/xen.h18
-rw-r--r--arch/x86/lib/Makefile15
-rw-r--r--arch/x86/lib/cmpxchg16b_emu.S12
-rw-r--r--arch/x86/lib/cmpxchg8b_emu.S30
-rw-r--r--arch/x86/lib/insn-eval.c6
-rw-r--r--arch/x86/lib/insn.c58
-rw-r--r--arch/x86/lib/msr-smp.c12
-rw-r--r--arch/x86/lib/msr.c6
-rw-r--r--arch/x86/lib/retpoline.S56
-rw-r--r--arch/x86/lib/x86-opcode-map.txt4
-rw-r--r--arch/x86/mm/Makefile3
-rw-r--r--arch/x86/mm/amdtopology.c34
-rw-r--r--arch/x86/mm/debug_pagetables.c4
-rw-r--r--arch/x86/mm/dump_pagetables.c28
-rw-r--r--arch/x86/mm/extable.c78
-rw-r--r--arch/x86/mm/fault.c53
-rw-r--r--arch/x86/mm/ident_map.c23
-rw-r--r--arch/x86/mm/init_32.c4
-rw-r--r--arch/x86/mm/init_64.c16
-rw-r--r--arch/x86/mm/kasan_init_64.c4
-rw-r--r--arch/x86/mm/mem_encrypt.c55
-rw-r--r--arch/x86/mm/mem_encrypt_amd.c18
-rw-r--r--arch/x86/mm/mem_encrypt_identity.c114
-rw-r--r--arch/x86/mm/numa_32.c1
-rw-r--r--arch/x86/mm/pat/memtype.c58
-rw-r--r--arch/x86/mm/pat/set_memory.c33
-rw-r--r--arch/x86/mm/pgtable.c8
-rw-r--r--arch/x86/mm/pti.c10
-rw-r--r--arch/x86/mm/tlb.c49
-rw-r--r--arch/x86/net/bpf_jit_comp.c259
-rw-r--r--arch/x86/net/bpf_jit_comp32.c2
-rw-r--r--arch/x86/pci/fixup.c48
-rw-r--r--arch/x86/platform/atom/punit_atom_debug.c54
-rw-r--r--arch/x86/platform/ce4100/ce4100.c14
-rw-r--r--arch/x86/platform/efi/efi.c5
-rw-r--r--arch/x86/platform/intel-mid/intel-mid.c5
-rw-r--r--arch/x86/platform/pvh/enlighten.c4
-rw-r--r--arch/x86/power/Makefile2
-rw-r--r--arch/x86/power/hibernate.c6
-rw-r--r--arch/x86/purgatory/Makefile2
-rw-r--r--arch/x86/realmode/rm/trampoline_64.S33
-rw-r--r--arch/x86/tools/relocs.c8
-rw-r--r--arch/x86/virt/Makefile2
-rw-r--r--arch/x86/virt/svm/Makefile3
-rw-r--r--arch/x86/virt/svm/sev.c570
-rw-r--r--arch/x86/xen/Kconfig1
-rw-r--r--arch/x86/xen/apic.c27
-rw-r--r--arch/x86/xen/enlighten.c32
-rw-r--r--arch/x86/xen/enlighten_hvm.c6
-rw-r--r--arch/x86/xen/enlighten_pv.c3
-rw-r--r--arch/x86/xen/enlighten_pvh.c69
-rw-r--r--arch/x86/xen/mmu_pv.c14
-rw-r--r--arch/x86/xen/setup.c44
-rw-r--r--arch/x86/xen/smp.c2
-rw-r--r--arch/x86/xen/smp.h2
-rw-r--r--arch/x86/xen/smp_pv.c69
-rw-r--r--arch/x86/xen/vga.c1
-rw-r--r--arch/x86/xen/xen-asm.S10
-rw-r--r--arch/x86/xen/xen-head.S2
-rw-r--r--arch/x86/xen/xen-ops.h14
-rw-r--r--arch/xtensa/Kconfig2
-rw-r--r--arch/xtensa/include/asm/cachetype.h10
-rw-r--r--arch/xtensa/include/asm/page.h2
-rw-r--r--arch/xtensa/platforms/iss/simdisk.c8
1909 files changed, 72552 insertions, 20824 deletions
diff --git a/arch/Kconfig b/arch/Kconfig
index a5af0edd3eb8..9f066785bb71 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -799,7 +799,7 @@ config CFI_CLANG
depends on ARCH_SUPPORTS_CFI_CLANG
depends on $(cc-option,-fsanitize=kcfi)
help
- This option enables Clang’s forward-edge Control Flow Integrity
+ This option enables Clang's forward-edge Control Flow Integrity
(CFI) checking, where the compiler injects a runtime check to each
indirect function call to ensure the target is a valid function with
the correct static type. This restricts possible call targets and
@@ -1078,17 +1078,107 @@ config HAVE_ARCH_COMPAT_MMAP_BASES
and vice-versa 32-bit applications to call 64-bit mmap().
Required for applications doing different bitness syscalls.
+config HAVE_PAGE_SIZE_4KB
+ bool
+
+config HAVE_PAGE_SIZE_8KB
+ bool
+
+config HAVE_PAGE_SIZE_16KB
+ bool
+
+config HAVE_PAGE_SIZE_32KB
+ bool
+
+config HAVE_PAGE_SIZE_64KB
+ bool
+
+config HAVE_PAGE_SIZE_256KB
+ bool
+
+choice
+ prompt "MMU page size"
+
+config PAGE_SIZE_4KB
+ bool "4KiB pages"
+ depends on HAVE_PAGE_SIZE_4KB
+ help
+ This option select the standard 4KiB Linux page size and the only
+ available option on many architectures. Using 4KiB page size will
+ minimize memory consumption and is therefore recommended for low
+ memory systems.
+ Some software that is written for x86 systems makes incorrect
+ assumptions about the page size and only runs on 4KiB pages.
+
+config PAGE_SIZE_8KB
+ bool "8KiB pages"
+ depends on HAVE_PAGE_SIZE_8KB
+ help
+ This option is the only supported page size on a few older
+ processors, and can be slightly faster than 4KiB pages.
+
+config PAGE_SIZE_16KB
+ bool "16KiB pages"
+ depends on HAVE_PAGE_SIZE_16KB
+ help
+ This option is usually a good compromise between memory
+ consumption and performance for typical desktop and server
+ workloads, often saving a level of page table lookups compared
+ to 4KB pages as well as reducing TLB pressure and overhead of
+ per-page operations in the kernel at the expense of a larger
+ page cache.
+
+config PAGE_SIZE_32KB
+ bool "32KiB pages"
+ depends on HAVE_PAGE_SIZE_32KB
+ help
+ Using 32KiB page size will result in slightly higher performance
+ kernel at the price of higher memory consumption compared to
+ 16KiB pages. This option is available only on cnMIPS cores.
+ Note that you will need a suitable Linux distribution to
+ support this.
+
+config PAGE_SIZE_64KB
+ bool "64KiB pages"
+ depends on HAVE_PAGE_SIZE_64KB
+ help
+ Using 64KiB page size will result in slightly higher performance
+ kernel at the price of much higher memory consumption compared to
+ 4KiB or 16KiB pages.
+ This is not suitable for general-purpose workloads but the
+ better performance may be worth the cost for certain types of
+ supercomputing or database applications that work mostly with
+ large in-memory data rather than small files.
+
+config PAGE_SIZE_256KB
+ bool "256KiB pages"
+ depends on HAVE_PAGE_SIZE_256KB
+ help
+ 256KiB pages have little practical value due to their extreme
+ memory usage. The kernel will only be able to run applications
+ that have been compiled with '-zmax-page-size' set to 256KiB
+ (the default is 64KiB or 4KiB on most architectures).
+
+endchoice
+
config PAGE_SIZE_LESS_THAN_64KB
def_bool y
- depends on !ARM64_64K_PAGES
depends on !PAGE_SIZE_64KB
- depends on !PARISC_PAGE_SIZE_64KB
depends on PAGE_SIZE_LESS_THAN_256KB
config PAGE_SIZE_LESS_THAN_256KB
def_bool y
depends on !PAGE_SIZE_256KB
+config PAGE_SHIFT
+ int
+ default 12 if PAGE_SIZE_4KB
+ default 13 if PAGE_SIZE_8KB
+ default 14 if PAGE_SIZE_16KB
+ default 15 if PAGE_SIZE_32KB
+ default 16 if PAGE_SIZE_64KB
+ default 18 if PAGE_SIZE_256KB
+
# This allows to use a set of generic functions to determine mmap base
# address by giving priority to top-down scheme only if the process
# is not in legacy mode (compat task, unlimited stack size or
@@ -1507,4 +1597,16 @@ config FUNCTION_ALIGNMENT
default 4 if FUNCTION_ALIGNMENT_4B
default 0
+config CC_HAS_MIN_FUNCTION_ALIGNMENT
+ # Detect availability of the GCC option -fmin-function-alignment which
+ # guarantees minimal alignment for all functions, unlike
+ # -falign-functions which the compiler ignores for cold functions.
+ def_bool $(cc-option, -fmin-function-alignment=8)
+
+config CC_HAS_SANE_FUNCTION_ALIGNMENT
+ # Set if the guaranteed alignment with -fmin-function-alignment is
+ # available or extra care is required in the kernel. Clang provides
+ # strict alignment always, even with -falign-functions.
+ def_bool CC_HAS_MIN_FUNCTION_ALIGNMENT || CC_IS_CLANG
+
endmenu
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index d6968d090d49..3afd042150f8 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -14,6 +14,7 @@ config ALPHA
select PCI_DOMAINS if PCI
select PCI_SYSCALL if PCI
select HAVE_ASM_MODVERSIONS
+ select HAVE_PAGE_SIZE_8KB
select HAVE_PCSPKR_PLATFORM
select HAVE_PERF_EVENTS
select NEED_DMA_MAP_STATE
@@ -338,6 +339,7 @@ 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
@@ -365,10 +367,6 @@ 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_EV4
- bool
- default y if ALPHA_LYNX && !ALPHA_EV5
-
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
@@ -393,16 +391,12 @@ config ALPHA_PRIMO
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)?"
- depends on ALPHA_SABLE
+ 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.
-config ALPHA_GAMMA
- bool
- depends on ALPHA_LYNX
- default y
-
config ALPHA_T2
bool
depends on ALPHA_SABLE || ALPHA_LYNX
diff --git a/arch/alpha/include/asm/page.h b/arch/alpha/include/asm/page.h
index 4db1ebc0ed99..70419e6be1a3 100644
--- a/arch/alpha/include/asm/page.h
+++ b/arch/alpha/include/asm/page.h
@@ -6,7 +6,7 @@
#include <asm/pal.h>
/* PAGE_SHIFT determines the page size */
-#define PAGE_SHIFT 13
+#define PAGE_SHIFT CONFIG_PAGE_SHIFT
#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index 7439b2377df5..8e9dd63b220c 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -467,11 +467,6 @@ smp_prepare_cpus(unsigned int max_cpus)
smp_num_cpus = smp_num_probed;
}
-void
-smp_prepare_boot_cpu(void)
-{
-}
-
int
__cpu_up(unsigned int cpu, struct task_struct *tidle)
{
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 1b0483c51cc1..99d2845f3feb 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -6,6 +6,7 @@
config ARC
def_bool y
select ARC_TIMERS
+ select ARCH_HAS_CPU_CACHE_ALIASING
select ARCH_HAS_CACHE_LINE_SIZE
select ARCH_HAS_DEBUG_VM_PGTABLE
select ARCH_HAS_DMA_PREP_COHERENT
@@ -284,14 +285,17 @@ choice
config ARC_PAGE_SIZE_8K
bool "8KB"
+ select HAVE_PAGE_SIZE_8KB
help
Choose between 8k vs 16k
config ARC_PAGE_SIZE_16K
+ select HAVE_PAGE_SIZE_16KB
bool "16KB"
config ARC_PAGE_SIZE_4K
bool "4KB"
+ select HAVE_PAGE_SIZE_4KB
depends on ARC_MMU_V3 || ARC_MMU_V4
endchoice
diff --git a/arch/arc/include/asm/cachetype.h b/arch/arc/include/asm/cachetype.h
new file mode 100644
index 000000000000..05fc7ed59712
--- /dev/null
+++ b/arch/arc/include/asm/cachetype.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_ARC_CACHETYPE_H
+#define __ASM_ARC_CACHETYPE_H
+
+#include <linux/types.h>
+
+#define cpu_dcache_is_aliasing() true
+
+#endif
diff --git a/arch/arc/include/uapi/asm/page.h b/arch/arc/include/uapi/asm/page.h
index 2a4ad619abfb..7fd9e741b527 100644
--- a/arch/arc/include/uapi/asm/page.h
+++ b/arch/arc/include/uapi/asm/page.h
@@ -13,10 +13,8 @@
#include <linux/const.h>
/* PAGE_SHIFT determines the page size */
-#if defined(CONFIG_ARC_PAGE_SIZE_16K)
-#define PAGE_SHIFT 14
-#elif defined(CONFIG_ARC_PAGE_SIZE_4K)
-#define PAGE_SHIFT 12
+#ifdef __KERNEL__
+#define PAGE_SHIFT CONFIG_PAGE_SHIFT
#else
/*
* Default 8k
diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
index 8d9b188caa27..b2f2c59279a6 100644
--- a/arch/arc/kernel/smp.c
+++ b/arch/arc/kernel/smp.c
@@ -39,11 +39,6 @@ struct plat_smp_ops __weak plat_smp_ops;
/* XXX: per cpu ? Only needed once in early secondary boot */
struct task_struct *secondary_idle_tsk;
-/* Called from start_kernel */
-void __init smp_prepare_boot_cpu(void)
-{
-}
-
static int __init arc_get_cpu_map(const char *name, struct cpumask *cpumask)
{
unsigned long dt_root = of_get_flat_dt_root();
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0af6709570d1..b14aed3a17ab 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -5,6 +5,7 @@ config ARM
select ARCH_32BIT_OFF_T
select ARCH_CORRECT_STACKTRACE_ON_KRETPROBE if HAVE_KRETPROBES && FRAME_POINTER && !ARM_UNWIND
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_DEBUG_VIRTUAL if MMU
@@ -29,7 +30,7 @@ config ARM
select ARCH_HAVE_NMI_SAFE_CMPXCHG if CPU_V7 || CPU_V7M || CPU_V6K
select ARCH_HAS_GCOV_PROFILE_ALL
select ARCH_KEEP_MEMBLOCK
- select ARCH_HAS_UBSAN_SANITIZE_ALL
+ select ARCH_HAS_UBSAN
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
@@ -116,6 +117,7 @@ config ARM
select HAVE_MOD_ARCH_SPECIFIC
select HAVE_NMI
select HAVE_OPTPROBES if !THUMB2_KERNEL
+ select HAVE_PAGE_SIZE_4KB
select HAVE_PCI if MMU
select HAVE_PERF_EVENTS
select HAVE_PERF_REGS
@@ -503,8 +505,8 @@ source "arch/arm/mm/Kconfig"
config IWMMXT
bool "Enable iWMMXt support"
- depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_PJ4 || CPU_PJ4B
- default y if PXA27x || PXA3xx || ARCH_MMP || CPU_PJ4 || CPU_PJ4B
+ depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK
+ default y if PXA27x || PXA3xx || ARCH_MMP
help
Enable support for iWMMXt context switching at run time if
running on a CPU that supports it.
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 5fbbac1b708b..7f47b4f335c3 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -17,7 +17,7 @@ config ARM_PTDUMP_DEBUGFS
kernel.
If in doubt, say "N"
-config DEBUG_WX
+config ARM_DEBUG_WX
bool "Warn on W+X mappings at boot"
depends on MMU
select ARM_PTDUMP_CORE
@@ -90,9 +90,6 @@ config BACKTRACE_VERBOSE
In most cases, say N here, unless you are intending to debug the
kernel and have access to the kernel binary image.
-config FRAME_POINTER
- bool
-
config DEBUG_USER
bool "Verbose user fault messages"
help
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 473280d5adce..d82908b1b1bb 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -158,9 +158,7 @@ textofs-$(CONFIG_ARCH_REALTEK) := 0x00108000
ifeq ($(CONFIG_ARCH_SA1100),y)
textofs-$(CONFIG_SA1111) := 0x00208000
endif
-textofs-$(CONFIG_ARCH_IPQ40XX) := 0x00208000
-textofs-$(CONFIG_ARCH_MSM8X60) := 0x00208000
-textofs-$(CONFIG_ARCH_MSM8960) := 0x00208000
+textofs-$(CONFIG_ARCH_QCOM_RESERVE_SMEM) := 0x00208000
textofs-$(CONFIG_ARCH_MESON) := 0x00208000
textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000
diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c
index 6b4baa6a9a50..6c41b270560e 100644
--- a/arch/arm/boot/compressed/misc.c
+++ b/arch/arm/boot/compressed/misc.c
@@ -154,7 +154,7 @@ decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
putstr(" done, booting the kernel.\n");
}
-void fortify_panic(const char *name)
+void __fortify_panic(const u8 reason, size_t avail, size_t size)
{
error("detected buffer overflow");
}
diff --git a/arch/arm/boot/compressed/misc.h b/arch/arm/boot/compressed/misc.h
index 6da00a26ac08..8c73940b5fe4 100644
--- a/arch/arm/boot/compressed/misc.h
+++ b/arch/arm/boot/compressed/misc.h
@@ -10,7 +10,7 @@ void __div0(void);
void
decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
unsigned long free_mem_ptr_end_p, int arch_id);
-void fortify_panic(const char *name);
+void __fortify_panic(const u8 reason, size_t avail, size_t size);
int atags_to_fdt(void *atag_list, void *fdt, int total_space);
uint32_t fdt_check_mem_start(uint32_t mem_start, const void *fdt);
int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x));
diff --git a/arch/arm/boot/dts/allwinner/sun8i-r40-feta40i.dtsi b/arch/arm/boot/dts/allwinner/sun8i-r40-feta40i.dtsi
index 9f39b5a2bb35..c12361d0317f 100644
--- a/arch/arm/boot/dts/allwinner/sun8i-r40-feta40i.dtsi
+++ b/arch/arm/boot/dts/allwinner/sun8i-r40-feta40i.dtsi
@@ -42,6 +42,13 @@
vcc-pg-supply = <&reg_dldo1>;
};
+&reg_aldo1 {
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-3v3-tv-usb";
+};
+
&reg_aldo2 {
regulator-always-on;
regulator-min-microvolt = <1800000>;
diff --git a/arch/arm/boot/dts/amlogic/meson.dtsi b/arch/arm/boot/dts/amlogic/meson.dtsi
index 8e3860d5d916..8cb0fc78b2af 100644
--- a/arch/arm/boot/dts/amlogic/meson.dtsi
+++ b/arch/arm/boot/dts/amlogic/meson.dtsi
@@ -23,7 +23,7 @@
#size-cells = <1>;
ranges;
- cbus: cbus@c1100000 {
+ cbus: bus@c1100000 {
compatible = "simple-bus";
reg = <0xc1100000 0x200000>;
#address-cells = <1>;
@@ -206,7 +206,7 @@
};
};
- aobus: aobus@c8100000 {
+ aobus: bus@c8100000 {
compatible = "simple-bus";
reg = <0xc8100000 0x100000>;
#address-cells = <1>;
@@ -302,7 +302,7 @@
reg = <0xd9040000 0x10000>;
};
- secbus: secbus@da000000 {
+ secbus: bus@da000000 {
compatible = "simple-bus";
reg = <0xda000000 0x6000>;
#address-cells = <1>;
diff --git a/arch/arm/boot/dts/amlogic/meson8.dtsi b/arch/arm/boot/dts/amlogic/meson8.dtsi
index 59932fbfd5d5..f57be9ae150f 100644
--- a/arch/arm/boot/dts/amlogic/meson8.dtsi
+++ b/arch/arm/boot/dts/amlogic/meson8.dtsi
@@ -645,7 +645,6 @@
};
&hwrng {
- compatible = "amlogic,meson8-rng", "amlogic,meson-rng";
clocks = <&clkc CLKID_RNG0>;
clock-names = "core";
};
diff --git a/arch/arm/boot/dts/amlogic/meson8b.dtsi b/arch/arm/boot/dts/amlogic/meson8b.dtsi
index 5198f5177c2c..2d9d24d3a95d 100644
--- a/arch/arm/boot/dts/amlogic/meson8b.dtsi
+++ b/arch/arm/boot/dts/amlogic/meson8b.dtsi
@@ -620,7 +620,6 @@
};
&hwrng {
- compatible = "amlogic,meson8b-rng", "amlogic,meson-rng";
clocks = <&clkc CLKID_RNG0>;
clock-names = "core";
};
diff --git a/arch/arm/boot/dts/arm/arm-realview-pb1176.dts b/arch/arm/boot/dts/arm/arm-realview-pb1176.dts
index efed325af88d..d99bac02232b 100644
--- a/arch/arm/boot/dts/arm/arm-realview-pb1176.dts
+++ b/arch/arm/boot/dts/arm/arm-realview-pb1176.dts
@@ -451,7 +451,7 @@
/* Direct-mapped development chip ROM */
pb1176_rom@10200000 {
- compatible = "direct-mapped";
+ compatible = "mtd-rom";
reg = <0x10200000 0x4000>;
bank-width = <1>;
};
diff --git a/arch/arm/boot/dts/arm/integratorap-im-pd1.dts b/arch/arm/boot/dts/arm/integratorap-im-pd1.dts
index 7072a70da00d..367850ea0912 100644
--- a/arch/arm/boot/dts/arm/integratorap-im-pd1.dts
+++ b/arch/arm/boot/dts/arm/integratorap-im-pd1.dts
@@ -129,8 +129,6 @@
bridge {
compatible = "ti,ths8134b", "ti,ths8134";
- #address-cells = <1>;
- #size-cells = <0>;
ports {
#address-cells = <1>;
@@ -154,6 +152,7 @@
vga {
compatible = "vga-connector";
+ label = "J30";
port {
vga_con_in: endpoint {
diff --git a/arch/arm/boot/dts/arm/versatile-ab.dts b/arch/arm/boot/dts/arm/versatile-ab.dts
index f31dcf7e5862..de45aa99e260 100644
--- a/arch/arm/boot/dts/arm/versatile-ab.dts
+++ b/arch/arm/boot/dts/arm/versatile-ab.dts
@@ -32,8 +32,6 @@
bridge {
compatible = "ti,ths8134b", "ti,ths8134";
- #address-cells = <1>;
- #size-cells = <0>;
ports {
#address-cells = <1>;
@@ -59,6 +57,7 @@
vga {
compatible = "vga-connector";
+ label = "J1";
port {
vga_con_in: endpoint {
diff --git a/arch/arm/boot/dts/arm/vexpress-v2p-ca9.dts b/arch/arm/boot/dts/arm/vexpress-v2p-ca9.dts
index 5916e4877eac..8bf35666412b 100644
--- a/arch/arm/boot/dts/arm/vexpress-v2p-ca9.dts
+++ b/arch/arm/boot/dts/arm/vexpress-v2p-ca9.dts
@@ -20,7 +20,9 @@
#address-cells = <1>;
#size-cells = <1>;
- chosen { };
+ chosen {
+ stdout-path = &v2m_serial0;
+ };
aliases {
serial0 = &v2m_serial0;
diff --git a/arch/arm/boot/dts/broadcom/bcm47622.dtsi b/arch/arm/boot/dts/broadcom/bcm47622.dtsi
index 7cd38de118c3..485863f9c420 100644
--- a/arch/arm/boot/dts/broadcom/bcm47622.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm47622.dtsi
@@ -138,6 +138,20 @@
status = "disabled";
};
+ nand_controller: nand-controller@1800 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+ reg = <0x1800 0x600>, <0x2000 0x10>;
+ reg-names = "nand", "nand-int-base";
+ status = "disabled";
+
+ nandcs: nand@0 {
+ compatible = "brcm,nandcs";
+ reg = <0>;
+ };
+ };
+
uart0: serial@12000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x12000 0x1000>;
diff --git a/arch/arm/boot/dts/broadcom/bcm63138.dtsi b/arch/arm/boot/dts/broadcom/bcm63138.dtsi
index 4ef02283612b..e74ba6bf370d 100644
--- a/arch/arm/boot/dts/broadcom/bcm63138.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm63138.dtsi
@@ -229,7 +229,12 @@
reg-names = "nand", "nand-int-base";
status = "disabled";
interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "nand";
+ interrupt-names = "nand_ctlrdy";
+
+ nandcs: nand@0 {
+ compatible = "brcm,nandcs";
+ reg = <0>;
+ };
};
serial@4400 {
diff --git a/arch/arm/boot/dts/broadcom/bcm63148.dtsi b/arch/arm/boot/dts/broadcom/bcm63148.dtsi
index 24431de1810e..53703827ee3f 100644
--- a/arch/arm/boot/dts/broadcom/bcm63148.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm63148.dtsi
@@ -119,5 +119,19 @@
num-cs = <8>;
status = "disabled";
};
+
+ nand_controller: nand-controller@2000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+ reg = <0x2000 0x600>, <0xf0 0x10>;
+ reg-names = "nand", "nand-int-base";
+ status = "disabled";
+
+ nandcs: nand@0 {
+ compatible = "brcm,nandcs";
+ reg = <0>;
+ };
+ };
};
};
diff --git a/arch/arm/boot/dts/broadcom/bcm63178.dtsi b/arch/arm/boot/dts/broadcom/bcm63178.dtsi
index 3f9aed96babf..6d8d33498983 100644
--- a/arch/arm/boot/dts/broadcom/bcm63178.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm63178.dtsi
@@ -129,6 +129,20 @@
status = "disabled";
};
+ nand_controller: nand-controller@1800 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+ reg = <0x1800 0x600>, <0x2000 0x10>;
+ reg-names = "nand", "nand-int-base";
+ status = "disabled";
+
+ nandcs: nand@0 {
+ compatible = "brcm,nandcs";
+ reg = <0>;
+ };
+ };
+
uart0: serial@12000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x12000 0x1000>;
diff --git a/arch/arm/boot/dts/broadcom/bcm6756.dtsi b/arch/arm/boot/dts/broadcom/bcm6756.dtsi
index 1d8d957d65dd..6433f8fa5eff 100644
--- a/arch/arm/boot/dts/broadcom/bcm6756.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm6756.dtsi
@@ -139,6 +139,20 @@
status = "disabled";
};
+ nand_controller: nand-controller@1800 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+ reg = <0x1800 0x600>, <0x2000 0x10>;
+ reg-names = "nand", "nand-int-base";
+ status = "disabled";
+
+ nandcs: nand@0 {
+ compatible = "brcm,nandcs";
+ reg = <0>;
+ };
+ };
+
uart0: serial@12000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x12000 0x1000>;
diff --git a/arch/arm/boot/dts/broadcom/bcm6846.dtsi b/arch/arm/boot/dts/broadcom/bcm6846.dtsi
index cf92cf8c4693..ee361cb00b7c 100644
--- a/arch/arm/boot/dts/broadcom/bcm6846.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm6846.dtsi
@@ -119,5 +119,19 @@
num-cs = <8>;
status = "disabled";
};
+
+ nand_controller: nand-controller@1800 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+ reg = <0x1800 0x600>, <0x2000 0x10>;
+ reg-names = "nand", "nand-int-base";
+ status = "disabled";
+
+ nandcs: nand@0 {
+ compatible = "brcm,nandcs";
+ reg = <0>;
+ };
+ };
};
};
diff --git a/arch/arm/boot/dts/broadcom/bcm6855.dtsi b/arch/arm/boot/dts/broadcom/bcm6855.dtsi
index 52d6bc89f9f8..52915ec6f339 100644
--- a/arch/arm/boot/dts/broadcom/bcm6855.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm6855.dtsi
@@ -129,6 +129,20 @@
status = "disabled";
};
+ nand_controller: nand-controller@1800 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+ reg = <0x1800 0x600>, <0x2000 0x10>;
+ reg-names = "nand", "nand-int-base";
+ status = "disabled";
+
+ nandcs: nand@0 {
+ compatible = "brcm,nandcs";
+ reg = <0>;
+ };
+ };
+
uart0: serial@12000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x12000 0x1000>;
diff --git a/arch/arm/boot/dts/broadcom/bcm6878.dtsi b/arch/arm/boot/dts/broadcom/bcm6878.dtsi
index 2c5d706bac7e..70cf23a65fdb 100644
--- a/arch/arm/boot/dts/broadcom/bcm6878.dtsi
+++ b/arch/arm/boot/dts/broadcom/bcm6878.dtsi
@@ -120,6 +120,20 @@
status = "disabled";
};
+ nand_controller: nand-controller@1800 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+ reg = <0x1800 0x600>, <0x2000 0x10>;
+ reg-names = "nand", "nand-int-base";
+ status = "disabled";
+
+ nandcs: nand@0 {
+ compatible = "brcm,nandcs";
+ reg = <0>;
+ };
+ };
+
uart0: serial@12000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x12000 0x1000>;
diff --git a/arch/arm/boot/dts/broadcom/bcm947622.dts b/arch/arm/boot/dts/broadcom/bcm947622.dts
index 93b8ce22678d..6241485408d3 100644
--- a/arch/arm/boot/dts/broadcom/bcm947622.dts
+++ b/arch/arm/boot/dts/broadcom/bcm947622.dts
@@ -32,3 +32,13 @@
&hsspi {
status = "okay";
};
+
+&nand_controller {
+ brcm,wp-not-connected;
+ status = "okay";
+};
+
+&nandcs {
+ nand-on-flash-bbt;
+ brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm963138.dts b/arch/arm/boot/dts/broadcom/bcm963138.dts
index 1b405c249213..7fd87e05ec20 100644
--- a/arch/arm/boot/dts/broadcom/bcm963138.dts
+++ b/arch/arm/boot/dts/broadcom/bcm963138.dts
@@ -29,3 +29,13 @@
&hsspi {
status = "okay";
};
+
+&nand_controller {
+ brcm,wp-not-connected;
+ status = "okay";
+};
+
+&nandcs {
+ nand-on-flash-bbt;
+ brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm963138dvt.dts b/arch/arm/boot/dts/broadcom/bcm963138dvt.dts
index b5af61853a07..f60d09908ab9 100644
--- a/arch/arm/boot/dts/broadcom/bcm963138dvt.dts
+++ b/arch/arm/boot/dts/broadcom/bcm963138dvt.dts
@@ -32,15 +32,15 @@
};
&nand_controller {
+ brcm,wp-not-connected;
status = "okay";
+};
- nand@0 {
- compatible = "brcm,nandcs";
- reg = <0>;
- nand-ecc-strength = <4>;
- nand-ecc-step-size = <512>;
- brcm,nand-oob-sectors-size = <16>;
- };
+&nandcs {
+ nand-ecc-strength = <4>;
+ nand-ecc-step-size = <512>;
+ brcm,nand-oob-sector-size = <16>;
+ nand-on-flash-bbt;
};
&ahci {
diff --git a/arch/arm/boot/dts/broadcom/bcm963148.dts b/arch/arm/boot/dts/broadcom/bcm963148.dts
index 1f5d6d783f09..44bca063a327 100644
--- a/arch/arm/boot/dts/broadcom/bcm963148.dts
+++ b/arch/arm/boot/dts/broadcom/bcm963148.dts
@@ -32,3 +32,13 @@
&hsspi {
status = "okay";
};
+
+&nand_controller {
+ brcm,wp-not-connected;
+ status = "okay";
+};
+
+&nandcs {
+ nand-on-flash-bbt;
+ brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm963178.dts b/arch/arm/boot/dts/broadcom/bcm963178.dts
index d036e99dd8d1..098a222cd71a 100644
--- a/arch/arm/boot/dts/broadcom/bcm963178.dts
+++ b/arch/arm/boot/dts/broadcom/bcm963178.dts
@@ -32,3 +32,13 @@
&hsspi {
status = "okay";
};
+
+&nand_controller {
+ brcm,wp-not-connected;
+ status = "okay";
+};
+
+&nandcs {
+ nand-on-flash-bbt;
+ brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm96756.dts b/arch/arm/boot/dts/broadcom/bcm96756.dts
index 8b104f3fb14a..402038d3cd0c 100644
--- a/arch/arm/boot/dts/broadcom/bcm96756.dts
+++ b/arch/arm/boot/dts/broadcom/bcm96756.dts
@@ -32,3 +32,13 @@
&hsspi {
status = "okay";
};
+
+&nand_controller {
+ brcm,wp-not-connected;
+ status = "okay";
+};
+
+&nandcs {
+ nand-on-flash-bbt;
+ brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm96846.dts b/arch/arm/boot/dts/broadcom/bcm96846.dts
index 55852c229608..943896afb7cc 100644
--- a/arch/arm/boot/dts/broadcom/bcm96846.dts
+++ b/arch/arm/boot/dts/broadcom/bcm96846.dts
@@ -32,3 +32,13 @@
&hsspi {
status = "okay";
};
+
+&nand_controller {
+ brcm,wp-not-connected;
+ status = "okay";
+};
+
+&nandcs {
+ nand-on-flash-bbt;
+ brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm96855.dts b/arch/arm/boot/dts/broadcom/bcm96855.dts
index 2ad880af2104..571663d9a1ea 100644
--- a/arch/arm/boot/dts/broadcom/bcm96855.dts
+++ b/arch/arm/boot/dts/broadcom/bcm96855.dts
@@ -32,3 +32,13 @@
&hsspi {
status = "okay";
};
+
+&nand_controller {
+ brcm,wp-not-connected;
+ status = "okay";
+};
+
+&nandcs {
+ nand-on-flash-bbt;
+ brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm/boot/dts/broadcom/bcm96878.dts b/arch/arm/boot/dts/broadcom/bcm96878.dts
index b7af8ade7a9d..8d6eddd54c6e 100644
--- a/arch/arm/boot/dts/broadcom/bcm96878.dts
+++ b/arch/arm/boot/dts/broadcom/bcm96878.dts
@@ -32,3 +32,13 @@
&hsspi {
status = "okay";
};
+
+&nand_controller {
+ brcm,wp-not-connected;
+ status = "okay";
+};
+
+&nandcs {
+ nand-on-flash-bbt;
+ brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm/boot/dts/gemini/gemini-dlink-dir-685.dts b/arch/arm/boot/dts/gemini/gemini-dlink-dir-685.dts
index 396149664297..b4dbcf8f168e 100644
--- a/arch/arm/boot/dts/gemini/gemini-dlink-dir-685.dts
+++ b/arch/arm/boot/dts/gemini/gemini-dlink-dir-685.dts
@@ -27,10 +27,10 @@
gpio_keys {
compatible = "gpio-keys";
- button-esc {
+ button-reset {
debounce-interval = <100>;
wakeup-source;
- linux,code = <KEY_ESC>;
+ linux,code = <KEY_RESTART>;
label = "reset";
/* Collides with LPC_LAD[0], UART DCD, SSP 97RST */
gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
@@ -187,7 +187,7 @@
};
/* This is a RealTek RTL8366RB switch and PHY using SMI over GPIO */
- switch {
+ ethernet-switch {
compatible = "realtek,rtl8366rb";
/* 22 = MDIO (has input reads), 21 = MDC (clock, output only) */
mdc-gpios = <&gpio0 21 GPIO_ACTIVE_HIGH>;
@@ -204,36 +204,36 @@
#interrupt-cells = <1>;
};
- ports {
+ ethernet-ports {
#address-cells = <1>;
#size-cells = <0>;
- port@0 {
+ ethernet-port@0 {
reg = <0>;
label = "lan0";
phy-handle = <&phy0>;
};
- port@1 {
+ ethernet-port@1 {
reg = <1>;
label = "lan1";
phy-handle = <&phy1>;
};
- port@2 {
+ ethernet-port@2 {
reg = <2>;
label = "lan2";
phy-handle = <&phy2>;
};
- port@3 {
+ ethernet-port@3 {
reg = <3>;
label = "lan3";
phy-handle = <&phy3>;
};
- port@4 {
+ ethernet-port@4 {
reg = <4>;
label = "wan";
phy-handle = <&phy4>;
};
- rtl8366rb_cpu_port: port@5 {
+ rtl8366rb_cpu_port: ethernet-port@5 {
reg = <5>;
label = "cpu";
ethernet = <&gmac0>;
@@ -252,27 +252,27 @@
#address-cells = <1>;
#size-cells = <0>;
- phy0: phy@0 {
+ phy0: ethernet-phy@0 {
reg = <0>;
interrupt-parent = <&switch_intc>;
interrupts = <0>;
};
- phy1: phy@1 {
+ phy1: ethernet-phy@1 {
reg = <1>;
interrupt-parent = <&switch_intc>;
interrupts = <1>;
};
- phy2: phy@2 {
+ phy2: ethernet-phy@2 {
reg = <2>;
interrupt-parent = <&switch_intc>;
interrupts = <2>;
};
- phy3: phy@3 {
+ phy3: ethernet-phy@3 {
reg = <3>;
interrupt-parent = <&switch_intc>;
interrupts = <3>;
};
- phy4: phy@4 {
+ phy4: ethernet-phy@4 {
reg = <4>;
interrupt-parent = <&switch_intc>;
interrupts = <12>;
diff --git a/arch/arm/boot/dts/gemini/gemini-dlink-dns-313.dts b/arch/arm/boot/dts/gemini/gemini-dlink-dns-313.dts
index 138c47e1ac1b..8c54d3a5a721 100644
--- a/arch/arm/boot/dts/gemini/gemini-dlink-dns-313.dts
+++ b/arch/arm/boot/dts/gemini/gemini-dlink-dns-313.dts
@@ -33,10 +33,10 @@
gpio_keys {
compatible = "gpio-keys";
- button-esc {
+ button-reset {
debounce-interval = <100>;
wakeup-source;
- linux,code = <KEY_ESC>;
+ linux,code = <KEY_RESTART>;
label = "reset";
gpios = <&gpio1 31 GPIO_ACTIVE_LOW>;
};
diff --git a/arch/arm/boot/dts/gemini/gemini-sl93512r.dts b/arch/arm/boot/dts/gemini/gemini-sl93512r.dts
index 91c19e8ebfe8..4992ec276de9 100644
--- a/arch/arm/boot/dts/gemini/gemini-sl93512r.dts
+++ b/arch/arm/boot/dts/gemini/gemini-sl93512r.dts
@@ -43,7 +43,7 @@
button-setup {
debounce-interval = <50>;
wakeup-source;
- linux,code = <KEY_SETUP>;
+ linux,code = <KEY_RESTART>;
label = "factory reset";
/* Conflict with NAND flash */
gpios = <&gpio0 18 GPIO_ACTIVE_LOW>;
@@ -93,7 +93,7 @@
cs-gpios = <&gpio1 31 GPIO_ACTIVE_HIGH>;
num-chipselects = <1>;
- switch@0 {
+ ethernet-switch@0 {
compatible = "vitesse,vsc7385";
reg = <0>;
/* Specified for 2.5 MHz or below */
@@ -101,27 +101,27 @@
gpio-controller;
#gpio-cells = <2>;
- ports {
+ ethernet-ports {
#address-cells = <1>;
#size-cells = <0>;
- port@0 {
+ ethernet-port@0 {
reg = <0>;
label = "lan1";
};
- port@1 {
+ ethernet-port@1 {
reg = <1>;
label = "lan2";
};
- port@2 {
+ ethernet-port@2 {
reg = <2>;
label = "lan3";
};
- port@3 {
+ ethernet-port@3 {
reg = <3>;
label = "lan4";
};
- vsc: port@6 {
+ vsc: ethernet-port@6 {
reg = <6>;
label = "cpu";
ethernet = <&gmac1>;
diff --git a/arch/arm/boot/dts/gemini/gemini-sq201.dts b/arch/arm/boot/dts/gemini/gemini-sq201.dts
index d0efd76695da..f8c6f6e5cdea 100644
--- a/arch/arm/boot/dts/gemini/gemini-sq201.dts
+++ b/arch/arm/boot/dts/gemini/gemini-sq201.dts
@@ -30,7 +30,7 @@
button-setup {
debounce-interval = <100>;
wakeup-source;
- linux,code = <KEY_SETUP>;
+ linux,code = <KEY_RESTART>;
label = "factory reset";
/* Conflict with NAND flash */
gpios = <&gpio0 18 GPIO_ACTIVE_LOW>;
@@ -78,7 +78,7 @@
cs-gpios = <&gpio1 31 GPIO_ACTIVE_HIGH>;
num-chipselects = <1>;
- switch@0 {
+ ethernet-switch@0 {
compatible = "vitesse,vsc7395";
reg = <0>;
/* Specified for 2.5 MHz or below */
@@ -86,27 +86,27 @@
gpio-controller;
#gpio-cells = <2>;
- ports {
+ ethernet-ports {
#address-cells = <1>;
#size-cells = <0>;
- port@0 {
+ ethernet-port@0 {
reg = <0>;
label = "lan1";
};
- port@1 {
+ ethernet-port@1 {
reg = <1>;
label = "lan2";
};
- port@2 {
+ ethernet-port@2 {
reg = <2>;
label = "lan3";
};
- port@3 {
+ ethernet-port@3 {
reg = <3>;
label = "lan4";
};
- vsc: port@6 {
+ vsc: ethernet-port@6 {
reg = <6>;
label = "cpu";
ethernet = <&gmac1>;
diff --git a/arch/arm/boot/dts/gemini/gemini-wbd111.dts b/arch/arm/boot/dts/gemini/gemini-wbd111.dts
index 3c88c59ab481..6a0c89e0c918 100644
--- a/arch/arm/boot/dts/gemini/gemini-wbd111.dts
+++ b/arch/arm/boot/dts/gemini/gemini-wbd111.dts
@@ -10,7 +10,7 @@
/ {
model = "Wiliboard WBD-111";
- compatible = "wiliboard,wbd111", "cortina,gemini";
+ compatible = "wiligear,wiliboard-wbd111", "cortina,gemini";
#address-cells = <1>;
#size-cells = <1>;
@@ -28,10 +28,10 @@
gpio_keys {
compatible = "gpio-keys";
- button-setup {
+ button-reset {
debounce-interval = <100>;
wakeup-source;
- linux,code = <KEY_SETUP>;
+ linux,code = <KEY_RESTART>;
label = "reset";
/* Conflict with ICE */
gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm/boot/dts/gemini/gemini-wbd222.dts b/arch/arm/boot/dts/gemini/gemini-wbd222.dts
index ff72bbc4db3e..d8b34ebad4b0 100644
--- a/arch/arm/boot/dts/gemini/gemini-wbd222.dts
+++ b/arch/arm/boot/dts/gemini/gemini-wbd222.dts
@@ -10,7 +10,7 @@
/ {
model = "Wiliboard WBD-222";
- compatible = "wiliboard,wbd222", "cortina,gemini";
+ compatible = "wiligear,wiliboard-wbd222", "cortina,gemini";
#address-cells = <1>;
#size-cells = <1>;
@@ -27,10 +27,10 @@
gpio_keys {
compatible = "gpio-keys";
- button-setup {
+ button-reset {
debounce-interval = <100>;
wakeup-source;
- linux,code = <KEY_SETUP>;
+ linux,code = <KEY_RESTART>;
label = "reset";
/* Conflict with ICE */
gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm/boot/dts/marvell/armada-385-clearfog-gtr-l8.dts b/arch/arm/boot/dts/marvell/armada-385-clearfog-gtr-l8.dts
index 1707d1b01545..cb85f8e31dfc 100644
--- a/arch/arm/boot/dts/marvell/armada-385-clearfog-gtr-l8.dts
+++ b/arch/arm/boot/dts/marvell/armada-385-clearfog-gtr-l8.dts
@@ -4,6 +4,18 @@
/ {
model = "SolidRun Clearfog GTR L8";
+ compatible = "solidrun,clearfog-gtr-l8", "marvell,armada385",
+ "marvell,armada380";
+
+ /* CON25 */
+ sfp1: sfp-1 {
+ compatible = "sff,sfp";
+ pinctrl-0 = <&cf_gtr_sfp1_pins>;
+ pinctrl-names = "default";
+ i2c-bus = <&i2c0>;
+ mod-def0-gpio = <&gpio0 24 GPIO_ACTIVE_LOW>;
+ tx-disable-gpio = <&gpio1 22 GPIO_ACTIVE_HIGH>;
+ };
};
&mdio {
@@ -20,57 +32,65 @@
ethernet-port@1 {
reg = <1>;
- label = "lan8";
+ label = "lan1";
phy-handle = <&switch0phy0>;
};
ethernet-port@2 {
reg = <2>;
- label = "lan7";
+ label = "lan2";
phy-handle = <&switch0phy1>;
};
ethernet-port@3 {
reg = <3>;
- label = "lan6";
+ label = "lan3";
phy-handle = <&switch0phy2>;
};
ethernet-port@4 {
reg = <4>;
- label = "lan5";
+ label = "lan4";
phy-handle = <&switch0phy3>;
};
ethernet-port@5 {
reg = <5>;
- label = "lan4";
+ label = "lan5";
phy-handle = <&switch0phy4>;
};
ethernet-port@6 {
reg = <6>;
- label = "lan3";
+ label = "lan6";
phy-handle = <&switch0phy5>;
};
ethernet-port@7 {
reg = <7>;
- label = "lan2";
+ label = "lan7";
phy-handle = <&switch0phy6>;
};
ethernet-port@8 {
reg = <8>;
- label = "lan1";
+ label = "lan8";
phy-handle = <&switch0phy7>;
};
+ ethernet-port@9 {
+ reg = <9>;
+ label = "lan-sfp";
+ phy-mode = "sgmii";
+ sfp = <&sfp1>;
+ managed = "in-band-status";
+ };
+
ethernet-port@10 {
reg = <10>;
phy-mode = "2500base-x";
-
ethernet = <&eth1>;
+
fixed-link {
speed = <2500>;
full-duplex;
diff --git a/arch/arm/boot/dts/marvell/armada-385-clearfog-gtr-s4.dts b/arch/arm/boot/dts/marvell/armada-385-clearfog-gtr-s4.dts
index a7678a784c18..5f83d981449a 100644
--- a/arch/arm/boot/dts/marvell/armada-385-clearfog-gtr-s4.dts
+++ b/arch/arm/boot/dts/marvell/armada-385-clearfog-gtr-s4.dts
@@ -4,6 +4,8 @@
/ {
model = "SolidRun Clearfog GTR S4";
+ compatible = "solidrun,clearfog-gtr-s4", "marvell,armada385",
+ "marvell,armada380";
};
&sfp0 {
diff --git a/arch/arm/boot/dts/marvell/armada-385-clearfog-gtr.dtsi b/arch/arm/boot/dts/marvell/armada-385-clearfog-gtr.dtsi
index d1452a04e904..f3a3cb6ac311 100644
--- a/arch/arm/boot/dts/marvell/armada-385-clearfog-gtr.dtsi
+++ b/arch/arm/boot/dts/marvell/armada-385-clearfog-gtr.dtsi
@@ -141,18 +141,13 @@
};
pinctrl@18000 {
- cf_gtr_switch_reset_pins: cf-gtr-switch-reset-pins {
- marvell,pins = "mpp18";
- marvell,function = "gpio";
- };
-
- cf_gtr_usb3_con_vbus: cf-gtr-usb3-con-vbus {
- marvell,pins = "mpp22";
+ cf_gtr_fan_pwm: cf-gtr-fan-pwm {
+ marvell,pins = "mpp23";
marvell,function = "gpio";
};
- cf_gtr_fan_pwm: cf-gtr-fan-pwm {
- marvell,pins = "mpp23";
+ cf_gtr_front_button_pins: cf-gtr-front-button-pins {
+ marvell,pins = "mpp53";
marvell,function = "gpio";
};
@@ -162,6 +157,37 @@
marvell,function = "i2c1";
};
+ cf_gtr_isolation_pins: cf-gtr-isolation-pins {
+ marvell,pins = "mpp47";
+ marvell,function = "gpio";
+ };
+
+ cf_gtr_led_pins: led-pins {
+ marvell,pins = "mpp42", "mpp52";
+ marvell,function = "gpio";
+ };
+
+ cf_gtr_lte_disable_pins: lte-disable-pins {
+ marvell,pins = "mpp34";
+ marvell,function = "gpio";
+ };
+
+ cf_gtr_pci_pins: pci-pins {
+ // pci reset
+ marvell,pins = "mpp33", "mpp35", "mpp44";
+ marvell,function = "gpio";
+ };
+
+ cf_gtr_poe_reset_pins: cf-gtr-poe-reset-pins {
+ marvell,pins = "mpp48";
+ marvell,function = "gpio";
+ };
+
+ cf_gtr_rear_button_pins: cf-gtr-rear-button-pins {
+ marvell,pins = "mpp36";
+ marvell,function = "gpio";
+ };
+
cf_gtr_sdhci_pins: cf-gtr-sdhci-pins {
marvell,pins = "mpp21", "mpp28",
"mpp37", "mpp38",
@@ -169,13 +195,15 @@
marvell,function = "sd0";
};
- cf_gtr_isolation_pins: cf-gtr-isolation-pins {
- marvell,pins = "mpp47";
+ cf_gtr_sfp0_pins: sfp0-pins {
+ /* sfp modabs, txdisable */
+ marvell,pins = "mpp25", "mpp46";
marvell,function = "gpio";
};
- cf_gtr_poe_reset_pins: cf-gtr-poe-reset-pins {
- marvell,pins = "mpp48";
+ cf_gtr_sfp1_pins: sfp1-pins {
+ /* sfp modabs, txdisable */
+ marvell,pins = "mpp24", "mpp54";
marvell,function = "gpio";
};
@@ -184,13 +212,18 @@
marvell,function = "spi1";
};
- cf_gtr_front_button_pins: cf-gtr-front-button-pins {
- marvell,pins = "mpp53";
+ cf_gtr_switch_reset_pins: cf-gtr-switch-reset-pins {
+ marvell,pins = "mpp18";
marvell,function = "gpio";
};
- cf_gtr_rear_button_pins: cf-gtr-rear-button-pins {
- marvell,pins = "mpp36";
+ cf_gtr_usb3_con_vbus: cf-gtr-usb3-con-vbus {
+ marvell,pins = "mpp22";
+ marvell,function = "gpio";
+ };
+
+ cf_gtr_wifi_disable_pins: wifi-disable-pins {
+ marvell,pins = "mpp30", "mpp31";
marvell,function = "gpio";
};
};
@@ -221,21 +254,26 @@
};
pcie {
+ pinctrl-0 = <&cf_gtr_pci_pins>;
+ pinctrl-names = "default";
status = "okay";
/*
* The PCIe units are accessible through
* the mini-PCIe connectors on the board.
*/
+ /* CON3 - serdes 0 */
pcie@1,0 {
reset-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
status = "okay";
};
+ /* CON4 - serdes 2 */
pcie@2,0 {
reset-gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
status = "okay";
};
+ /* CON2 - serdes 4 */
pcie@3,0 {
reset-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
status = "okay";
@@ -243,10 +281,12 @@
};
};
- sfp0: sfp {
+ /* CON5 */
+ sfp0: sfp-0 {
compatible = "sff,sfp";
+ pinctrl-0 = <&cf_gtr_sfp0_pins>;
+ pinctrl-names = "default";
i2c-bus = <&i2c1>;
- los-gpio = <&gpio1 22 GPIO_ACTIVE_HIGH>;
mod-def0-gpio = <&gpio0 25 GPIO_ACTIVE_LOW>;
tx-disable-gpio = <&gpio1 14 GPIO_ACTIVE_HIGH>;
};
@@ -273,6 +313,8 @@
gpio-leds {
compatible = "gpio-leds";
+ pinctrl-0 = <&cf_gtr_led_pins>;
+ pinctrl-names = "default";
led1 {
function = LED_FUNCTION_CPU;
@@ -408,7 +450,7 @@
};
&gpio0 {
- pinctrl-0 = <&cf_gtr_fan_pwm>;
+ pinctrl-0 = <&cf_gtr_fan_pwm &cf_gtr_wifi_disable_pins>;
pinctrl-names = "default";
wifi-disable {
@@ -420,7 +462,7 @@
};
&gpio1 {
- pinctrl-0 = <&cf_gtr_isolation_pins &cf_gtr_poe_reset_pins>;
+ pinctrl-0 = <&cf_gtr_isolation_pins &cf_gtr_poe_reset_pins &cf_gtr_lte_disable_pins>;
pinctrl-names = "default";
lte-disable {
diff --git a/arch/arm/boot/dts/marvell/armada-388-clearfog.dts b/arch/arm/boot/dts/marvell/armada-388-clearfog.dts
index 3290ccad2374..09bf2e6d4ed0 100644
--- a/arch/arm/boot/dts/marvell/armada-388-clearfog.dts
+++ b/arch/arm/boot/dts/marvell/armada-388-clearfog.dts
@@ -10,8 +10,9 @@
/ {
model = "SolidRun Clearfog A1";
- compatible = "solidrun,clearfog-a1", "marvell,armada388",
- "marvell,armada385", "marvell,armada380";
+ compatible = "solidrun,clearfog-pro-a1", "solidrun,clearfog-a1",
+ "marvell,armada388", "marvell,armada385",
+ "marvell,armada380";
soc {
internal-regs {
diff --git a/arch/arm/boot/dts/marvell/dove-cubox.dts b/arch/arm/boot/dts/marvell/dove-cubox.dts
index bfde99486a87..bcaaf8320c45 100644
--- a/arch/arm/boot/dts/marvell/dove-cubox.dts
+++ b/arch/arm/boot/dts/marvell/dove-cubox.dts
@@ -101,7 +101,7 @@
/* connect xtal input as source of pll0 and pll1 */
silabs,pll-source = <0 0>, <1 0>;
- clkout0 {
+ clkout@0 {
reg = <0>;
silabs,drive-strength = <8>;
silabs,multisynth-source = <0>;
@@ -109,7 +109,7 @@
silabs,pll-master;
};
- clkout2 {
+ clkout@2 {
reg = <2>;
silabs,drive-strength = <8>;
silabs,multisynth-source = <1>;
diff --git a/arch/arm/boot/dts/marvell/mmp2-brownstone.dts b/arch/arm/boot/dts/marvell/mmp2-brownstone.dts
index 04f1ae1382e7..bc64348b8218 100644
--- a/arch/arm/boot/dts/marvell/mmp2-brownstone.dts
+++ b/arch/arm/boot/dts/marvell/mmp2-brownstone.dts
@@ -28,7 +28,7 @@
&twsi1 {
status = "okay";
pmic: max8925@3c {
- compatible = "maxium,max8925";
+ compatible = "maxim,max8925";
reg = <0x3c>;
interrupts = <1>;
interrupt-parent = <&intcmux4>;
diff --git a/arch/arm/boot/dts/microchip/Makefile b/arch/arm/boot/dts/microchip/Makefile
index efde9546c8f4..0c45c8d17468 100644
--- a/arch/arm/boot/dts/microchip/Makefile
+++ b/arch/arm/boot/dts/microchip/Makefile
@@ -11,6 +11,7 @@ DTC_FLAGS_at91-sama5d2_xplained := -@
DTC_FLAGS_at91-sama5d3_eds := -@
DTC_FLAGS_at91-sama5d3_xplained := -@
DTC_FLAGS_at91-sama5d4_xplained := -@
+DTC_FLAGS_at91-sama7g54_curiosity := -@
DTC_FLAGS_at91-sama7g5ek := -@
dtb-$(CONFIG_SOC_AT91RM9200) += \
at91rm9200ek.dtb \
@@ -87,6 +88,7 @@ dtb-$(CONFIG_SOC_SAM_V7) += \
at91-sama5d4ek.dtb \
at91-vinco.dtb
dtb-$(CONFIG_SOC_SAMA7G5) += \
+ at91-sama7g54_curiosity.dtb \
at91-sama7g5ek.dtb
dtb-$(CONFIG_SOC_LAN966) += \
diff --git a/arch/arm/boot/dts/microchip/at91-sama7g54_curiosity.dts b/arch/arm/boot/dts/microchip/at91-sama7g54_curiosity.dts
new file mode 100644
index 000000000000..4f609e9e510e
--- /dev/null
+++ b/arch/arm/boot/dts/microchip/at91-sama7g54_curiosity.dts
@@ -0,0 +1,482 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * at91-sama7g54_curiosity.dts - Device Tree file for SAMA7G54 Curiosity Board
+ *
+ * Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Mihai Sain <mihai.sain@microchip.com>
+ *
+ */
+/dts-v1/;
+#include "sama7g5-pinfunc.h"
+#include "sama7g5.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/mfd/atmel-flexcom.h>
+#include <dt-bindings/pinctrl/at91.h>
+
+/ {
+ model = "Microchip SAMA7G54 Curiosity";
+ compatible = "microchip,sama7g54-curiosity", "microchip,sama7g5", "microchip,sama7";
+
+ aliases {
+ serial0 = &uart3;
+ i2c0 = &i2c10;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_key_gpio_default>;
+
+ button-user {
+ label = "user-button";
+ gpios = <&pioA PIN_PD19 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_PROG1>;
+ wakeup-source;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_led_gpio_default>;
+
+ led-red {
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_POWER;
+ gpios = <&pioA PIN_PD13 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led-green {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_BOOT;
+ gpios = <&pioA PIN_PD14 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ led-blue {
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_CPU;
+ gpios = <&pioA PIN_PB15 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ memory@60000000 {
+ device_type = "memory";
+ reg = <0x60000000 0x10000000>; /* 256 MiB DDR3L-1066 16-bit */
+ };
+};
+
+&adc {
+ vddana-supply = <&vddout25>;
+ vref-supply = <&vddout25>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mikrobus1_an_default &pinctrl_mikrobus2_an_default>;
+ status = "okay";
+};
+
+&cpu0 {
+ cpu-supply = <&vddcpu>;
+};
+
+&dma0 {
+ status = "okay";
+};
+
+&dma1 {
+ status = "okay";
+};
+
+&dma2 {
+ status = "okay";
+};
+
+&ebi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nand_default>;
+ status = "okay";
+
+ nand_controller: nand-controller {
+ status = "okay";
+
+ nand@3 {
+ reg = <0x3 0x0 0x800000>;
+ atmel,rb = <0>;
+ nand-bus-width = <8>;
+ nand-ecc-mode = "hw";
+ nand-ecc-strength = <8>;
+ nand-ecc-step-size = <512>;
+ nand-on-flash-bbt;
+ label = "nand";
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ at91bootstrap@0 {
+ label = "nand: at91bootstrap";
+ reg = <0x0 0x40000>;
+ };
+
+ bootloader@40000 {
+ label = "nand: u-boot";
+ reg = <0x40000 0x100000>;
+ };
+
+ bootloaderenv@140000 {
+ label = "nand: u-boot env";
+ reg = <0x140000 0x40000>;
+ };
+
+ dtb@180000 {
+ label = "nand: device tree";
+ reg = <0x180000 0x80000>;
+ };
+
+ kernel@200000 {
+ label = "nand: kernel";
+ reg = <0x200000 0x600000>;
+ };
+
+ rootfs@800000 {
+ label = "nand: rootfs";
+ reg = <0x800000 0x1f800000>;
+ };
+ };
+ };
+ };
+};
+
+&flx3 {
+ atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_USART>;
+ status = "okay";
+
+ uart3: serial@200 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flx3_default>;
+ status = "okay";
+ };
+};
+
+&flx10 {
+ atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_TWI>;
+ status = "okay";
+
+ i2c10: i2c@600 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flx10_default>;
+ i2c-analog-filter;
+ i2c-digital-filter;
+ i2c-digital-filter-width-ns = <35>;
+ status = "okay";
+
+ eeprom@51 {
+ compatible = "atmel,24c02";
+ reg = <0x51>;
+ pagesize = <16>;
+ size = <256>;
+ vcc-supply = <&vdd_3v3>;
+ };
+
+ pmic@5b {
+ compatible = "microchip,mcp16502";
+ reg = <0x5b>;
+
+ regulators {
+ vdd_3v3: VDD_IO {
+ regulator-name = "VDD_IO";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-initial-mode = <2>;
+ regulator-allowed-modes = <2>, <4>;
+ regulator-always-on;
+
+ regulator-state-standby {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ regulator-mode = <4>;
+ };
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-mode = <4>;
+ };
+ };
+
+ vddioddr: VDD_DDR {
+ regulator-name = "VDD_DDR";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-initial-mode = <2>;
+ regulator-allowed-modes = <2>, <4>;
+ regulator-always-on;
+
+ regulator-state-standby {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1350000>;
+ regulator-mode = <4>;
+ };
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1350000>;
+ regulator-mode = <4>;
+ };
+ };
+
+ vddcore: VDD_CORE {
+ regulator-name = "VDD_CORE";
+ regulator-min-microvolt = <1150000>;
+ regulator-max-microvolt = <1150000>;
+ regulator-initial-mode = <2>;
+ regulator-allowed-modes = <2>, <4>;
+ regulator-always-on;
+
+ regulator-state-standby {
+ regulator-on-in-suspend;
+ regulator-suspend-voltage = <1150000>;
+ regulator-mode = <4>;
+ };
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-mode = <4>;
+ };
+ };
+
+ vddcpu: VDD_OTHER {
+ regulator-name = "VDD_OTHER";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1250000>;
+ regulator-initial-mode = <2>;
+ regulator-allowed-modes = <2>, <4>;
+ regulator-ramp-delay = <3125>;
+ regulator-always-on;
+
+ regulator-state-standby {
+ regulator-on-in-suspend;
+ regulator-suspend-voltage = <1050000>;
+ regulator-mode = <4>;
+ };
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-mode = <4>;
+ };
+ };
+
+ vldo1: LDO1 {
+ regulator-name = "LDO1";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+
+ regulator-state-standby {
+ regulator-suspend-voltage = <1800000>;
+ regulator-on-in-suspend;
+ };
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vldo2: LDO2 {
+ regulator-name = "LDO2";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+
+ regulator-state-standby {
+ regulator-suspend-voltage = <3300000>;
+ regulator-on-in-suspend;
+ };
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+ };
+};
+
+&main_xtal {
+ clock-frequency = <24000000>;
+};
+
+&qspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_qspi1_default>;
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0x0>;
+ spi-max-frequency = <100000000>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+ m25p,fast-read;
+ };
+};
+
+&pioA {
+ pinctrl_flx3_default: flx3-default {
+ pinmux = <PIN_PD16__FLEXCOM3_IO0>,
+ <PIN_PD17__FLEXCOM3_IO1>;
+ bias-pull-up;
+ };
+
+ pinctrl_flx10_default: flx10-default {
+ pinmux = <PIN_PC30__FLEXCOM10_IO0>,
+ <PIN_PC31__FLEXCOM10_IO1>;
+ bias-pull-up;
+ };
+
+ pinctrl_key_gpio_default: key-gpio-default {
+ pinmux = <PIN_PD19__GPIO>;
+ bias-pull-up;
+ };
+
+ pinctrl_led_gpio_default: led-gpio-default {
+ pinmux = <PIN_PD13__GPIO>,
+ <PIN_PD14__GPIO>,
+ <PIN_PB15__GPIO>;
+ bias-pull-up;
+ };
+
+ pinctrl_mikrobus1_an_default: mikrobus1-an-default {
+ pinmux = <PIN_PC15__GPIO>;
+ bias-disable;
+ };
+
+ pinctrl_mikrobus2_an_default: mikrobus2-an-default {
+ pinmux = <PIN_PC13__GPIO>;
+ bias-disable;
+ };
+
+ pinctrl_nand_default: nand-default {
+ pinmux = <PIN_PD9__D0>,
+ <PIN_PD10__D1>,
+ <PIN_PD11__D2>,
+ <PIN_PC21__D3>,
+ <PIN_PC22__D4>,
+ <PIN_PC23__D5>,
+ <PIN_PC24__D6>,
+ <PIN_PD2__D7>,
+ <PIN_PD3__NANDRDY>,
+ <PIN_PD4__NCS3_NANDCS>,
+ <PIN_PD5__NWE_NWR0_NANDWE>,
+ <PIN_PD6__NRD_NANDOE>,
+ <PIN_PD7__A21_NANDALE>,
+ <PIN_PD8__A22_NANDCLE>;
+ bias-disable;
+ slew-rate = <0>;
+ };
+
+ pinctrl_qspi1_default: qspi1-default {
+ pinmux = <PIN_PB22__QSPI1_IO3>,
+ <PIN_PB23__QSPI1_IO2>,
+ <PIN_PB24__QSPI1_IO1>,
+ <PIN_PB25__QSPI1_IO0>,
+ <PIN_PB26__QSPI1_CS>,
+ <PIN_PB27__QSPI1_SCK>;
+ bias-pull-up;
+ slew-rate = <0>;
+ };
+
+ pinctrl_sdmmc0_default: sdmmc0-default {
+ pinmux = <PIN_PA0__SDMMC0_CK>,
+ <PIN_PA1__SDMMC0_CMD>,
+ <PIN_PA2__SDMMC0_RSTN>,
+ <PIN_PA3__SDMMC0_DAT0>,
+ <PIN_PA4__SDMMC0_DAT1>,
+ <PIN_PA5__SDMMC0_DAT2>,
+ <PIN_PA6__SDMMC0_DAT3>;
+ bias-pull-up;
+ slew-rate = <0>;
+ };
+
+ pinctrl_sdmmc1_default: sdmmc1-default {
+ pinmux = <PIN_PB29__SDMMC1_CMD>,
+ <PIN_PB30__SDMMC1_CK>,
+ <PIN_PB31__SDMMC1_DAT0>,
+ <PIN_PC0__SDMMC1_DAT1>,
+ <PIN_PC1__SDMMC1_DAT2>,
+ <PIN_PC2__SDMMC1_DAT3>,
+ <PIN_PC4__SDMMC1_CD>;
+ bias-pull-up;
+ slew-rate = <0>;
+ };
+};
+
+&rtt {
+ atmel,rtt-rtc-time-reg = <&gpbr 0x0>;
+};
+
+/* M.2 slot for wireless card */
+&sdmmc0 {
+ bus-width = <4>;
+ cd-gpios = <&pioA 31 GPIO_ACTIVE_LOW>;
+ disable-wp;
+ sdhci-caps-mask = <0x0 0x00200000>;
+ vmmc-supply = <&vdd_3v3>;
+ vqmmc-supply = <&vdd_3v3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sdmmc0_default>;
+ status = "okay";
+};
+
+/* micro SD socket */
+&sdmmc1 {
+ bus-width = <4>;
+ disable-wp;
+ sdhci-caps-mask = <0x0 0x00200000>;
+ vmmc-supply = <&vdd_3v3>;
+ vqmmc-supply = <&vdd_3v3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sdmmc1_default>;
+ status = "okay";
+};
+
+&slow_xtal {
+ clock-frequency = <32768>;
+};
+
+&shdwc {
+ debounce-delay-us = <976>;
+ status = "okay";
+
+ input@0 {
+ reg = <0>;
+ };
+};
+
+&tcb0 {
+ timer0: timer@0 {
+ compatible = "atmel,tcb-timer";
+ reg = <0>;
+ };
+
+ timer1: timer@1 {
+ compatible = "atmel,tcb-timer";
+ reg = <1>;
+ };
+};
+
+&trng {
+ status = "okay";
+};
+
+&vddout25 {
+ vin-supply = <&vdd_3v3>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/microchip/at91sam9g25-gardena-smart-gateway.dts b/arch/arm/boot/dts/microchip/at91sam9g25-gardena-smart-gateway.dts
index 92f2c05c873f..af70eb8a3a02 100644
--- a/arch/arm/boot/dts/microchip/at91sam9g25-gardena-smart-gateway.dts
+++ b/arch/arm/boot/dts/microchip/at91sam9g25-gardena-smart-gateway.dts
@@ -121,6 +121,8 @@
};
&usart3 {
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
status = "okay";
pinctrl-0 = <&pinctrl_usart3
diff --git a/arch/arm/boot/dts/microchip/at91sam9x5ek.dtsi b/arch/arm/boot/dts/microchip/at91sam9x5ek.dtsi
index 5f4eaa618ab4..9618b8d965b0 100644
--- a/arch/arm/boot/dts/microchip/at91sam9x5ek.dtsi
+++ b/arch/arm/boot/dts/microchip/at91sam9x5ek.dtsi
@@ -39,6 +39,8 @@
};
&dbgu {
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
status = "okay";
};
diff --git a/arch/arm/boot/dts/microchip/sam9x60.dtsi b/arch/arm/boot/dts/microchip/sam9x60.dtsi
index 73d570a17269..291540e5d81e 100644
--- a/arch/arm/boot/dts/microchip/sam9x60.dtsi
+++ b/arch/arm/boot/dts/microchip/sam9x60.dtsi
@@ -179,7 +179,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(8))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(9))>;
@@ -202,7 +202,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(8))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(9))>;
@@ -220,7 +220,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(8))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(9))>;
@@ -248,7 +248,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(10))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(11))>;
@@ -271,7 +271,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(10))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(11))>;
@@ -289,7 +289,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(10))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(11))>;
@@ -377,7 +377,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(22))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(23))>;
@@ -399,7 +399,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(22))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(23))>;
@@ -426,7 +426,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(24))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(25))>;
@@ -448,7 +448,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(24))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(25))>;
@@ -583,7 +583,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(12))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(13))>;
@@ -605,7 +605,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(12))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(13))>;
@@ -632,7 +632,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(14))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(15))>;
@@ -654,7 +654,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(14))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(15))>;
@@ -681,7 +681,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(16))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(17))>;
@@ -703,7 +703,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(16))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(17))>;
@@ -730,7 +730,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(0))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(1))>;
@@ -753,7 +753,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(0))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(1))>;
@@ -771,7 +771,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(0))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(1))>;
@@ -798,7 +798,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(2))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(3))>;
@@ -821,7 +821,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(2))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(3))>;
@@ -839,7 +839,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(2))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(3))>;
@@ -866,7 +866,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(4))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(5))>;
@@ -889,7 +889,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(4))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(5))>;
@@ -907,7 +907,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(4))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(5))>;
@@ -934,7 +934,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(6))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(7))>;
@@ -957,7 +957,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(6))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(7))>;
@@ -975,7 +975,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(6))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(7))>;
@@ -1057,7 +1057,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(18))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(19))>;
@@ -1079,7 +1079,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(18))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(19))>;
@@ -1106,7 +1106,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(20))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(21))>;
@@ -1128,7 +1128,7 @@
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(20))>,
- <&dma0
+ <&dma0
(AT91_XDMAC_DT_MEM_IF(0) |
AT91_XDMAC_DT_PER_IF(1) |
AT91_XDMAC_DT_PERID(21))>;
diff --git a/arch/arm/boot/dts/microchip/sama7g5.dtsi b/arch/arm/boot/dts/microchip/sama7g5.dtsi
index 269e0a3ca269..75778be126a3 100644
--- a/arch/arm/boot/dts/microchip/sama7g5.dtsi
+++ b/arch/arm/boot/dts/microchip/sama7g5.dtsi
@@ -698,7 +698,7 @@
};
flx0: flexcom@e1818000 {
- compatible = "atmel,sama5d2-flexcom";
+ compatible = "microchip,sama7g5-flexcom", "atmel,sama5d2-flexcom";
reg = <0xe1818000 0x200>;
clocks = <&pmc PMC_TYPE_PERIPHERAL 38>;
#address-cells = <1>;
@@ -714,7 +714,7 @@
clocks = <&pmc PMC_TYPE_PERIPHERAL 38>;
clock-names = "usart";
dmas = <&dma1 AT91_XDMAC_DT_PERID(6)>,
- <&dma1 AT91_XDMAC_DT_PERID(5)>;
+ <&dma1 AT91_XDMAC_DT_PERID(5)>;
dma-names = "tx", "rx";
atmel,use-dma-rx;
atmel,use-dma-tx;
@@ -723,7 +723,7 @@
};
flx1: flexcom@e181c000 {
- compatible = "atmel,sama5d2-flexcom";
+ compatible = "microchip,sama7g5-flexcom", "atmel,sama5d2-flexcom";
reg = <0xe181c000 0x200>;
clocks = <&pmc PMC_TYPE_PERIPHERAL 39>;
#address-cells = <1>;
@@ -740,14 +740,14 @@
clocks = <&pmc PMC_TYPE_PERIPHERAL 39>;
atmel,fifo-size = <32>;
dmas = <&dma0 AT91_XDMAC_DT_PERID(8)>,
- <&dma0 AT91_XDMAC_DT_PERID(7)>;
+ <&dma0 AT91_XDMAC_DT_PERID(7)>;
dma-names = "tx", "rx";
status = "disabled";
};
};
flx3: flexcom@e1824000 {
- compatible = "atmel,sama5d2-flexcom";
+ compatible = "microchip,sama7g5-flexcom", "atmel,sama5d2-flexcom";
reg = <0xe1824000 0x200>;
clocks = <&pmc PMC_TYPE_PERIPHERAL 41>;
#address-cells = <1>;
@@ -763,7 +763,7 @@
clocks = <&pmc PMC_TYPE_PERIPHERAL 41>;
clock-names = "usart";
dmas = <&dma1 AT91_XDMAC_DT_PERID(12)>,
- <&dma1 AT91_XDMAC_DT_PERID(11)>;
+ <&dma1 AT91_XDMAC_DT_PERID(11)>;
dma-names = "tx", "rx";
atmel,use-dma-rx;
atmel,use-dma-tx;
@@ -791,7 +791,7 @@
};
flx4: flexcom@e2018000 {
- compatible = "atmel,sama5d2-flexcom";
+ compatible = "microchip,sama7g5-flexcom", "atmel,sama5d2-flexcom";
reg = <0xe2018000 0x200>;
clocks = <&pmc PMC_TYPE_PERIPHERAL 42>;
#address-cells = <1>;
@@ -807,7 +807,7 @@
clocks = <&pmc PMC_TYPE_PERIPHERAL 42>;
clock-names = "usart";
dmas = <&dma1 AT91_XDMAC_DT_PERID(14)>,
- <&dma1 AT91_XDMAC_DT_PERID(13)>;
+ <&dma1 AT91_XDMAC_DT_PERID(13)>;
dma-names = "tx", "rx";
atmel,use-dma-rx;
atmel,use-dma-tx;
@@ -817,7 +817,7 @@
};
flx7: flexcom@e2024000 {
- compatible = "atmel,sama5d2-flexcom";
+ compatible = "microchip,sama7g5-flexcom", "atmel,sama5d2-flexcom";
reg = <0xe2024000 0x200>;
clocks = <&pmc PMC_TYPE_PERIPHERAL 45>;
#address-cells = <1>;
@@ -833,7 +833,7 @@
clocks = <&pmc PMC_TYPE_PERIPHERAL 45>;
clock-names = "usart";
dmas = <&dma1 AT91_XDMAC_DT_PERID(20)>,
- <&dma1 AT91_XDMAC_DT_PERID(19)>;
+ <&dma1 AT91_XDMAC_DT_PERID(19)>;
dma-names = "tx", "rx";
atmel,use-dma-rx;
atmel,use-dma-tx;
@@ -911,7 +911,7 @@
};
flx8: flexcom@e2818000 {
- compatible = "atmel,sama5d2-flexcom";
+ compatible = "microchip,sama7g5-flexcom", "atmel,sama5d2-flexcom";
reg = <0xe2818000 0x200>;
clocks = <&pmc PMC_TYPE_PERIPHERAL 46>;
#address-cells = <1>;
@@ -928,14 +928,14 @@
clocks = <&pmc PMC_TYPE_PERIPHERAL 46>;
atmel,fifo-size = <32>;
dmas = <&dma0 AT91_XDMAC_DT_PERID(22)>,
- <&dma0 AT91_XDMAC_DT_PERID(21)>;
+ <&dma0 AT91_XDMAC_DT_PERID(21)>;
dma-names = "tx", "rx";
status = "disabled";
};
};
flx9: flexcom@e281c000 {
- compatible = "atmel,sama5d2-flexcom";
+ compatible = "microchip,sama7g5-flexcom", "atmel,sama5d2-flexcom";
reg = <0xe281c000 0x200>;
clocks = <&pmc PMC_TYPE_PERIPHERAL 47>;
#address-cells = <1>;
@@ -952,14 +952,38 @@
clocks = <&pmc PMC_TYPE_PERIPHERAL 47>;
atmel,fifo-size = <32>;
dmas = <&dma0 AT91_XDMAC_DT_PERID(24)>,
- <&dma0 AT91_XDMAC_DT_PERID(23)>;
+ <&dma0 AT91_XDMAC_DT_PERID(23)>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+ };
+
+ flx10: flexcom@e2820000 {
+ compatible = "microchip,sama7g5-flexcom", "atmel,sama5d2-flexcom";
+ reg = <0xe2820000 0x200>;
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 48>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0xe2820000 0x800>;
+ status = "disabled";
+
+ i2c10: i2c@600 {
+ compatible = "microchip,sama7g5-i2c", "microchip,sam9x60-i2c";
+ reg = <0x600 0x200>;
+ interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&pmc PMC_TYPE_PERIPHERAL 48>;
+ atmel,fifo-size = <32>;
+ dmas = <&dma0 AT91_XDMAC_DT_PERID(26)>,
+ <&dma0 AT91_XDMAC_DT_PERID(25)>;
dma-names = "tx", "rx";
status = "disabled";
};
};
flx11: flexcom@e2824000 {
- compatible = "atmel,sama5d2-flexcom";
+ compatible = "microchip,sama7g5-flexcom", "atmel,sama5d2-flexcom";
reg = <0xe2824000 0x200>;
clocks = <&pmc PMC_TYPE_PERIPHERAL 49>;
#address-cells = <1>;
@@ -977,7 +1001,7 @@
#size-cells = <0>;
atmel,fifo-size = <32>;
dmas = <&dma0 AT91_XDMAC_DT_PERID(28)>,
- <&dma0 AT91_XDMAC_DT_PERID(27)>;
+ <&dma0 AT91_XDMAC_DT_PERID(27)>;
dma-names = "tx", "rx";
status = "disabled";
};
diff --git a/arch/arm/boot/dts/nvidia/Makefile b/arch/arm/boot/dts/nvidia/Makefile
index 60091bf7e48b..96972559253c 100644
--- a/arch/arm/boot/dts/nvidia/Makefile
+++ b/arch/arm/boot/dts/nvidia/Makefile
@@ -39,5 +39,7 @@ dtb-$(CONFIG_ARCH_TEGRA_3x_SOC) += \
tegra30-cardhu-a02.dtb \
tegra30-cardhu-a04.dtb \
tegra30-colibri-eval-v3.dtb \
+ tegra30-lg-p880.dtb \
+ tegra30-lg-p895.dtb \
tegra30-ouya.dtb \
tegra30-pegatron-chagall.dtb
diff --git a/arch/arm/boot/dts/nvidia/tegra124-nyan.dtsi b/arch/arm/boot/dts/nvidia/tegra124-nyan.dtsi
index a2ee37180200..8125c1b3e8d7 100644
--- a/arch/arm/boot/dts/nvidia/tegra124-nyan.dtsi
+++ b/arch/arm/boot/dts/nvidia/tegra124-nyan.dtsi
@@ -338,6 +338,7 @@
interrupt-parent = <&gpio>;
interrupts = <TEGRA_GPIO(C, 7) IRQ_TYPE_LEVEL_LOW>;
reg = <0>;
+ wakeup-source;
google,cros-ec-spi-msg-delay = <2000>;
diff --git a/arch/arm/boot/dts/nvidia/tegra124-venice2.dts b/arch/arm/boot/dts/nvidia/tegra124-venice2.dts
index 3924ee385dee..df98dc2a67b8 100644
--- a/arch/arm/boot/dts/nvidia/tegra124-venice2.dts
+++ b/arch/arm/boot/dts/nvidia/tegra124-venice2.dts
@@ -857,6 +857,7 @@
interrupt-parent = <&gpio>;
interrupts = <TEGRA_GPIO(C, 7) IRQ_TYPE_LEVEL_LOW>;
reg = <0>;
+ wakeup-source;
google,cros-ec-spi-msg-delay = <2000>;
diff --git a/arch/arm/boot/dts/nvidia/tegra30-asus-nexus7-grouper-common.dtsi b/arch/arm/boot/dts/nvidia/tegra30-asus-nexus7-grouper-common.dtsi
index a9342e04b14b..15f53babdc21 100644
--- a/arch/arm/boot/dts/nvidia/tegra30-asus-nexus7-grouper-common.dtsi
+++ b/arch/arm/boot/dts/nvidia/tegra30-asus-nexus7-grouper-common.dtsi
@@ -915,6 +915,9 @@
reg = <0x1c>;
realtek,dmic1-data-pin = <1>;
+
+ clocks = <&tegra_pmc TEGRA_PMC_CLK_OUT_1>;
+ clock-names = "mclk";
};
nct72: temperature-sensor@4c {
diff --git a/arch/arm/boot/dts/nvidia/tegra30-lg-p880.dts b/arch/arm/boot/dts/nvidia/tegra30-lg-p880.dts
new file mode 100644
index 000000000000..2f7754fd42a1
--- /dev/null
+++ b/arch/arm/boot/dts/nvidia/tegra30-lg-p880.dts
@@ -0,0 +1,489 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+
+#include "tegra30-lg-x3.dtsi"
+
+/ {
+ model = "LG Optimus 4X HD P880";
+ compatible = "lg,p880", "nvidia,tegra30";
+
+ aliases {
+ mmc1 = &sdmmc3; /* uSD slot */
+ mmc2 = &sdmmc1; /* WiFi */
+ };
+
+ pinmux@70000868 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ /* WLAN SDIO pinmux */
+ host-wlan-wake {
+ nvidia,pins = "pu4";
+ nvidia,function = "pwm1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* GNSS UART-B pinmux */
+ uartb-rxd {
+ nvidia,pins = "uart2_rxd_pc3";
+ nvidia,function = "uartb";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ uartb-txd {
+ nvidia,pins = "uart2_txd_pc2";
+ nvidia,function = "uartb";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gps-reset {
+ nvidia,pins = "kb_row7_pr7";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* MicroSD pinmux */
+ sdmmc3-clk {
+ nvidia,pins = "sdmmc3_clk_pa6";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc3-data {
+ nvidia,pins = "sdmmc3_cmd_pa7",
+ "sdmmc3_dat0_pb7",
+ "sdmmc3_dat1_pb6",
+ "sdmmc3_dat2_pb5",
+ "sdmmc3_dat3_pb4";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ microsd-detect {
+ nvidia,pins = "clk2_out_pw5";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* GPIO keys pinmux */
+ volume-up {
+ nvidia,pins = "ulpi_data6_po7";
+ nvidia,function = "spi2";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* Sensors pinmux */
+ current-alert-irq {
+ nvidia,pins = "uart2_rts_n_pj6";
+ nvidia,function = "uartb";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* AUDIO pinmux */
+ sub-mic-ldo {
+ nvidia,pins = "gmi_cs7_n_pi6";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ };
+ };
+
+ i2c@7000c400 {
+ touchscreen@20 {
+ rmi4-f11@11 {
+ syna,clip-x-high = <1110>;
+ syna,clip-y-high = <1973>;
+
+ touchscreen-inverted-y;
+ };
+ };
+ };
+
+ memory-controller@7000f000 {
+ emc-timings-0 {
+ /* SAMSUNG 1GB K4P8G304EB FGC1 533MHz */
+ nvidia,ram-code = <0>;
+
+ timing-12750000 {
+ clock-frequency = <12750000>;
+
+ nvidia,emem-configuration = < 0x00050001 0xc0000010
+ 0x00000001 0x00000001 0x00000002 0x00000000
+ 0x00000003 0x00000001 0x00000002 0x00000004
+ 0x00000001 0x00000000 0x00000002 0x00000002
+ 0x02020001 0x00060402 0x77230303 0x001f0000 >;
+ };
+
+ timing-25500000 {
+ clock-frequency = <25500000>;
+
+ nvidia,emem-configuration = < 0x00020001 0xc0000010
+ 0x00000001 0x00000001 0x00000002 0x00000000
+ 0x00000003 0x00000001 0x00000002 0x00000004
+ 0x00000001 0x00000000 0x00000002 0x00000002
+ 0x02020001 0x00060402 0x73e30303 0x001f0000 >;
+ };
+
+ timing-51000000 {
+ clock-frequency = <51000000>;
+
+ nvidia,emem-configuration = < 0x00010001 0xc0000010
+ 0x00000001 0x00000001 0x00000002 0x00000000
+ 0x00000003 0x00000001 0x00000002 0x00000004
+ 0x00000001 0x00000000 0x00000002 0x00000002
+ 0x02020001 0x00060402 0x72c30303 0x001f0000 >;
+ };
+
+ timing-102000000 {
+ clock-frequency = <102000000>;
+
+ nvidia,emem-configuration = < 0x00000001 0xc0000018
+ 0x00000001 0x00000001 0x00000003 0x00000001
+ 0x00000003 0x00000001 0x00000002 0x00000004
+ 0x00000001 0x00000000 0x00000002 0x00000002
+ 0x02020001 0x00060403 0x72430504 0x001f0000 >;
+ };
+
+ timing-204000000 {
+ clock-frequency = <204000000>;
+
+ nvidia,emem-configuration = < 0x00000003 0xc0000025
+ 0x00000001 0x00000001 0x00000006 0x00000003
+ 0x00000005 0x00000001 0x00000002 0x00000004
+ 0x00000001 0x00000000 0x00000003 0x00000002
+ 0x02030001 0x00070506 0x71e40a07 0x001f0000 >;
+ };
+
+ timing-266500000 {
+ clock-frequency = <266500000>;
+
+ nvidia,emem-configuration = < 0x00000004 0xC0000030
+ 0x00000001 0x00000002 0x00000008 0x00000004
+ 0x00000006 0x00000001 0x00000002 0x00000005
+ 0x00000001 0x00000000 0x00000003 0x00000003
+ 0x03030001 0x00090608 0x70040c09 0x001f0000 >;
+ };
+
+ timing-533000000 {
+ clock-frequency = <533000000>;
+
+ nvidia,emem-configuration = < 0x00000008 0xC0000060
+ 0x00000003 0x00000004 0x00000010 0x0000000a
+ 0x0000000d 0x00000002 0x00000002 0x00000008
+ 0x00000002 0x00000000 0x00000004 0x00000005
+ 0x05040002 0x00110b10 0x70281811 0x001f0000 >;
+ };
+ };
+ };
+
+ memory-controller@7000f400 {
+ emc-timings-0 {
+ /* SAMSUNG 1GB K4P8G304EB FGC1 533MHz */
+ nvidia,ram-code = <0>;
+
+ timing-12750000 {
+ clock-frequency = <12750000>;
+
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-mode-1 = <0x00010022>;
+ nvidia,emc-mode-2 = <0x00020001>;
+ nvidia,emc-mode-reset = <0x00000000>;
+ nvidia,emc-zcal-cnt-long = <0x00000009>;
+ nvidia,emc-cfg-dyn-self-ref;
+ nvidia,emc-cfg-periodic-qrst;
+
+ nvidia,emc-configuration = < 0x00000000
+ 0x00000001 0x00000002 0x00000002 0x00000004
+ 0x00000004 0x00000001 0x00000005 0x00000002
+ 0x00000002 0x00000001 0x00000001 0x00000000
+ 0x00000001 0x00000003 0x00000001 0x0000000b
+ 0x00000009 0x0000002f 0x00000000 0x0000000b
+ 0x00000001 0x00000001 0x00000002 0x00000000
+ 0x00000001 0x00000007 0x00000002 0x00000002
+ 0x00000003 0x00000008 0x00000004 0x00000001
+ 0x00000002 0x00000036 0x00000004 0x00000004
+ 0x00000000 0x00000000 0x00004282 0x007800a4
+ 0x00008000 0x000fc000 0x000fc000 0x000fc000
+ 0x000fc000 0x000fc000 0x000fc000 0x000fc000
+ 0x000fc000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x000fc000 0x000fc000 0x000fc000
+ 0x000fc000 0x00100220 0x0800201c 0x00000000
+ 0x77ffc004 0x01f1f008 0x00000000 0x00000007
+ 0x08000068 0x08000000 0x00000802 0x00064000
+ 0x00000009 0x00090009 0xa0f10000 0x00000000
+ 0x00000000 0x80000164 0xe0000000 0xff00ff00 >;
+ };
+
+ timing-25500000 {
+ clock-frequency = <25500000>;
+
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-mode-1 = <0x00010022>;
+ nvidia,emc-mode-2 = <0x00020001>;
+ nvidia,emc-mode-reset = <0x00000000>;
+ nvidia,emc-zcal-cnt-long = <0x00000009>;
+ nvidia,emc-cfg-dyn-self-ref;
+ nvidia,emc-cfg-periodic-qrst;
+
+ nvidia,emc-configuration = < 0x00000001
+ 0x00000003 0x00000002 0x00000002 0x00000004
+ 0x00000004 0x00000001 0x00000005 0x00000002
+ 0x00000002 0x00000001 0x00000001 0x00000000
+ 0x00000001 0x00000003 0x00000001 0x0000000b
+ 0x00000009 0x00000060 0x00000000 0x00000018
+ 0x00000001 0x00000001 0x00000002 0x00000000
+ 0x00000001 0x00000007 0x00000004 0x00000004
+ 0x00000003 0x00000008 0x00000004 0x00000001
+ 0x00000002 0x0000006b 0x00000004 0x00000004
+ 0x00000000 0x00000000 0x00004282 0x007800a4
+ 0x00008000 0x000fc000 0x000fc000 0x000fc000
+ 0x000fc000 0x000fc000 0x000fc000 0x000fc000
+ 0x000fc000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x000fc000 0x000fc000 0x000fc000
+ 0x000fc000 0x00100220 0x0800201c 0x00000000
+ 0x77ffc004 0x01f1f008 0x00000000 0x00000007
+ 0x08000068 0x08000000 0x00000802 0x00064000
+ 0x0000000a 0x00090009 0xa0f10000 0x00000000
+ 0x00000000 0x800001c5 0xe0000000 0xff00ff00 >;
+ };
+
+ timing-51000000 {
+ clock-frequency = <51000000>;
+
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-mode-1 = <0x00010022>;
+ nvidia,emc-mode-2 = <0x00020001>;
+ nvidia,emc-mode-reset = <0x00000000>;
+ nvidia,emc-zcal-cnt-long = <0x00000009>;
+ nvidia,emc-cfg-dyn-self-ref;
+ nvidia,emc-cfg-periodic-qrst;
+
+ nvidia,emc-configuration = < 0x00000003
+ 0x00000006 0x00000002 0x00000002 0x00000004
+ 0x00000004 0x00000001 0x00000005 0x00000002
+ 0x00000002 0x00000001 0x00000001 0x00000000
+ 0x00000001 0x00000003 0x00000001 0x0000000b
+ 0x00000009 0x000000c0 0x00000000 0x00000030
+ 0x00000001 0x00000001 0x00000002 0x00000000
+ 0x00000001 0x00000007 0x00000008 0x00000008
+ 0x00000003 0x00000008 0x00000004 0x00000001
+ 0x00000002 0x000000d5 0x00000004 0x00000004
+ 0x00000000 0x00000000 0x00004282 0x007800a4
+ 0x00008000 0x000fc000 0x000fc000 0x000fc000
+ 0x000fc000 0x000fc000 0x000fc000 0x000fc000
+ 0x000fc000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x000fc000 0x000fc000 0x000fc000
+ 0x000fc000 0x00100220 0x0800201c 0x00000000
+ 0x77ffc004 0x01f1f008 0x00000000 0x00000007
+ 0x08000068 0x08000000 0x00000802 0x00064000
+ 0x00000013 0x00090009 0xa0f10000 0x00000000
+ 0x00000000 0x80000287 0xe0000000 0xff00ff00 >;
+ };
+
+ timing-102000000 {
+ clock-frequency = <102000000>;
+
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-mode-1 = <0x00010022>;
+ nvidia,emc-mode-2 = <0x00020001>;
+ nvidia,emc-mode-reset = <0x00000000>;
+ nvidia,emc-zcal-cnt-long = <0x0000000a>;
+ nvidia,emc-cfg-dyn-self-ref;
+ nvidia,emc-cfg-periodic-qrst;
+
+ nvidia,emc-configuration = < 0x00000006
+ 0x0000000d 0x00000004 0x00000002 0x00000004
+ 0x00000004 0x00000001 0x00000005 0x00000002
+ 0x00000002 0x00000001 0x00000001 0x00000000
+ 0x00000001 0x00000003 0x00000001 0x0000000b
+ 0x00000009 0x00000181 0x00000000 0x00000060
+ 0x00000001 0x00000001 0x00000002 0x00000000
+ 0x00000001 0x00000007 0x0000000f 0x0000000f
+ 0x00000003 0x00000008 0x00000004 0x00000001
+ 0x00000002 0x000001a9 0x00000004 0x00000004
+ 0x00000000 0x00000000 0x00004282 0x007800a4
+ 0x00008000 0x000fc000 0x000fc000 0x000fc000
+ 0x000fc000 0x000fc000 0x000fc000 0x000fc000
+ 0x000fc000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x000fc000 0x000fc000 0x000fc000
+ 0x000fc000 0x00100220 0x0800201c 0x00000000
+ 0x77ffc004 0x01f1f008 0x00000000 0x00000007
+ 0x08000068 0x08000000 0x00000802 0x00064000
+ 0x00000025 0x00090009 0xa0f10000 0x00000000
+ 0x00000000 0x8000040b 0xe0000000 0xff00ff00 >;
+ };
+
+ timing-204000000 {
+ clock-frequency = <204000000>;
+
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-mode-1 = <0x00010042>;
+ nvidia,emc-mode-2 = <0x00020001>;
+ nvidia,emc-mode-reset = <0x00000000>;
+ nvidia,emc-zcal-cnt-long = <0x00000013>;
+ nvidia,emc-cfg-dyn-self-ref;
+ nvidia,emc-cfg-periodic-qrst;
+
+ nvidia,emc-configuration = < 0x0000000c
+ 0x0000001a 0x00000008 0x00000003 0x00000005
+ 0x00000004 0x00000001 0x00000006 0x00000003
+ 0x00000003 0x00000002 0x00000002 0x00000000
+ 0x00000001 0x00000003 0x00000001 0x0000000c
+ 0x0000000a 0x00000303 0x00000000 0x000000c0
+ 0x00000001 0x00000001 0x00000003 0x00000000
+ 0x00000001 0x00000007 0x0000001d 0x0000001d
+ 0x00000004 0x0000000b 0x00000005 0x00000001
+ 0x00000002 0x00000351 0x00000004 0x00000006
+ 0x00000000 0x00000000 0x00004282 0x004400a4
+ 0x00008000 0x00070000 0x00070000 0x00070000
+ 0x00070000 0x00070000 0x00070000 0x00070000
+ 0x00070000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00080000 0x00080000 0x00080000
+ 0x00080000 0x000e0220 0x0800201c 0x00000000
+ 0x77ffc004 0x01f1f008 0x00000000 0x00000007
+ 0x08000068 0x08000000 0x00000802 0x00064000
+ 0x0000004a 0x00090009 0xa0f10000 0x00000000
+ 0x00000000 0x80000713 0xe0000000 0xff00ff00 >;
+ };
+
+ timing-266500000 {
+ clock-frequency = <266500000>;
+
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-mode-1 = <0x00010042>;
+ nvidia,emc-mode-2 = <0x00020002>;
+ nvidia,emc-mode-reset = <0x00000000>;
+ nvidia,emc-zcal-cnt-long = <0x00000018>;
+ nvidia,emc-cfg-periodic-qrst;
+
+ nvidia,emc-configuration = < 0x0000000f
+ 0x00000022 0x0000000b 0x00000004 0x00000005
+ 0x00000005 0x00000001 0x00000007 0x00000004
+ 0x00000004 0x00000002 0x00000002 0x00000000
+ 0x00000002 0x00000005 0x00000002 0x0000000c
+ 0x0000000b 0x000003ef 0x00000000 0x000000fb
+ 0x00000001 0x00000001 0x00000004 0x00000000
+ 0x00000001 0x00000009 0x00000026 0x00000026
+ 0x00000004 0x0000000e 0x00000006 0x00000001
+ 0x00000002 0x00000455 0x00000000 0x00000004
+ 0x00000000 0x00000000 0x00006282 0x003200a4
+ 0x00008000 0x00050000 0x00050000 0x00050000
+ 0x00050000 0x00050000 0x00050000 0x00050000
+ 0x00050000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00060000 0x00060000 0x00060000
+ 0x00060000 0x000b0220 0x0800003d 0x00000000
+ 0x77ffc004 0x01f1f008 0x00000000 0x00000007
+ 0x08000068 0x08000000 0x00000802 0x00064000
+ 0x00000060 0x000a000a 0xa0f10000 0x00000000
+ 0x00000000 0x800008ee 0xe0000000 0xff00ff00 >;
+ };
+
+ timing-533000000 {
+ clock-frequency = <533000000>;
+
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-mode-1 = <0x000100c2>;
+ nvidia,emc-mode-2 = <0x00020006>;
+ nvidia,emc-mode-reset = <0x00000000>;
+ nvidia,emc-zcal-cnt-long = <0x00000030>;
+ nvidia,emc-cfg-periodic-qrst;
+
+ nvidia,emc-configuration = < 0x0000001f
+ 0x00000045 0x00000016 0x00000009 0x00000008
+ 0x00000009 0x00000003 0x0000000d 0x00000009
+ 0x00000009 0x00000005 0x00000003 0x00000000
+ 0x00000004 0x00000009 0x00000006 0x0000000d
+ 0x00000010 0x000007df 0x00000000 0x000001f7
+ 0x00000003 0x00000003 0x00000009 0x00000000
+ 0x00000001 0x0000000f 0x0000004b 0x0000004b
+ 0x00000008 0x0000001b 0x0000000c 0x00000001
+ 0x00000002 0x000008aa 0x00000000 0x00000006
+ 0x00000000 0x00000000 0x00006282 0xf0120091
+ 0x00008000 0x0000000a 0x0000000a 0x0000000a
+ 0x0000000a 0x0000000a 0x0000000a 0x0000000a
+ 0x0000000a 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x0000000a 0x0000000a 0x0000000a
+ 0x0000000a 0x00090220 0x0800003d 0x00000000
+ 0x77ffc004 0x01f1f408 0x00000000 0x00000007
+ 0x08000068 0x08000000 0x00000802 0x00064000
+ 0x000000c0 0x000e000e 0xa0f10000 0x00000000
+ 0x00000000 0x800010d9 0xe0000000 0xff00ff88 >;
+ };
+ };
+ };
+
+ sdmmc3: mmc@78000400 {
+ status = "okay";
+
+ cd-gpios = <&gpio TEGRA_GPIO(W, 5) GPIO_ACTIVE_LOW>;
+ bus-width = <4>;
+
+ vmmc-supply = <&vdd_usd>;
+ vqmmc-supply = <&vdd_1v8_vio>;
+ };
+
+ battery: battery-cell {
+ compatible = "simple-battery";
+ device-chemistry = "lithium-ion";
+ charge-full-design-microamp-hours = <2150000>;
+ energy-full-design-microwatt-hours = <8200000>;
+ operating-range-celsius = <0 45>;
+ };
+
+ gpio-keys {
+ key-volume-up {
+ label = "Volume Up";
+ gpios = <&gpio TEGRA_GPIO(O, 7) GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ debounce-interval = <10>;
+ wakeup-event-action = <EV_ACT_ASSERTED>;
+ wakeup-source;
+ };
+ };
+
+ sound {
+ compatible = "lg,tegra-audio-max98089-p880",
+ "nvidia,tegra-audio-max98089";
+ nvidia,model = "LG Optimus 4X HD MAX98089";
+
+ nvidia,int-mic-en-gpios = <&gpio TEGRA_GPIO(I, 6) GPIO_ACTIVE_HIGH>;
+ };
+};
diff --git a/arch/arm/boot/dts/nvidia/tegra30-lg-p895.dts b/arch/arm/boot/dts/nvidia/tegra30-lg-p895.dts
new file mode 100644
index 000000000000..e32fafc7f5e0
--- /dev/null
+++ b/arch/arm/boot/dts/nvidia/tegra30-lg-p895.dts
@@ -0,0 +1,496 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+
+#include "tegra30-lg-x3.dtsi"
+
+/ {
+ model = "LG Optimus Vu P895";
+ compatible = "lg,p895", "nvidia,tegra30";
+
+ pinmux@70000868 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ /* GNSS UART-B pinmux */
+ uartb-cts-rxd {
+ nvidia,pins = "uart2_cts_n_pj5",
+ "uart2_rxd_pc3";
+ nvidia,function = "uartb";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ uartb-rts-txd {
+ nvidia,pins = "uart2_rts_n_pj6",
+ "uart2_txd_pc2";
+ nvidia,function = "uartb";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gps-reset {
+ nvidia,pins = "spdif_out_pk5";
+ nvidia,function = "spdif";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* GPIO keys pinmux */
+ memo-key {
+ nvidia,pins = "sdmmc3_dat1_pb6";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ volume-up {
+ nvidia,pins = "gmi_cs7_n_pi6";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* Sensors pinmux */
+ current-alert-irq {
+ nvidia,pins = "spi1_cs0_n_px6";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* Panel pinmux */
+ panel-vdd {
+ nvidia,pins = "pbb0";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* AUDIO pinmux */
+ sub-mic-ldo {
+ nvidia,pins = "gmi_dqs_pi2";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* Modem pinmux */
+ usim-detect {
+ nvidia,pins = "clk2_out_pw5";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* GPIO power/drive control */
+ drive-sdmmc4 {
+ nvidia,pins = "drive_gma",
+ "drive_gmb",
+ "drive_gmc",
+ "drive_gmd";
+ nvidia,pull-down-strength = <9>;
+ nvidia,pull-up-strength = <9>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_SLOWEST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_SLOWEST>;
+ };
+ };
+ };
+
+ i2c@7000c400 {
+ touchscreen@20 {
+ rmi4-f11@11 {
+ syna,clip-x-high = <1535>;
+ syna,clip-y-high = <2047>;
+ };
+ };
+ };
+
+ memory-controller@7000f000 {
+ emc-timings-2 {
+ /* Hynix 1GB H9TCNNN8JDMMPR LPDDR2 533MHz */
+ nvidia,ram-code = <2>;
+
+ timing-12750000 {
+ clock-frequency = <12750000>;
+
+ nvidia,emem-configuration = < 0x00020001 0xc0000010
+ 0x00000001 0x00000001 0x00000002 0x00000000
+ 0x00000003 0x00000001 0x00000002 0x00000004
+ 0x00000001 0x00000000 0x00000002 0x00000002
+ 0x02020001 0x00060402 0x77230303 0x001f0000 >;
+ };
+
+ timing-25500000 {
+ clock-frequency = <25500000>;
+
+ nvidia,emem-configuration = < 0x00030003 0xc0000010
+ 0x00000001 0x00000001 0x00000002 0x00000000
+ 0x00000003 0x00000001 0x00000002 0x00000004
+ 0x00000001 0x00000000 0x00000002 0x00000002
+ 0x02020001 0x00060402 0x73e30303 0x001f0000 >;
+ };
+
+ timing-51000000 {
+ clock-frequency = <51000000>;
+
+ nvidia,emem-configuration = < 0x00010003 0xc0000010
+ 0x00000001 0x00000001 0x00000002 0x00000000
+ 0x00000003 0x00000001 0x00000002 0x00000004
+ 0x00000001 0x00000000 0x00000002 0x00000002
+ 0x02020001 0x00060402 0x72c30303 0x001f0000 >;
+ };
+
+ timing-102000000 {
+ clock-frequency = <102000000>;
+
+ nvidia,emem-configuration = < 0x00000003 0xc0000018
+ 0x00000001 0x00000001 0x00000003 0x00000001
+ 0x00000003 0x00000001 0x00000002 0x00000004
+ 0x00000001 0x00000000 0x00000002 0x00000002
+ 0x02020001 0x00060403 0x72430504 0x001f0000 >;
+ };
+
+ timing-204000000 {
+ clock-frequency = <204000000>;
+
+ nvidia,emem-configuration = < 0x00000006 0xc0000025
+ 0x00000001 0x00000001 0x00000006 0x00000003
+ 0x00000005 0x00000001 0x00000002 0x00000004
+ 0x00000001 0x00000000 0x00000003 0x00000002
+ 0x02030001 0x00070506 0x71e40a07 0x001f0000 >;
+ };
+
+ timing-266500000 {
+ clock-frequency = <266500000>;
+
+ nvidia,emem-configuration = < 0x00000008 0xc0000030
+ 0x00000001 0x00000002 0x00000008 0x00000004
+ 0x00000006 0x00000001 0x00000002 0x00000005
+ 0x00000001 0x00000000 0x00000003 0x00000003
+ 0x03030001 0x00090608 0x70040c09 0x001f0000 >;
+ };
+
+ timing-533000000 {
+ clock-frequency = <533000000>;
+
+ nvidia,emem-configuration = < 0x0000000f 0xc0000060
+ 0x00000003 0x00000004 0x00000010 0x0000000a
+ 0x0000000d 0x00000002 0x00000002 0x00000008
+ 0x00000002 0x00000000 0x00000004 0x00000005
+ 0x05040002 0x00110b10 0x70281811 0x001f0000 >;
+ };
+ };
+ };
+
+ memory-controller@7000f400 {
+ emc-timings-2 {
+ /* Hynix 1GB H9TCNNN8JDMMPR LPDDR2 533MHz */
+ nvidia,ram-code = <2>;
+
+ timing-12750000 {
+ clock-frequency = <12750000>;
+
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-mode-1 = <0x00010022>;
+ nvidia,emc-mode-2 = <0x00020001>;
+ nvidia,emc-mode-reset = <0x00000000>;
+ nvidia,emc-zcal-cnt-long = <0x00000009>;
+ nvidia,emc-cfg-periodic-qrst;
+
+ nvidia,emc-configuration = < 0x00000000
+ 0x00000001 0x00000002 0x00000002 0x00000004
+ 0x00000004 0x00000001 0x00000005 0x00000002
+ 0x00000002 0x00000001 0x00000001 0x00000000
+ 0x00000001 0x00000003 0x00000001 0x0000000b
+ 0x00000009 0x0000002f 0x00000000 0x0000000b
+ 0x00000001 0x00000001 0x00000002 0x00000000
+ 0x00000001 0x00000007 0x00000002 0x00000002
+ 0x00000003 0x00000008 0x00000004 0x00000004
+ 0x00000002 0x00000036 0x00000004 0x00000004
+ 0x00000000 0x00000000 0x00004282 0x007800a4
+ 0x00008000 0x000fc000 0x000fc000 0x000fc000
+ 0x000fc000 0x000fc000 0x000fc000 0x000fc000
+ 0x000fc000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x000fc000 0x000fc000 0x000fc000
+ 0x000fc000 0x00100220 0x0800201c 0x00000000
+ 0x77ffc004 0x01f1f008 0x00000000 0x00000007
+ 0x08000068 0x08000000 0x00000802 0x00064000
+ 0x00000009 0x00090009 0xa0f10000 0x00000000
+ 0x00000000 0x80000164 0xe0000000 0xff00ff00 >;
+ };
+
+ timing-25500000 {
+ clock-frequency = <25500000>;
+
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-mode-1 = <0x00010022>;
+ nvidia,emc-mode-2 = <0x00020001>;
+ nvidia,emc-mode-reset = <0x00000000>;
+ nvidia,emc-zcal-cnt-long = <0x00000009>;
+ nvidia,emc-cfg-periodic-qrst;
+
+ nvidia,emc-configuration = < 0x00000001
+ 0x00000003 0x00000002 0x00000002 0x00000004
+ 0x00000004 0x00000001 0x00000005 0x00000002
+ 0x00000002 0x00000001 0x00000001 0x00000000
+ 0x00000001 0x00000003 0x00000001 0x0000000b
+ 0x00000009 0x00000060 0x00000000 0x00000018
+ 0x00000001 0x00000001 0x00000002 0x00000000
+ 0x00000001 0x00000007 0x00000004 0x00000004
+ 0x00000003 0x00000008 0x00000004 0x00000004
+ 0x00000002 0x0000006b 0x00000004 0x00000004
+ 0x00000000 0x00000000 0x00004282 0x007800a4
+ 0x00008000 0x000fc000 0x000fc000 0x000fc000
+ 0x000fc000 0x000fc000 0x000fc000 0x000fc000
+ 0x000fc000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x000fc000 0x000fc000 0x000fc000
+ 0x000fc000 0x00100220 0x0800201c 0x00000000
+ 0x77ffc004 0x01f1f008 0x00000000 0x00000007
+ 0x08000068 0x08000000 0x00000802 0x00064000
+ 0x0000000a 0x00090009 0xa0f10000 0x00000000
+ 0x00000000 0x800001c5 0xd0000000 0xff00ff00 >;
+ };
+
+ timing-51000000 {
+ clock-frequency = <51000000>;
+
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-mode-1 = <0x00010022>;
+ nvidia,emc-mode-2 = <0x00020001>;
+ nvidia,emc-mode-reset = <0x00000000>;
+ nvidia,emc-zcal-cnt-long = <0x00000009>;
+ nvidia,emc-cfg-periodic-qrst;
+
+ nvidia,emc-configuration = < 0x00000003
+ 0x00000006 0x00000002 0x00000002 0x00000004
+ 0x00000004 0x00000001 0x00000005 0x00000002
+ 0x00000002 0x00000001 0x00000001 0x00000000
+ 0x00000001 0x00000003 0x00000001 0x0000000b
+ 0x00000009 0x000000c0 0x00000000 0x00000030
+ 0x00000001 0x00000001 0x00000002 0x00000000
+ 0x00000001 0x00000007 0x00000008 0x00000008
+ 0x00000003 0x00000008 0x00000004 0x00000004
+ 0x00000002 0x000000d5 0x00000004 0x00000004
+ 0x00000000 0x00000000 0x00004282 0x007800a4
+ 0x00008000 0x000fc000 0x000fc000 0x000fc000
+ 0x000fc000 0x000fc000 0x000fc000 0x000fc000
+ 0x000fc000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x000fc000 0x000fc000 0x000fc000
+ 0x000fc000 0x00100220 0x0800201c 0x00000000
+ 0x77ffc004 0x01f1f008 0x00000000 0x00000007
+ 0x08000068 0x08000000 0x00000802 0x00064000
+ 0x00000013 0x00090009 0xa0f10000 0x00000000
+ 0x00000000 0x80000287 0xd0000000 0xff00ff00 >;
+ };
+
+ timing-102000000 {
+ clock-frequency = <102000000>;
+
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-mode-1 = <0x00010022>;
+ nvidia,emc-mode-2 = <0x00020001>;
+ nvidia,emc-mode-reset = <0x00000000>;
+ nvidia,emc-zcal-cnt-long = <0x0000000a>;
+ nvidia,emc-cfg-periodic-qrst;
+
+ nvidia,emc-configuration = < 0x00000006
+ 0x0000000d 0x00000004 0x00000002 0x00000004
+ 0x00000004 0x00000001 0x00000005 0x00000002
+ 0x00000002 0x00000001 0x00000001 0x00000000
+ 0x00000001 0x00000003 0x00000001 0x0000000b
+ 0x00000009 0x00000181 0x00000000 0x00000060
+ 0x00000001 0x00000001 0x00000002 0x00000000
+ 0x00000001 0x00000007 0x0000000f 0x0000000f
+ 0x00000003 0x00000008 0x00000004 0x00000004
+ 0x00000002 0x000001a9 0x00000004 0x00000006
+ 0x00000000 0x00000000 0x00004282 0x007800a4
+ 0x00008000 0x000fc000 0x000fc000 0x000fc000
+ 0x000fc000 0x000fc000 0x000fc000 0x000fc000
+ 0x000fc000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x000fc000 0x000fc000 0x000fc000
+ 0x000fc000 0x00100220 0x0800201c 0x00000000
+ 0x77ffc004 0x01f1f008 0x00000000 0x00000007
+ 0x08000068 0x08000000 0x00000802 0x00064000
+ 0x00000025 0x00090009 0xa0f10000 0x00000000
+ 0x00000000 0x8000040b 0xd0000000 0xff00ff00 >;
+ };
+
+ timing-204000000 {
+ clock-frequency = <204000000>;
+
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-mode-1 = <0x00010042>;
+ nvidia,emc-mode-2 = <0x00020001>;
+ nvidia,emc-mode-reset = <0x00000000>;
+ nvidia,emc-zcal-cnt-long = <0x00000013>;
+ nvidia,emc-cfg-periodic-qrst;
+
+ nvidia,emc-configuration = < 0x0000000c
+ 0x0000001a 0x00000008 0x00000003 0x00000005
+ 0x00000004 0x00000001 0x00000006 0x00000003
+ 0x00000003 0x00000002 0x00000002 0x00000000
+ 0x00000001 0x00000004 0x00000001 0x0000000c
+ 0x0000000a 0x00000303 0x00000000 0x000000c0
+ 0x00000001 0x00000001 0x00000003 0x00000000
+ 0x00000001 0x00000007 0x0000001d 0x0000001d
+ 0x00000004 0x0000000b 0x00000005 0x00000004
+ 0x00000002 0x00000351 0x00000005 0x00000004
+ 0x00000000 0x00000000 0x00004282 0x004400a4
+ 0x00008000 0x00080000 0x00080000 0x00080000
+ 0x00080000 0x00072000 0x00072000 0x00072000
+ 0x00072000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00080000 0x00080000 0x00080000
+ 0x00080000 0x000e0220 0x0800201c 0x00000000
+ 0x77ffc004 0x01f1f008 0x00000000 0x00000007
+ 0x08000068 0x08000000 0x00000802 0x00064000
+ 0x0000004a 0x00090009 0xa0f10000 0x00000000
+ 0x00000000 0x80000713 0xe0000000 0xff00ff00 >;
+ };
+
+ timing-266500000 {
+ clock-frequency = <266500000>;
+
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-mode-1 = <0x00010042>;
+ nvidia,emc-mode-2 = <0x00020002>;
+ nvidia,emc-mode-reset = <0x00000000>;
+ nvidia,emc-zcal-cnt-long = <0x00000018>;
+ nvidia,emc-cfg-periodic-qrst;
+
+ nvidia,emc-configuration = < 0x0000000f
+ 0x00000022 0x0000000b 0x00000004 0x00000005
+ 0x00000005 0x00000001 0x00000007 0x00000004
+ 0x00000004 0x00000002 0x00000002 0x00000000
+ 0x00000002 0x00000005 0x00000002 0x0000000c
+ 0x0000000b 0x000003ef 0x00000000 0x000000fb
+ 0x00000001 0x00000001 0x00000004 0x00000000
+ 0x00000001 0x00000009 0x00000026 0x00000026
+ 0x00000004 0x0000000e 0x00000006 0x00000004
+ 0x00000002 0x00000455 0x00000000 0x00000004
+ 0x00000000 0x00000000 0x00006282 0x003200a4
+ 0x00008000 0x00070000 0x00070000 0x00070000
+ 0x00070000 0x00072000 0x00072000 0x00072000
+ 0x00072000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00080002 0x00080002 0x00080002
+ 0x00080002 0x000e0220 0x0800003d 0x00000000
+ 0x77ffc004 0x01f1f008 0x00000000 0x00000007
+ 0x08000068 0x08000000 0x00000802 0x00064000
+ 0x00000060 0x000a000a 0xa0f10000 0x00000000
+ 0x00000000 0x800008ee 0xe0000000 0xff00ff00 >;
+ };
+
+ timing-533000000 {
+ clock-frequency = <533000000>;
+
+ nvidia,emc-auto-cal-interval = <0x001fffff>;
+ nvidia,emc-mode-1 = <0x000100c2>;
+ nvidia,emc-mode-2 = <0x00020006>;
+ nvidia,emc-mode-reset = <0x00000000>;
+ nvidia,emc-zcal-cnt-long = <0x00000030>;
+ nvidia,emc-cfg-periodic-qrst;
+
+ nvidia,emc-configuration = < 0x0000001f
+ 0x00000045 0x00000016 0x00000009 0x00000008
+ 0x00000009 0x00000003 0x0000000d 0x00000009
+ 0x00000009 0x00000005 0x00000003 0x00000000
+ 0x00000004 0x0000000a 0x00000006 0x0000000d
+ 0x00000010 0x000007df 0x00000000 0x000001f7
+ 0x00000003 0x00000003 0x00000009 0x00000000
+ 0x00000001 0x0000000f 0x0000004b 0x0000004b
+ 0x00000008 0x0000001b 0x0000000c 0x00000004
+ 0x00000002 0x000008aa 0x00000000 0x00000004
+ 0x00000000 0x00000000 0x00006282 0xf0120091
+ 0x00008000 0x0000000c 0x0000000c 0x0000000c
+ 0x0000000c 0x0000000a 0x0000000a 0x0000000a
+ 0x0000000a 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x0000000c 0x0000000c 0x0000000c
+ 0x0000000c 0x000c0220 0x0800003d 0x00000000
+ 0x77ffc004 0x01f1f408 0x00000000 0x00000007
+ 0x08000068 0x08000000 0x00000802 0x00064000
+ 0x000000c0 0x000e000e 0xa0f10000 0x00000000
+ 0x00000000 0x800010d9 0xe0000000 0xff00ff88 >;
+ };
+ };
+ };
+
+ battery: battery-cell {
+ compatible = "simple-battery";
+ device-chemistry = "lithium-ion";
+ charge-full-design-microamp-hours = <2080000>;
+ energy-full-design-microwatt-hours = <7700000>;
+ operating-range-celsius = <0 45>;
+ };
+
+ gpio-keys {
+ key-memo {
+ label = "Memo";
+ gpios = <&gpio TEGRA_GPIO(B, 6) GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_MEMO>;
+ debounce-interval = <10>;
+ wakeup-event-action = <EV_ACT_ASSERTED>;
+ wakeup-source;
+ };
+
+ key-volume-up {
+ label = "Volume Up";
+ gpios = <&gpio TEGRA_GPIO(I, 6) GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ debounce-interval = <10>;
+ wakeup-event-action = <EV_ACT_ASSERTED>;
+ wakeup-source;
+ };
+ };
+
+ gpio-leds {
+ led-power {
+ label = "power::white";
+ gpios = <&gpio TEGRA_GPIO(R, 3) GPIO_ACTIVE_HIGH>;
+
+ linux,default-trigger = "battery-charging";
+
+ color = <LED_COLOR_ID_WHITE>;
+ function = LED_FUNCTION_CHARGING;
+ };
+ };
+
+ regulator-lcd3v {
+ gpio = <&gpio TEGRA_GPIO(BB, 0) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ sound {
+ compatible = "lg,tegra-audio-max98089-p895",
+ "nvidia,tegra-audio-max98089";
+ nvidia,model = "LG Optimus Vu MAX98089";
+
+ nvidia,int-mic-en-gpios = <&gpio TEGRA_GPIO(I, 2) GPIO_ACTIVE_HIGH>;
+ };
+};
diff --git a/arch/arm/boot/dts/nvidia/tegra30-lg-x3.dtsi b/arch/arm/boot/dts/nvidia/tegra30-lg-x3.dtsi
new file mode 100644
index 000000000000..909260a5d0fb
--- /dev/null
+++ b/arch/arm/boot/dts/nvidia/tegra30-lg-x3.dtsi
@@ -0,0 +1,1812 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <dt-bindings/input/gpio-keys.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/mfd/max77620.h>
+#include <dt-bindings/thermal/thermal.h>
+
+#include "tegra30.dtsi"
+#include "tegra30-cpu-opp.dtsi"
+#include "tegra30-cpu-opp-microvolt.dtsi"
+
+/ {
+ chassis-type = "handset";
+
+ aliases {
+ mmc0 = &sdmmc4; /* eMMC */
+ mmc1 = &sdmmc1; /* WiFi */
+
+ rtc0 = &pmic;
+ rtc1 = "/rtc@7000e000";
+
+ serial0 = &uartd; /* Console */
+ serial1 = &uartc; /* Bluetooth */
+ serial2 = &uartb; /* GPS */
+ };
+
+ /*
+ * The decompressor and also some bootloaders rely on a
+ * pre-existing /chosen node to be available to insert the
+ * command line and merge other ATAGS info.
+ */
+ chosen { };
+
+ firmware {
+ trusted-foundations {
+ compatible = "tlm,trusted-foundations";
+ tlm,version-major = <2>;
+ tlm,version-minor = <8>;
+ };
+ };
+
+ memory@80000000 {
+ reg = <0x80000000 0x40000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ linux,cma@80000000 {
+ compatible = "shared-dma-pool";
+ alloc-ranges = <0x80000000 0x30000000>;
+ size = <0x10000000>; /* 256MiB */
+ linux,cma-default;
+ reusable;
+ };
+
+ ramoops@bed00000 {
+ compatible = "ramoops";
+ reg = <0xbed00000 0x10000>; /* 64kB */
+ console-size = <0x8000>; /* 32kB */
+ record-size = <0x400>; /* 1kB */
+ ecc-size = <16>;
+ };
+
+ trustzone@bfe00000 {
+ reg = <0xbfe00000 0x200000>; /* 2MB */
+ no-map;
+ };
+ };
+
+ vde@6001a000 {
+ assigned-clocks = <&tegra_car TEGRA30_CLK_VDE>;
+ assigned-clock-parents = <&tegra_car TEGRA30_CLK_PLL_P>;
+ assigned-clock-rates = <408000000>;
+ };
+
+ pinmux@70000868 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ /* WLAN SDIO pinmux */
+ sdmmc1-clk {
+ nvidia,pins = "sdmmc1_clk_pz0";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc1-cmd {
+ nvidia,pins = "sdmmc1_cmd_pz1",
+ "sdmmc1_dat3_py4",
+ "sdmmc1_dat2_py5",
+ "sdmmc1_dat1_py6",
+ "sdmmc1_dat0_py7";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ wlan-reset {
+ nvidia,pins = "pv3";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ wlan-host-wake {
+ nvidia,pins = "pu6";
+ nvidia,function = "pwm3";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* GNSS UART-B pinmux */
+ gps-pwr-en {
+ nvidia,pins = "kb_row6_pr6";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gps-ldo-en {
+ nvidia,pins = "ulpi_dir_py1";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ gps-clk-ref {
+ nvidia,pins = "gmi_ad8_ph0";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* Bluetooth UART-C pinmux */
+ uartc-cts-rxd {
+ nvidia,pins = "uart3_cts_n_pa1",
+ "uart3_rxd_pw7";
+ nvidia,function = "uartc";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ uartc-rts-txd {
+ nvidia,pins = "uart3_rts_n_pc0",
+ "uart3_txd_pw6";
+ nvidia,function = "uartc";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ bt-reset {
+ nvidia,pins = "clk2_req_pcc5";
+ nvidia,function = "dap";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ bt-dev-wake {
+ nvidia,pins = "kb_row11_ps3";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ bt-host-wake {
+ nvidia,pins = "kb_row12_ps4";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ bt-pcm-dap4 {
+ nvidia,pins = "dap4_fs_pp4",
+ "dap4_din_pp5",
+ "dap4_dout_pp6",
+ "dap4_sclk_pp7";
+ nvidia,function = "i2s3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* EMMC pinmux */
+ sdmmc4-clk {
+ nvidia,pins = "sdmmc4_clk_pcc4";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4-data {
+ nvidia,pins = "sdmmc4_cmd_pt7",
+ "sdmmc4_dat0_paa0",
+ "sdmmc4_dat1_paa1",
+ "sdmmc4_dat2_paa2",
+ "sdmmc4_dat3_paa3",
+ "sdmmc4_dat4_paa4",
+ "sdmmc4_dat5_paa5",
+ "sdmmc4_dat6_paa6",
+ "sdmmc4_dat7_paa7";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ sdmmc4-reset {
+ nvidia,pins = "sdmmc4_rst_n_pcc3";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* I2C pinmux */
+ gen1-i2c {
+ nvidia,pins = "gen1_i2c_scl_pc4",
+ "gen1_i2c_sda_pc5";
+ nvidia,function = "i2c1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ };
+ gen2-i2c {
+ nvidia,pins = "gen2_i2c_scl_pt5",
+ "gen2_i2c_sda_pt6";
+ nvidia,function = "i2c2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ };
+ cam-i2c {
+ nvidia,pins = "cam_i2c_scl_pbb1",
+ "cam_i2c_sda_pbb2";
+ nvidia,function = "i2c3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ };
+ ddc-i2c {
+ nvidia,pins = "ddc_scl_pv4",
+ "ddc_sda_pv5";
+ nvidia,function = "i2c4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ };
+ pwr-i2c {
+ nvidia,pins = "pwr_i2c_scl_pz6",
+ "pwr_i2c_sda_pz7";
+ nvidia,function = "i2cpwr";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <TEGRA_PIN_DISABLE>;
+ };
+ mhl-i2c {
+ nvidia,pins = "kb_col6_pq6",
+ "kb_col7_pq7";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* GPIO keys pinmux */
+ power-key {
+ nvidia,pins = "gmi_wp_n_pc7";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ volume-down {
+ nvidia,pins = "ulpi_data3_po4";
+ nvidia,function = "spi3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* Sensors pinmux */
+ sen-vdd {
+ nvidia,pins = "spi1_miso_px7";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ proxi-vdd {
+ nvidia,pins = "spi2_miso_px1";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ sen-vio {
+ nvidia,pins = "lcd_dc1_pd2";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ nct-irq {
+ nvidia,pins = "gmi_iordy_pi5";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ bat-irq {
+ nvidia,pins = "kb_row8_ps0";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ charger-irq {
+ nvidia,pins = "gmi_cs1_n_pj2";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ mpu-irq {
+ nvidia,pins = "gmi_ad12_ph4";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ compass-irq {
+ nvidia,pins = "gmi_ad13_ph5";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ light-irq {
+ nvidia,pins = "gmi_cs4_n_pk2";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* LED pinmux */
+ backlight-en {
+ nvidia,pins = "lcd_dc0_pn6";
+ nvidia,function = "rsvd3";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ flash-led-en {
+ nvidia,pins = "pbb3";
+ nvidia,function = "vgp3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ keypad-led {
+ nvidia,pins = "kb_row2_pr2",
+ "kb_row3_pr3";
+ nvidia,function = "rsvd3";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* NFC pinmux */
+ nfc-irq {
+ nvidia,pins = "spi2_cs1_n_pw2";
+ nvidia,function = "spi2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ nfc-ven {
+ nvidia,pins = "spi1_sck_px5";
+ nvidia,function = "spi1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ nfc-firm {
+ nvidia,pins = "kb_row0_pr0";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* DC pinmux */
+ lcd-pwr {
+ nvidia,pins = "lcd_pwr0_pb2",
+ "lcd_pwr1_pc1";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ lcd-wr-n {
+ nvidia,pins = "lcd_wr_n_pz3";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd-id {
+ nvidia,pins = "lcd_m1_pw1";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ lcd-pclk {
+ nvidia,pins = "lcd_pclk_pb3",
+ "lcd_de_pj1",
+ "lcd_hsync_pj3",
+ "lcd_vsync_pj4";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd-rgb-blue {
+ nvidia,pins = "lcd_d0_pe0",
+ "lcd_d1_pe1",
+ "lcd_d2_pe2",
+ "lcd_d3_pe3",
+ "lcd_d4_pe4",
+ "lcd_d5_pe5",
+ "lcd_d18_pm2",
+ "lcd_d19_pm3";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd-rgb-green {
+ nvidia,pins = "lcd_d6_pe6",
+ "lcd_d7_pe7",
+ "lcd_d8_pf0",
+ "lcd_d9_pf1",
+ "lcd_d10_pf2",
+ "lcd_d11_pf3",
+ "lcd_d20_pm4",
+ "lcd_d21_pm5";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ lcd-rgb-red {
+ nvidia,pins = "lcd_d12_pf4",
+ "lcd_d13_pf5",
+ "lcd_d14_pf6",
+ "lcd_d15_pf7",
+ "lcd_d16_pm0",
+ "lcd_d17_pm1",
+ "lcd_d22_pm6",
+ "lcd_d23_pm7";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* Bridge pinmux */
+ bridge-reset {
+ nvidia,pins = "ulpi_data1_po2";
+ nvidia,function = "spi3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ rgb-ic-en {
+ nvidia,pins = "gmi_a18_pb1";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ bridge-clk {
+ nvidia,pins = "clk3_out_pee0";
+ nvidia,function = "extperiph3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ rgb-bridge {
+ nvidia,pins = "lcd_sdin_pz2",
+ "lcd_sdout_pn5",
+ "lcd_cs0_n_pn4",
+ "lcd_sck_pz4";
+ nvidia,function = "spi5";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* Panel pinmux */
+ panel-reset {
+ nvidia,pins = "lcd_cs1_n_pw0";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ panel-vio {
+ nvidia,pins = "ulpi_clk_py0";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* Touchscreen pinmux */
+ touch-vdd {
+ nvidia,pins = "kb_col1_pq1";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ touch-vio {
+ nvidia,pins = "spi1_mosi_px4";
+ nvidia,function = "spi2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ touch-irq-n {
+ nvidia,pins = "kb_col3_pq3";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ touch-rst-n {
+ nvidia,pins = "ulpi_data0_po1";
+ nvidia,function = "spi3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ touch-maker-id {
+ nvidia,pins = "kb_col2_pq2";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* MHL pinmux */
+ mhl-vio {
+ nvidia,pins = "pv2";
+ nvidia,function = "owr";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ mhl-rst-n {
+ nvidia,pins = "clk3_req_pee1";
+ nvidia,function = "dev3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ mhl-irq {
+ nvidia,pins = "crt_vsync_pv7";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ mhl-sel {
+ nvidia,pins = "kb_row10_ps2";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ hdmi-hpd {
+ nvidia,pins = "hdmi_int_pn7";
+ nvidia,function = "hdmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* AUDIO pinmux */
+ hp-detect {
+ nvidia,pins = "pbb6";
+ nvidia,function = "vgp6";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ hp-hook {
+ nvidia,pins = "ulpi_data4_po5";
+ nvidia,function = "ulpi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ear-mic-en {
+ nvidia,pins = "spi2_mosi_px0";
+ nvidia,function = "spi2";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ audio-irq {
+ nvidia,pins = "spi2_cs2_n_pw3";
+ nvidia,function = "spi3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ audio-mclk {
+ nvidia,pins = "clk1_out_pw4";
+ nvidia,function = "extperiph1";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap-i2s0 {
+ nvidia,pins = "dap1_fs_pn0",
+ "dap1_din_pn1",
+ "dap1_dout_pn2",
+ "dap1_sclk_pn3";
+ nvidia,function = "i2s0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ dap-i2s1 {
+ nvidia,pins = "dap2_fs_pa2",
+ "dap2_sclk_pa3",
+ "dap2_din_pa4",
+ "dap2_dout_pa5";
+ nvidia,function = "i2s1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* MUIC pinmux */
+ muic-irq {
+ nvidia,pins = "gmi_cs0_n_pj0";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ muic-dp2t {
+ nvidia,pins = "pcc2";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ muic-usif {
+ nvidia,pins = "ulpi_stp_py3";
+ nvidia,function = "spi1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ifx-usb-vbus-en {
+ nvidia,pins = "kb_row4_pr4";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pcb-rev {
+ nvidia,pins = "gmi_wait_pi7",
+ "gmi_rst_n_pi4";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ jtag-rtck {
+ nvidia,pins = "jtag_rtck_pu7";
+ nvidia,function = "rtck";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* Camera pinmux */
+ cam-mclk {
+ nvidia,pins = "cam_mclk_pcc0";
+ nvidia,function = "vi_alt3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ cam-pmic-en {
+ nvidia,pins = "pbb4";
+ nvidia,function = "vgp4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ front-cam-rst {
+ nvidia,pins = "pbb5";
+ nvidia,function = "vgp5";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ front-cam-vio {
+ nvidia,pins = "ulpi_nxt_py2";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ rear-cam-rst {
+ nvidia,pins = "gmi_cs3_n_pk4";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ rear-cam-eprom-pr {
+ nvidia,pins = "gmi_cs2_n_pk3";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ rear-cam-vcm-pwdn {
+ nvidia,pins = "kb_row1_pr1";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* Haptic pinmux */
+ haptic-en {
+ nvidia,pins = "gmi_ad9_ph1";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ haptic-osc {
+ nvidia,pins = "gmi_ad11_ph3";
+ nvidia,function = "pwm3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* Modem pinmux */
+ cp2ap-ack1-host-active {
+ nvidia,pins = "pu5";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ cp2ap-ack2-host-wakeup {
+ nvidia,pins = "pv0";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ap2cp-ack2-suspend-req {
+ nvidia,pins = "kb_row14_ps6";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ap2cp-ack1-slave-wakeup {
+ nvidia,pins = "kb_row15_ps7";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ cp-kkp {
+ nvidia,pins = "kb_col0_pq0";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ cp-crash-irq {
+ nvidia,pins = "kb_row13_ps5";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ ap2cp-uarta-tx-ipc {
+ nvidia,pins = "pu0";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ ap2cp-uarta-rx-ipc {
+ nvidia,pins = "pu1";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ fota-ap-cts-cp-rts {
+ nvidia,pins = "pu2";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ fota-ap-rts-cp-cts {
+ nvidia,pins = "pu3";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ modem-enable {
+ nvidia,pins = "ulpi_data7_po0";
+ nvidia,function = "hsi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ modem-reset {
+ nvidia,pins = "pv1";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ dap-i2s2 {
+ nvidia,pins = "dap3_fs_pp0",
+ "dap3_din_pp1",
+ "dap3_dout_pp2",
+ "dap3_sclk_pp3";
+ nvidia,function = "i2s2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* GPIO power/drive control */
+ drive-i2c {
+ nvidia,pins = "drive_dbg",
+ "drive_at5",
+ "drive_gme",
+ "drive_ddc",
+ "drive_ao1";
+ nvidia,high-speed-mode = <TEGRA_PIN_DISABLE>;
+ nvidia,schmitt = <TEGRA_PIN_ENABLE>;
+ nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_1>;
+ nvidia,pull-down-strength = <31>;
+ nvidia,pull-up-strength = <31>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ };
+
+ drive-uart3 {
+ nvidia,pins = "drive_uart3";
+ nvidia,high-speed-mode = <TEGRA_PIN_DISABLE>;
+ nvidia,schmitt = <TEGRA_PIN_ENABLE>;
+ nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_1>;
+ nvidia,pull-down-strength = <31>;
+ nvidia,pull-up-strength = <31>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ };
+
+ drive-gmi {
+ nvidia,pins = "drive_at3";
+ nvidia,high-speed-mode = <TEGRA_PIN_DISABLE>;
+ nvidia,schmitt = <TEGRA_PIN_ENABLE>;
+ nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_1>;
+ nvidia,pull-down-strength = <31>;
+ nvidia,pull-up-strength = <31>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ };
+ };
+ };
+
+ uartb: serial@70006040 {
+ compatible = "nvidia,tegra30-hsuart";
+ reset-names = "serial";
+ /delete-property/ reg-shift;
+ status = "okay";
+
+ /* GNSS GSD5T */
+ };
+
+ uartc: serial@70006200 {
+ compatible = "nvidia,tegra30-hsuart";
+ reset-names = "serial";
+ /delete-property/ reg-shift;
+ status = "okay";
+
+ nvidia,adjust-baud-rates = <0 9600 100>,
+ <9600 115200 200>,
+ <1000000 4000000 136>;
+
+ /* BCM4330B1 37.4 MHz Class 1.5 ExtLNA */
+ bluetooth {
+ compatible = "brcm,bcm4330-bt";
+ max-speed = <4000000>;
+
+ clocks = <&tegra_pmc TEGRA_PMC_CLK_BLINK>;
+ clock-names = "txco";
+
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(S, 4) IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "host-wakeup";
+
+ device-wakeup-gpios = <&gpio TEGRA_GPIO(S, 3) GPIO_ACTIVE_HIGH>;
+ shutdown-gpios = <&gpio TEGRA_GPIO(CC, 5) GPIO_ACTIVE_HIGH>;
+
+ vbat-supply = <&vdd_3v3_vbat>;
+ vddio-supply = <&vdd_1v8_vio>;
+ };
+ };
+
+ uartd: serial@70006300 {
+ /delete-property/ dmas;
+ /delete-property/ dma-names;
+ status = "okay";
+
+ /* Console */
+ };
+
+ pwm@7000a000 {
+ status = "okay";
+ };
+
+ gen1_i2c: i2c@7000c000 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ /* Aichi AMI306 digital compass */
+ magnetometer@e {
+ compatible = "asahi-kasei,ak8974";
+ reg = <0x0e>;
+
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(H, 5) IRQ_TYPE_EDGE_RISING>;
+
+ avdd-supply = <&vdd_3v0_sen>;
+ dvdd-supply = <&vdd_1v8_vio>;
+
+ mount-matrix = "-1", "0", "0",
+ "0", "1", "0",
+ "0", "0", "-1";
+ };
+
+ max98089: audio-codec@10 {
+ compatible = "maxim,max98089";
+ reg = <0x10>;
+
+ clocks = <&tegra_pmc TEGRA_PMC_CLK_OUT_1>;
+ clock-names = "mclk";
+
+ assigned-clocks = <&tegra_pmc TEGRA_PMC_CLK_OUT_1>;
+ assigned-clock-parents = <&tegra_car TEGRA30_CLK_EXTERN1>;
+ };
+
+ nfc@28 {
+ compatible = "nxp,pn544-i2c";
+ reg = <0x28>;
+
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(W, 2) IRQ_TYPE_EDGE_RISING>;
+
+ enable-gpios = <&gpio TEGRA_GPIO(X, 5) GPIO_ACTIVE_HIGH>;
+ firmware-gpios = <&gpio TEGRA_GPIO(R, 0) GPIO_ACTIVE_HIGH>;
+ };
+
+ imu@68 {
+ compatible = "invensense,mpu6050";
+ reg = <0x68>;
+
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(H, 4) IRQ_TYPE_EDGE_RISING>;
+
+ vdd-supply = <&vdd_3v0_sen>;
+ vddio-supply = <&vdd_1v8_sen>;
+
+ mount-matrix = "1", "0", "0",
+ "0", "1", "0",
+ "0", "0", "-1";
+ };
+ };
+
+ gen2_i2c: i2c@7000c400 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ /* Synaptics RMI4 S3203B touchcreen */
+ touchscreen@20 {
+ compatible = "syna,rmi4-i2c";
+ reg = <0x20>;
+
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(Q, 3) IRQ_TYPE_EDGE_FALLING>;
+
+ vdd-supply = <&vdd_3v0_touch>;
+ vio-supply = <&vdd_1v8_touch>;
+
+ syna,reset-delay-ms = <20>;
+ syna,startup-delay-ms = <200>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ rmi4-f01@1 {
+ reg = <0x1>;
+ syna,nosleep-mode = <1>;
+ };
+
+ rmi4-f11@11 {
+ reg = <0x11>;
+ syna,sensor-type = <1>;
+
+ syna,clip-x-low = <0>;
+ syna,clip-y-low = <0>;
+ };
+ };
+ };
+
+ cam_i2c: i2c@7000c500 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ dw9714: coil@c {
+ compatible = "dongwoon,dw9714";
+ reg = <0x0c>;
+
+ enable-gpios = <&gpio TEGRA_GPIO(R, 1) GPIO_ACTIVE_HIGH>;
+
+ vcc-supply = <&vcc_focuser>;
+ };
+
+ camera-pmic@7d {
+ compatible = "ti,lp8720";
+ reg = <0x7d>;
+
+ enable-gpios = <&gpio TEGRA_GPIO(BB, 4) GPIO_ACTIVE_HIGH>;
+
+ vt_1v2_front: ldo1 {
+ regulator-name = "vt_1v2_dig";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ vt_2v7_front: ldo2 {
+ regulator-name = "vt_2v7_vana";
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <2700000>;
+ };
+
+ vdd_2v7_rear: ldo3 {
+ regulator-name = "8m_2v7_vana";
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ vio_1v8_rear: ldo4 {
+ regulator-name = "vio_1v8_cam";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vcc_focuser: ldo5 {
+ regulator-name = "8m_2v8_vcm";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ vdd_1v2_rear: buck {
+ regulator-name = "8m_1v2_cam";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+ };
+ };
+
+ hdmi_ddc: i2c@7000c700 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ pwr_i2c: i2c@7000d000 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ pmic: max77663@1c {
+ compatible = "maxim,max77663";
+ reg = <0x1c>;
+
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+
+ #gpio-cells = <2>;
+ gpio-controller;
+
+ system-power-controller;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&max77663_default>;
+
+ max77663_default: pinmux {
+ gpio1 {
+ pins = "gpio1";
+ function = "gpio";
+ drive-open-drain = <1>;
+ };
+
+ gpio4 {
+ pins = "gpio4";
+ function = "32k-out1";
+ };
+ };
+
+ fps {
+ fps0 {
+ maxim,fps-event-source = <MAX77620_FPS_EVENT_SRC_EN0>;
+ };
+
+ fps1 {
+ maxim,fps-event-source = <MAX77620_FPS_EVENT_SRC_EN1>;
+ };
+
+ fps2 {
+ maxim,fps-event-source = <MAX77620_FPS_EVENT_SRC_EN0>;
+ };
+ };
+
+ regulators {
+ in-sd0-supply = <&vdd_5v0_vbus>;
+ in-sd1-supply = <&vdd_5v0_vbus>;
+ in-sd2-supply = <&vdd_5v0_vbus>;
+ in-sd3-supply = <&vdd_5v0_vbus>;
+
+ in-ldo0-1-supply = <&vdd_1v8_vio>;
+ in-ldo2-supply = <&vdd_3v3_vbat>;
+ in-ldo3-5-supply = <&vdd_3v3_vbat>;
+ in-ldo4-6-supply = <&vdd_3v3_vbat>;
+ in-ldo7-8-supply = <&vdd_1v8_vio>;
+
+ vdd_cpu: sd0 {
+ regulator-name = "vdd_cpu";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1250000>;
+ regulator-coupled-with = <&vdd_core>;
+ regulator-coupled-max-spread = <300000>;
+ regulator-max-step-microvolt = <100000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ nvidia,tegra-cpu-regulator;
+ maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
+ };
+
+ vdd_core: sd1 {
+ regulator-name = "vdd_core";
+ regulator-min-microvolt = <950000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-coupled-with = <&vdd_cpu>;
+ regulator-coupled-max-spread = <300000>;
+ regulator-max-step-microvolt = <100000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ nvidia,tegra-core-regulator;
+ maxim,active-fps-source = <MAX77620_FPS_SRC_1>;
+ };
+
+ vdd_1v8_vio: sd2 {
+ regulator-name = "vdd_1v8_gen";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
+ };
+
+ sd3 {
+ regulator-name = "vddio_ddr";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
+ };
+
+ ldo0 {
+ regulator-name = "avdd_pll";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ maxim,active-fps-source = <MAX77620_FPS_SRC_1>;
+ };
+
+ ldo1 {
+ regulator-name = "vdd_ddr_hs";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
+ };
+
+ avdd_3v3_periph: ldo2 {
+ regulator-name = "avdd_usb";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
+ };
+
+ vdd_usd: ldo3 {
+ regulator-name = "vdd_sdmmc3";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+
+ maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
+ };
+
+ ldo4 {
+ regulator-name = "vdd_rtc";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ maxim,active-fps-source = <MAX77620_FPS_SRC_0>;
+ };
+
+ vcore_emmc: ldo5 {
+ regulator-name = "vdd_ddr_rx";
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ maxim,active-fps-source = <MAX77620_FPS_SRC_0>;
+ };
+
+ avdd_1v8_hdmi_pll: ldo6 {
+ regulator-name = "avdd_osc";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
+ };
+
+ vdd_1v2_mhl: ldo7 {
+ regulator-name = "vdd_1v2_mhl";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1250000>;
+
+ maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
+ };
+
+ ldo8 {
+ regulator-name = "avdd_dsi_csi";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+
+ maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
+ };
+ };
+ };
+
+ fuel-gauge@36 {
+ compatible = "maxim,max17043";
+ reg = <0x36>;
+
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(S, 0) IRQ_TYPE_EDGE_FALLING>;
+
+ monitored-battery = <&battery>;
+
+ maxim,alert-low-soc-level = <10>;
+ wakeup-source;
+ };
+
+ power-sensor@40 {
+ compatible = "ti,ina230";
+ reg = <0x40>;
+
+ vs-supply = <&vdd_3v0_sen>;
+ };
+
+ nct72: temperature-sensor@4c {
+ compatible = "onnn,nct1008";
+ reg = <0x4c>;
+
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(I, 5) IRQ_TYPE_EDGE_FALLING>;
+
+ vcc-supply = <&vdd_3v0_sen>;
+ #thermal-sensor-cells = <1>;
+ };
+ };
+
+ i2c-mhl {
+ compatible = "i2c-gpio";
+
+ sda-gpios = <&gpio TEGRA_GPIO(Q, 7) (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpio TEGRA_GPIO(Q, 6) (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+
+ i2c-gpio,delay-us = <5>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ spi@7000dc00 {
+ status = "okay";
+ spi-max-frequency = <25000000>;
+
+ /* DSI bridge */
+ };
+
+ pmc@7000e400 {
+ status = "okay";
+ nvidia,invert-interrupt;
+ nvidia,suspend-mode = <2>;
+ nvidia,cpu-pwr-good-time = <2000>;
+ nvidia,cpu-pwr-off-time = <200>;
+ nvidia,core-pwr-good-time = <3845 3845>;
+ nvidia,core-pwr-off-time = <0>;
+ nvidia,core-power-req-active-high;
+ nvidia,sys-clock-req-active-high;
+ core-supply = <&vdd_core>;
+
+ i2c-thermtrip {
+ nvidia,i2c-controller-id = <4>;
+ nvidia,bus-addr = <0x1c>;
+ nvidia,reg-addr = <0x41>;
+ nvidia,reg-data = <0x02>;
+ };
+ };
+
+ hda@70030000 {
+ status = "okay";
+ };
+
+ ahub@70080000 {
+ /* HIFI CODEC */
+ i2s@70080300 { /* i2s0 */
+ status = "okay";
+ };
+
+ /* BASEBAND */
+ i2s@70080500 { /* i2s2 */
+ status = "okay";
+ };
+
+ /* BT SCO */
+ i2s@70080600 { /* i2s3 */
+ status = "okay";
+ };
+ };
+
+ sdmmc1: mmc@78000000 {
+ status = "okay";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ assigned-clocks = <&tegra_car TEGRA30_CLK_SDMMC1>;
+ assigned-clock-parents = <&tegra_car TEGRA30_CLK_PLL_C>;
+ assigned-clock-rates = <50000000>;
+
+ max-frequency = <50000000>;
+ keep-power-in-suspend;
+ bus-width = <4>;
+ non-removable;
+
+ mmc-pwrseq = <&brcm_wifi_pwrseq>;
+ vmmc-supply = <&vdd_3v3_vbat>;
+ vqmmc-supply = <&vdd_1v8_vio>;
+
+ /* BCM4330B1 37.4 MHz Class 1.5 ExtLNA */
+ wifi@1 {
+ compatible = "brcm,bcm4329-fmac";
+ reg = <1>;
+
+ interrupt-parent = <&gpio>;
+ interrupts = <TEGRA_GPIO(U, 6) IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "host-wake";
+ };
+ };
+
+ sdmmc4: mmc@78000600 {
+ status = "okay";
+ bus-width = <8>;
+
+ non-removable;
+ mmc-ddr-1_8v;
+
+ vmmc-supply = <&vcore_emmc>;
+ vqmmc-supply = <&vdd_1v8_vio>;
+ };
+
+ /* Micro USB */
+ usb@7d000000 {
+ compatible = "nvidia,tegra30-udc";
+ status = "okay";
+ dr_mode = "peripheral";
+ };
+
+ usb-phy@7d000000 {
+ status = "okay";
+ dr_mode = "peripheral";
+ nvidia,hssync-start-delay = <0>;
+ nvidia,xcvr-lsfslew = <2>;
+ nvidia,xcvr-lsrslew = <2>;
+ vbus-supply = <&avdd_3v3_periph>;
+ };
+
+ /* PMIC has a built-in 32KHz oscillator which is used by PMC */
+ clk32k_in: clock-32k {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "pmic-oscillator";
+ };
+
+ gps_refclk: clock-gps {
+ compatible = "fixed-clock";
+ clock-frequency = <26000000>;
+ clock-accuracy = <100>;
+ #clock-cells = <0>;
+ };
+
+ gps_osc: clock-gps-osc-gate {
+ compatible = "gpio-gate-clock";
+ enable-gpios = <&gpio TEGRA_GPIO(H, 0) GPIO_ACTIVE_HIGH>;
+ clocks = <&gps_refclk>;
+ #clock-cells = <0>;
+ };
+
+ cpus {
+ cpu0: cpu@0 {
+ cpu-supply = <&vdd_cpu>;
+ operating-points-v2 = <&cpu0_opp_table>;
+ #cooling-cells = <2>;
+ };
+ cpu1: cpu@1 {
+ cpu-supply = <&vdd_cpu>;
+ operating-points-v2 = <&cpu0_opp_table>;
+ #cooling-cells = <2>;
+ };
+ cpu2: cpu@2 {
+ cpu-supply = <&vdd_cpu>;
+ operating-points-v2 = <&cpu0_opp_table>;
+ #cooling-cells = <2>;
+ };
+ cpu3: cpu@3 {
+ cpu-supply = <&vdd_cpu>;
+ operating-points-v2 = <&cpu0_opp_table>;
+ #cooling-cells = <2>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ key-power {
+ label = "Power";
+ gpios = <&gpio TEGRA_GPIO(C, 7) GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_POWER>;
+ debounce-interval = <10>;
+ wakeup-event-action = <EV_ACT_ASSERTED>;
+ wakeup-source;
+ };
+
+ key-volume-down {
+ label = "Volume Down";
+ gpios = <&gpio TEGRA_GPIO(O, 4) GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ debounce-interval = <10>;
+ wakeup-event-action = <EV_ACT_ASSERTED>;
+ wakeup-source;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ led-keypad {
+ label = "keypad::white";
+ gpios = <&gpio TEGRA_GPIO(R, 2) GPIO_ACTIVE_HIGH>;
+
+ color = <LED_COLOR_ID_WHITE>;
+ function = LED_FUNCTION_KBD_BACKLIGHT;
+ };
+ };
+
+ opp-table-actmon {
+ /delete-node/ opp-625000000;
+ /delete-node/ opp-667000000;
+ /delete-node/ opp-750000000;
+ /delete-node/ opp-800000000;
+ /delete-node/ opp-900000000;
+ };
+
+ opp-table-emc {
+ /delete-node/ opp-625000000-1200;
+ /delete-node/ opp-625000000-1250;
+ /delete-node/ opp-667000000-1200;
+ /delete-node/ opp-750000000-1300;
+ /delete-node/ opp-800000000-1300;
+ /delete-node/ opp-900000000-1350;
+ };
+
+ brcm_wifi_pwrseq: pwrseq-wifi {
+ compatible = "mmc-pwrseq-simple";
+
+ clocks = <&tegra_pmc TEGRA_PMC_CLK_BLINK>;
+ clock-names = "ext_clock";
+
+ reset-gpios = <&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_LOW>;
+ post-power-on-delay-ms = <300>;
+ power-off-delay-us = <300>;
+ };
+
+ vdd_5v0_vbus: regulator-vbus {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vdd_3v3_vbat: regulator-vbat {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd_vbat";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vdd_5v0_vbus>;
+ };
+
+ vdd_3v0_sen: regulator-sen3v {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd_3v0_sensor";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ gpio = <&gpio TEGRA_GPIO(X, 7) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_3v3_vbat>;
+ };
+
+ vdd_3v0_proxi: regulator-proxi {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd_3v0_proxi";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ gpio = <&gpio TEGRA_GPIO(X, 1) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_3v3_vbat>;
+ };
+
+ vdd_1v8_sen: regulator-sen1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd_1v8_sensor";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ gpio = <&gpio TEGRA_GPIO(D, 2) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_3v3_vbat>;
+ };
+
+ vcc_3v0_lcd: regulator-lcd3v {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_3v0_lcd";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ vin-supply = <&vdd_3v3_vbat>;
+ };
+
+ iovcc_1v8_lcd: regulator-lcd1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "iovcc_1v8_lcd";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ gpio = <&gpio TEGRA_GPIO(Y, 0) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_3v3_vbat>;
+ };
+
+ vio_1v8_mhl: regulator-mhl1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "vio_1v8_mhl";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ gpio = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_3v3_vbat>;
+ };
+
+ vdd_3v0_touch: regulator-touchpwr {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd_3v0_touch";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-boot-on;
+ gpio = <&gpio TEGRA_GPIO(Q, 1) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_3v3_vbat>;
+ };
+
+ vdd_1v8_touch: regulator-touchvio {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd_1v8_touch";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ gpio = <&gpio TEGRA_GPIO(X, 4) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_3v3_vbat>;
+ };
+
+ vcc_1v8_gps: regulator-gps {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_1v8_gps";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ gpio = <&gpio TEGRA_GPIO(Y, 1) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_3v3_vbat>;
+ };
+
+ vio_1v8_front: regulator-frontvio {
+ compatible = "regulator-fixed";
+ regulator-name = "vt_1v8_cam_vio";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ gpio = <&gpio TEGRA_GPIO(Y, 2) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_3v3_vbat>;
+ };
+
+ sound {
+ nvidia,audio-routing =
+ "Headphone Jack", "HPL",
+ "Headphone Jack", "HPR",
+ "Int Spk", "SPKL",
+ "Int Spk", "SPKR",
+ "Earpiece", "RECL",
+ "Earpiece", "RECR",
+ "INA1", "Mic Jack",
+ "MIC1", "MICBIAS",
+ "MICBIAS", "Internal Mic 1",
+ "MIC2", "Internal Mic 2";
+
+ nvidia,i2s-controller = <&tegra_i2s0>;
+ nvidia,audio-codec = <&max98089>;
+
+ nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(BB, 6) GPIO_ACTIVE_LOW>;
+ nvidia,mic-det-gpios = <&gpio TEGRA_GPIO(O, 5) GPIO_ACTIVE_HIGH>;
+ nvidia,ext-mic-en-gpios = <&gpio TEGRA_GPIO(X, 0) GPIO_ACTIVE_HIGH>;
+ nvidia,coupled-mic-hp-det;
+
+ clocks = <&tegra_car TEGRA30_CLK_PLL_A>,
+ <&tegra_car TEGRA30_CLK_PLL_A_OUT0>,
+ <&tegra_pmc TEGRA_PMC_CLK_OUT_1>;
+ clock-names = "pll_a", "pll_a_out0", "mclk";
+
+ assigned-clocks = <&tegra_car TEGRA30_CLK_EXTERN1>,
+ <&tegra_pmc TEGRA_PMC_CLK_OUT_1>;
+
+ assigned-clock-parents = <&tegra_car TEGRA30_CLK_PLL_A_OUT0>,
+ <&tegra_car TEGRA30_CLK_EXTERN1>;
+ };
+
+ thermal-zones {
+ /*
+ * NCT72 has two sensors:
+ *
+ * 0: internal that monitors ambient/skin temperature
+ * 1: external that is connected to the CPU's diode
+ *
+ * Ideally we should use userspace thermal governor,
+ * but it's a much more complex solution. The "skin"
+ * zone exists as a simpler solution which prevents
+ * this device from getting too hot from a user's
+ * tactile perspective. The CPU zone is intended to
+ * protect silicon from damage.
+ */
+
+ skin-thermal {
+ polling-delay-passive = <1000>; /* milliseconds */
+ polling-delay = <5000>; /* milliseconds */
+
+ thermal-sensors = <&nct72 0>;
+
+ trips {
+ trip0: skin-alert {
+ /* throttle at 50C until temperature drops to 49.8C */
+ temperature = <50000>;
+ hysteresis = <200>;
+ type = "passive";
+ };
+
+ trip1: skin-crit {
+ /* shut down at 60C */
+ temperature = <60000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&trip0>;
+ 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>,
+ <&actmon THERMAL_NO_LIMIT
+ THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ cpu-thermal {
+ polling-delay-passive = <1000>; /* milliseconds */
+ polling-delay = <5000>; /* milliseconds */
+
+ thermal-sensors = <&nct72 1>;
+
+ trips {
+ trip2: cpu-alert {
+ /* throttle at 75C until temperature drops to 74.8C */
+ temperature = <75000>;
+ hysteresis = <200>;
+ type = "passive";
+ };
+
+ trip3: cpu-crit {
+ /* shut down at 90C */
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map1 {
+ trip = <&trip2>;
+ 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>,
+ <&actmon THERMAL_NO_LIMIT
+ THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/nxp/imx/Makefile b/arch/arm/boot/dts/nxp/imx/Makefile
index a724d1a7a9a0..4052cad859fa 100644
--- a/arch/arm/boot/dts/nxp/imx/Makefile
+++ b/arch/arm/boot/dts/nxp/imx/Makefile
@@ -45,7 +45,9 @@ dtb-$(CONFIG_SOC_IMX53) += \
imx53-mba53.dtb \
imx53-ppd.dtb \
imx53-qsb.dtb \
+ imx53-qsb-hdmi.dtb \
imx53-qsrb.dtb \
+ imx53-qsrb-hdmi.dtb \
imx53-sk-imx53.dtb \
imx53-sk-imx53-atm0700d4-lvds.dtb \
imx53-sk-imx53-atm0700d4-rgb.dtb \
@@ -54,6 +56,8 @@ dtb-$(CONFIG_SOC_IMX53) += \
imx53-tx53-x13x.dtb \
imx53-usbarmory.dtb \
imx53-voipac-bsb.dtb
+imx53-qsb-hdmi-dtbs := imx53-qsb.dtb imx53-qsb-hdmi.dtbo
+imx53-qsrb-hdmi-dtbs := imx53-qsrb.dtb imx53-qsb-hdmi.dtbo
dtb-$(CONFIG_SOC_IMX6Q) += \
imx6dl-alti6p.dtb \
imx6dl-apf6dev.dtb \
@@ -118,6 +122,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
imx6dl-sabrelite.dtb \
imx6dl-sabresd.dtb \
imx6dl-savageboard.dtb \
+ imx6dl-sielaff.dtb \
imx6dl-skov-revc-lt2.dtb \
imx6dl-skov-revc-lt6.dtb \
imx6dl-solidsense.dtb \
@@ -147,6 +152,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
imx6dl-yapp4-phoenix.dtb \
imx6dl-yapp4-ursa.dtb \
imx6q-apalis-eval.dtb \
+ imx6q-apalis-eval-v1.2.dtb \
imx6q-apalis-ixora.dtb \
imx6q-apalis-ixora-v1.1.dtb \
imx6q-apalis-ixora-v1.2.dtb \
diff --git a/arch/arm/boot/dts/nxp/imx/imx1-apf9328.dts b/arch/arm/boot/dts/nxp/imx/imx1-apf9328.dts
index e66eef87a7a4..058e9435524f 100644
--- a/arch/arm/boot/dts/nxp/imx/imx1-apf9328.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx1-apf9328.dts
@@ -54,7 +54,7 @@
#size-cells = <1>;
};
- eth: eth@4,c00000 {
+ eth: ethernet@4,c00000 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_eth>;
compatible = "davicom,dm9000";
diff --git a/arch/arm/boot/dts/nxp/imx/imx1.dtsi b/arch/arm/boot/dts/nxp/imx/imx1.dtsi
index 1ac10965fdfd..389ecb1ebf8f 100644
--- a/arch/arm/boot/dts/nxp/imx/imx1.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx1.dtsi
@@ -251,7 +251,7 @@
};
};
- weim: weim@220000 {
+ weim: memory-controller@220000 {
#address-cells = <2>;
#size-cells = <1>;
compatible = "fsl,imx1-weim";
diff --git a/arch/arm/boot/dts/nxp/imx/imx27.dtsi b/arch/arm/boot/dts/nxp/imx/imx27.dtsi
index ec472695c71e..ec3ccc8f4095 100644
--- a/arch/arm/boot/dts/nxp/imx/imx27.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx27.dtsi
@@ -568,7 +568,7 @@
status = "disabled";
};
- weim: weim@d8002000 {
+ weim: memory-controller@d8002000 {
#address-cells = <2>;
#size-cells = <1>;
compatible = "fsl,imx27-weim";
diff --git a/arch/arm/boot/dts/nxp/imx/imx31.dtsi b/arch/arm/boot/dts/nxp/imx/imx31.dtsi
index e1ae7c175f7d..00006c90d9a7 100644
--- a/arch/arm/boot/dts/nxp/imx/imx31.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx31.dtsi
@@ -352,7 +352,7 @@
status = "disabled";
};
- weim: weim@b8002000 {
+ weim: memory-controller@b8002000 {
compatible = "fsl,imx31-weim", "fsl,imx27-weim";
reg = <0xb8002000 0x1000>;
clocks = <&clks 56>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx35.dtsi b/arch/arm/boot/dts/nxp/imx/imx35.dtsi
index 2d20e5541acc..442dc15677b8 100644
--- a/arch/arm/boot/dts/nxp/imx/imx35.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx35.dtsi
@@ -374,7 +374,7 @@
status = "disabled";
};
- weim: weim@b8002000 {
+ weim: memory-controller@b8002000 {
#address-cells = <2>;
#size-cells = <1>;
clocks = <&clks 0>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx51.dtsi b/arch/arm/boot/dts/nxp/imx/imx51.dtsi
index c96d6311dfa7..4efce49022e4 100644
--- a/arch/arm/boot/dts/nxp/imx/imx51.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx51.dtsi
@@ -578,7 +578,7 @@
reg = <0x83fd8000 0x1000>;
};
- weim: weim@83fda000 {
+ weim: memory-controller@83fda000 {
#address-cells = <2>;
#size-cells = <1>;
compatible = "fsl,imx51-weim";
diff --git a/arch/arm/boot/dts/nxp/imx/imx53-qsb-hdmi.dtso b/arch/arm/boot/dts/nxp/imx/imx53-qsb-hdmi.dtso
new file mode 100644
index 000000000000..c84e9b052527
--- /dev/null
+++ b/arch/arm/boot/dts/nxp/imx/imx53-qsb-hdmi.dtso
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * DT overlay for MCIMXHDMICARD as used with the iMX53 QSB or QSRB boards
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+ /delete-node/ panel;
+
+ hdmi: connector-hdmi {
+ compatible = "hdmi-connector";
+ label = "hdmi";
+ type = "a";
+
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&sii9022_out>;
+ };
+ };
+ };
+
+ reg_1p2v: regulator-1p2v {
+ compatible = "regulator-fixed";
+ regulator-name = "1P2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ vin-supply = <&reg_3p2v>;
+ };
+};
+
+&display0 {
+ status = "okay";
+};
+
+&display0 {
+ port@1 {
+ display0_out: endpoint {
+ remote-endpoint = <&sii9022_in>;
+ };
+ };
+};
+
+&i2c2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ sii9022: bridge-hdmi@39 {
+ compatible = "sil,sii9022";
+ reg = <0x39>;
+ reset-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
+ interrupts-extended = <&gpio3 31 IRQ_TYPE_LEVEL_LOW>;
+ iovcc-supply = <&reg_3p2v>;
+ #sound-dai-cells = <0>;
+ sil,i2s-data-lanes = <0>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ sii9022_in: endpoint {
+ remote-endpoint = <&display0_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ sii9022_out: endpoint {
+ remote-endpoint = <&hdmi_connector_in>;
+ };
+ };
+ };
+ };
+};
+
+&tve {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-sielaff.dts b/arch/arm/boot/dts/nxp/imx/imx6dl-sielaff.dts
new file mode 100644
index 000000000000..7de8d5f26518
--- /dev/null
+++ b/arch/arm/boot/dts/nxp/imx/imx6dl-sielaff.dts
@@ -0,0 +1,533 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright (C) 2022 Kontron Electronics GmbH
+ */
+
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include <dt-bindings/clock/imx6qdl-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ model = "Sielaff i.MX6 Solo";
+ compatible = "sielaff,imx6dl-board", "fsl,imx6dl";
+
+ chosen {
+ stdout-path = &uart2;
+ };
+
+ backlight: pwm-backlight {
+ compatible = "pwm-backlight";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_backlight>;
+ pwms = <&pwm3 0 50000 0>;
+ brightness-levels = <0 0 64 88 112 136 184 232 255>;
+ default-brightness-level = <4>;
+ enable-gpios = <&gpio6 16 GPIO_ACTIVE_HIGH>;
+ power-supply = <&reg_backlight>;
+ };
+
+ cec {
+ compatible = "cec-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hdmi_cec>;
+ cec-gpios = <&gpio2 7 GPIO_ACTIVE_HIGH>;
+ hdmi-phandle = <&hdmi>;
+ };
+
+ enet_ref: clock-enet-ref {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <50000000>;
+ clock-output-names = "enet-ref";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_keys>;
+
+ key-0 {
+ gpios = <&gpio2 16 0>;
+ debounce-interval = <10>;
+ linux,code = <1>;
+ };
+
+ key-1 {
+ gpios = <&gpio3 27 0>;
+ debounce-interval = <10>;
+ linux,code = <2>;
+ };
+
+ key-2 {
+ gpios = <&gpio5 4 0>;
+ debounce-interval = <10>;
+ linux,code = <3>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio_leds>;
+
+ led-debug {
+ label = "debug-led";
+ gpios = <&gpio5 21 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ memory@80000000 {
+ reg = <0x80000000 0x20000000>;
+ device_type = "memory";
+ };
+
+ osc_eth_phy: clock-osc-eth-phy {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ clock-output-names = "osc-eth-phy";
+ };
+
+ panel {
+ compatible = "lg,lb070wv8";
+ backlight = <&backlight>;
+ power-supply = <&reg_3v3>;
+
+ port {
+ panel_in_lvds: endpoint {
+ remote-endpoint = <&lvds_out>;
+ };
+ };
+ };
+
+ reg_3v3: regulator-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_backlight: regulator-backlight {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_backlight>;
+ enable-active-high;
+ gpio = <&gpio1 23 GPIO_ACTIVE_HIGH>;
+ regulator-name = "backlight";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ };
+
+ reg_usb_otg_vbus: regulator-usb-otg-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_usbotg_vbus>;
+ enable-active-high;
+ gpio = <&gpio4 15 GPIO_ACTIVE_HIGH>;
+ regulator-name = "usb_otg_vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+};
+
+&ecspi2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi2>;
+ cs-gpios = <&gpio5 29 GPIO_ACTIVE_LOW>;
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <20000000>;
+ };
+};
+
+&fec {
+ /*
+ * Set PTP clock to external instead of internal reference, as the
+ * REF_CLK from the PHY is fed back into the i.MX6 and the GPR
+ * register needs to be set accordingly (see mach-imx6q.c).
+ */
+ clocks = <&clks IMX6QDL_CLK_ENET>,
+ <&clks IMX6QDL_CLK_ENET>,
+ <&enet_ref>,
+ <&clks IMX6QDL_CLK_ENET_REF>;
+ clock-names = "ipg", "ahb", "ptp", "enet_out";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet>;
+ phy-connection-type = "rmii";
+ phy-handle = <&ethphy>;
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy: ethernet-phy@1 {
+ reg = <1>;
+ clocks = <&osc_eth_phy>;
+ clock-names = "rmii-ref";
+ micrel,led-mode = <1>;
+ reset-assert-us = <500>;
+ reset-deassert-us = <100>;
+ reset-gpios = <&gpio5 2 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&gpio1 {
+ gpio-line-names =
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "key-out", "key-in",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "";
+};
+
+&gpio2 {
+ gpio-line-names =
+ "", "", "", "", "", "", "", "",
+ "lan9500a-rst", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "";
+};
+
+&gpmi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpmi_nand>;
+ status = "okay";
+};
+
+&hdmi {
+ ddc-i2c-bus = <&i2c4>;
+ status = "okay";
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ touchscreen@55 {
+ compatible = "sitronix,st1633";
+ reg = <0x55>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_touch>;
+ interrupts = <18 IRQ_TYPE_EDGE_FALLING>;
+ interrupt-parent = <&gpio5>;
+ gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+ status = "disabled";
+ };
+
+ touchscreen@5d {
+ compatible = "goodix,gt928";
+ reg = <0x5d>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_touch>;
+ interrupts = <18 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-parent = <&gpio5>;
+ irq-gpios = <&gpio5 18 GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
+ status = "disabled";
+ };
+};
+
+&i2c4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c4>;
+ clock-frequency = <100000>;
+ status = "okay";
+};
+
+&ldb {
+ status = "okay";
+
+ lvds: lvds-channel@0 {
+ fsl,data-mapping = "spwg";
+ fsl,data-width = <24>;
+ status = "okay";
+
+ port@4 {
+ reg = <4>;
+
+ lvds_out: endpoint {
+ remote-endpoint = <&panel_in_lvds>;
+ };
+ };
+ };
+};
+
+&pwm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm3>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3>;
+ status = "okay";
+};
+
+&usbh1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbh1>;
+ disable-over-current;
+ status = "okay";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usb1@1 {
+ compatible = "usb4b4,6570";
+ reg = <1>;
+ clocks = <&clks IMX6QDL_CLK_CKO>;
+
+ assigned-clocks = <&clks IMX6QDL_CLK_CKO>,
+ <&clks IMX6QDL_CLK_CKO2_SEL>;
+ assigned-clock-parents = <&clks IMX6QDL_CLK_CKO2>,
+ <&clks IMX6QDL_CLK_OSC>;
+ assigned-clock-rates = <12000000 0>;
+ };
+};
+
+&usbotg {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ dr_mode = "host";
+ over-current-active-low;
+ vbus-supply = <&reg_usb_otg_vbus>;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3>;
+ cd-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
+ vmmc-supply = <&reg_3v3>;
+ voltage-ranges = <3300 3300>;
+ 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>;
+
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX6QDL_PAD_RGMII_RD0__GPIO6_IO25 0x1b0b0 /* PMIC_IRQ */
+ MX6QDL_PAD_SD2_DAT3__GPIO1_IO12 0x1b0b0
+ MX6QDL_PAD_SD2_DAT1__GPIO1_IO14 0x1b0b0
+ MX6QDL_PAD_SD2_DAT0__GPIO1_IO15 0x1b0b0
+ MX6QDL_PAD_SD4_DAT0__GPIO2_IO08 0x1b0b0
+ MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x1b0b0
+ >;
+ };
+
+ pinctrl_backlight: backlightgrp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_CS3__GPIO6_IO16 0x100b1
+ >;
+ };
+
+ pinctrl_ecspi2: ecspi2grp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_DAT10__ECSPI2_MISO 0x100b1
+ MX6QDL_PAD_CSI0_DAT9__ECSPI2_MOSI 0x100b1
+ MX6QDL_PAD_CSI0_DAT8__ECSPI2_SCLK 0x100b1
+ MX6QDL_PAD_CSI0_DAT11__GPIO5_IO29 0x100b1
+ >;
+ };
+
+ pinctrl_enet: enetgrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
+ MX6QDL_PAD_ENET_RXD0__ENET_RX_DATA0 0x1b0b0
+ MX6QDL_PAD_ENET_RXD1__ENET_RX_DATA1 0x1b0b0
+ MX6QDL_PAD_ENET_CRS_DV__ENET_RX_EN 0x1b0b0
+ MX6QDL_PAD_ENET_RX_ER__ENET_RX_ER 0x1b0b0
+ MX6QDL_PAD_ENET_TXD0__ENET_TX_DATA0 0x1b0b0
+ MX6QDL_PAD_ENET_TXD1__ENET_TX_DATA1 0x1b0b0
+ MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x1b0b0
+ MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
+ MX6QDL_PAD_EIM_A25__GPIO5_IO02 0x100b1
+ >;
+ };
+
+ pinctrl_gpio_keys: gpiokeysgrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_A22__GPIO2_IO16 0x1b080
+ MX6QDL_PAD_EIM_D27__GPIO3_IO27 0x1b080
+ MX6QDL_PAD_EIM_A24__GPIO5_IO04 0x1b080
+ >;
+ };
+
+ pinctrl_gpio_leds: gpioledsgrp {
+ fsl,pins = <
+ MX6QDL_PAD_CSI0_VSYNC__GPIO5_IO21 0x1b0b0
+ >;
+ };
+
+ pinctrl_gpmi_nand: gpminandgrp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1
+ MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1
+ MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
+ MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000
+ MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
+ MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1
+ MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1
+ MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1
+ MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1
+ MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1
+ MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1
+ MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1
+ MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1
+ MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1
+ MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1
+ >;
+ };
+
+ pinctrl_hdmi_cec: hdmicecgrp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_A21__GPIO2_IO17 0x1b8b1
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
+ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001f8b1
+ MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001f8b1
+ >;
+ };
+
+ pinctrl_i2c4: i2c4grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_7__I2C4_SCL 0x4001b8b1
+ MX6QDL_PAD_GPIO_8__I2C4_SDA 0x4001b8b1
+ >;
+ };
+
+ pinctrl_pwm3: pwm3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1
+ >;
+ };
+
+ pinctrl_reg_backlight: regbacklightgrp {
+ fsl,pins = <
+ MX6QDL_PAD_ENET_REF_CLK__GPIO1_IO23 0x1b0b1
+ >;
+ };
+
+ pinctrl_reg_usbotg_vbus: regusbotgvbusgrp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x1b0b1
+ >;
+ };
+
+ pinctrl_touch: touchgrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x1b0b0
+ MX6QDL_PAD_CSI0_PIXCLK__GPIO5_IO18 0x1b0b0
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1
+ MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1
+ MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1
+ >;
+ };
+
+ pinctrl_uart3: uart3grp {
+ fsl,pins = <
+ MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b0
+ MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b0
+ >;
+ };
+
+ pinctrl_usbh1: usbh1grp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_3__USB_H1_OC 0x1b0b1
+ MX6QDL_PAD_CSI0_MCLK__CCM_CLKO1 0x1b0b0
+ >;
+ };
+
+ pinctrl_usbotg: usbotggrp {
+ fsl,pins = <
+ MX6QDL_PAD_KEY_COL4__USB_OTG_OC 0x1b0b1
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059
+ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059
+ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059
+ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059
+ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059
+ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059
+ MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x100b1
+ >;
+ };
+
+ pinctrl_wdog: wdoggrp {
+ fsl,pins = <
+ MX6QDL_PAD_GPIO_9__WDOG1_B 0x1b0b0
+ >;
+ };
+};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi b/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi
index 3be38a3c4bb1..c32ea040fecd 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi
@@ -117,17 +117,9 @@
#address-cells = <1>;
#size-cells = <0>;
- phy_port2: phy@1 {
- reg = <1>;
- };
-
- phy_port3: phy@2 {
- reg = <2>;
- };
-
switch@10 {
compatible = "qca,qca8334";
- reg = <10>;
+ reg = <0x10>;
reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>;
switch_ports: ports {
@@ -149,15 +141,30 @@
eth2: port@2 {
reg = <2>;
label = "eth2";
+ phy-mode = "internal";
phy-handle = <&phy_port2>;
};
eth1: port@3 {
reg = <3>;
label = "eth1";
+ phy-mode = "internal";
phy-handle = <&phy_port3>;
};
};
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ phy_port2: ethernet-phy@1 {
+ reg = <1>;
+ };
+
+ phy_port3: ethernet-phy@2 {
+ reg = <2>;
+ };
+ };
};
};
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-apalis-eval-v1.2.dts b/arch/arm/boot/dts/nxp/imx/imx6q-apalis-eval-v1.2.dts
new file mode 100644
index 000000000000..15d4a98ee976
--- /dev/null
+++ b/arch/arm/boot/dts/nxp/imx/imx6q-apalis-eval-v1.2.dts
@@ -0,0 +1,200 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2024 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx6q-apalis-eval.dtsi"
+
+/ {
+ model = "Toradex Apalis iMX6Q/D Module on Apalis Evaluation Board v1.2";
+ compatible = "toradex,apalis_imx6q-eval-v1.2", "toradex,apalis_imx6q",
+ "fsl,imx6q";
+
+ reg_3v3_mmc: regulator-3v3-mmc {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio2 0 GPIO_ACTIVE_HIGH>;
+ off-on-delay-us = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enable_3v3_mmc>;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "3.3V_MMC";
+ startup-delay-us = <10000>;
+ };
+
+ reg_3v3_sd: regulator-3v3-sd {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio2 1 GPIO_ACTIVE_HIGH>;
+ off-on-delay-us = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enable_3v3_sd>;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "3.3V_SD";
+ startup-delay-us = <10000>;
+ };
+
+ reg_can1: regulator-can1 {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio2 3 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enable_can1_power>;
+ regulator-name = "5V_SW_CAN1";
+ startup-delay-us = <10000>;
+ };
+
+ reg_can2: regulator-can2 {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio2 2 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enable_can2_power>;
+ regulator-name = "5V_SW_CAN2";
+ startup-delay-us = <10000>;
+ };
+
+ sound-carrier {
+ 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,name = "apalis-nau8822";
+ simple-audio-card,routing =
+ "Headphones", "LHP",
+ "Headphones", "RHP",
+ "Speaker", "LSPK",
+ "Speaker", "RSPK",
+ "Line Out", "AUXOUT1",
+ "Line Out", "AUXOUT2",
+ "LAUX", "Line In",
+ "RAUX", "Line In",
+ "LMICP", "Mic In",
+ "RMICP", "Mic In";
+ simple-audio-card,widgets =
+ "Headphones", "Headphones",
+ "Line Out", "Line Out",
+ "Speaker", "Speaker",
+ "Microphone", "Mic In",
+ "Line", "Line In";
+
+ codec_dai: simple-audio-card,codec {
+ sound-dai = <&nau8822_1a>;
+ system-clock-frequency = <12288000>;
+ };
+
+ simple-audio-card,cpu {
+ sound-dai = <&ssi2>;
+ };
+ };
+};
+
+&can1 {
+ xceiver-supply = <&reg_can1>;
+ status = "okay";
+};
+
+&can2 {
+ xceiver-supply = <&reg_can2>;
+ status = "okay";
+};
+
+/* I2C1_SDA/SCL on MXM3 209/211 */
+&i2c1 {
+ /* Audio Codec */
+ nau8822_1a: audio-codec@1a {
+ compatible = "nuvoton,nau8822";
+ reg = <0x1a>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_nau8822>;
+ #sound-dai-cells = <0>;
+ };
+
+ /* Current measurement into module VCC */
+ hwmon@40 {
+ compatible = "ti,ina219";
+ reg = <0x40>;
+ shunt-resistor = <5000>;
+ };
+
+ /* Temperature Sensor */
+ temperature-sensor@4f {
+ compatible = "ti,tmp75c";
+ reg = <0x4f>;
+ };
+
+ /* EEPROM */
+ eeprom@57 {
+ compatible = "st,24c02", "atmel,24c02";
+ reg = <0x57>;
+ pagesize = <16>;
+ size = <256>;
+ };
+};
+
+&pcie {
+ status = "okay";
+};
+
+&ssi2 {
+ status = "okay";
+};
+
+/* MMC1 */
+&usdhc1 {
+ bus-width = <4>;
+ pinctrl-0 = <&pinctrl_usdhc1_4bit &pinctrl_mmc_cd>;
+ vmmc-supply = <&reg_3v3_mmc>;
+ status = "okay";
+};
+
+/* SD1 */
+&usdhc2 {
+ cd-gpios = <&gpio6 14 GPIO_ACTIVE_LOW>;
+ pinctrl-0 = <&pinctrl_usdhc2 &pinctrl_sd_cd>;
+ vmmc-supply = <&reg_3v3_sd>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl_enable_3v3_mmc: enable3v3mmcgrp {
+ fsl,pins = <
+ /* MMC1_PWR_CTRL */
+ MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x1b0b0
+ >;
+ };
+
+ pinctrl_enable_3v3_sd: enable3v3sdgrp {
+ fsl,pins = <
+ /* SD1_PWR_CTRL */
+ MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x1b0b0
+ >;
+ };
+
+ pinctrl_enable_can1_power: enablecan1powergrp {
+ fsl,pins = <
+ /* CAN1_PWR_EN */
+ MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x1b0b0
+ >;
+ };
+
+ pinctrl_enable_can2_power: enablecan2powergrp {
+ fsl,pins = <
+ /* CAN2_PWR_EN */
+ MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x1b0b0
+ >;
+ };
+
+ pinctrl_nau8822: nau8822grp {
+ fsl,pins = <
+ MX6QDL_PAD_DISP0_DAT16__AUD5_TXC 0x130b0
+ MX6QDL_PAD_DISP0_DAT17__AUD5_TXD 0x130b0
+ MX6QDL_PAD_DISP0_DAT18__AUD5_TXFS 0x130b0
+ MX6QDL_PAD_DISP0_DAT19__AUD5_RXD 0x130b0
+ >;
+ };
+};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-apalis-eval.dts b/arch/arm/boot/dts/nxp/imx/imx6q-apalis-eval.dts
index 3fc079dfd61e..e1077e2da5f4 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6q-apalis-eval.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6q-apalis-eval.dts
@@ -7,29 +7,13 @@
/dts-v1/;
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/interrupt-controller/irq.h>
-#include "imx6q.dtsi"
-#include "imx6qdl-apalis.dtsi"
+#include "imx6q-apalis-eval.dtsi"
/ {
model = "Toradex Apalis iMX6Q/D Module on Apalis Evaluation Board";
compatible = "toradex,apalis_imx6q-eval", "toradex,apalis_imx6q",
"fsl,imx6q";
- aliases {
- i2c0 = &i2c1;
- i2c1 = &i2c3;
- i2c2 = &i2c2;
- rtc0 = &rtc_i2c;
- rtc1 = &snvs_rtc;
- };
-
- chosen {
- stdout-path = "serial0:115200n8";
- };
-
reg_pcie_switch: regulator-pcie-switch {
compatible = "regulator-fixed";
enable-active-high;
@@ -40,14 +24,6 @@
startup-delay-us = <100000>;
status = "okay";
};
-
- reg_3v3_sw: regulator-3v3-sw {
- compatible = "regulator-fixed";
- regulator-always-on;
- regulator-max-microvolt = <3300000>;
- regulator-min-microvolt = <3300000>;
- regulator-name = "3.3V_SW";
- };
};
&can1 {
@@ -62,102 +38,22 @@
/* I2C1_SDA/SCL on MXM3 209/211 (e.g. RTC on carrier board) */
&i2c1 {
- status = "okay";
-
+ /* PCIe Switch */
pcie-switch@58 {
compatible = "plx,pex8605";
reg = <0x58>;
};
-
- /* M41T0M6 real time clock on carrier board */
- rtc_i2c: rtc@68 {
- compatible = "st,m41t0";
- reg = <0x68>;
- };
-};
-
-/*
- * I2C3_SDA/SCL (CAM) on MXM3 pin 201/203 (e.g. camera sensor on carrier
- * board)
- */
-&i2c3 {
- status = "okay";
};
&pcie {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_reset_moci>;
- /* active-high meaning opposite of regular PERST# active-low polarity */
- reset-gpio = <&gpio1 28 GPIO_ACTIVE_HIGH>;
- reset-gpio-active-high;
vpcie-supply = <&reg_pcie_switch>;
status = "okay";
};
-&pwm1 {
- status = "okay";
-};
-
-&pwm2 {
- status = "okay";
-};
-
-&pwm3 {
- status = "okay";
-};
-
-&pwm4 {
- status = "okay";
-};
-
-&reg_usb_host_vbus {
- status = "okay";
-};
-
-&reg_usb_otg_vbus {
- status = "okay";
-};
-
-&sata {
- status = "okay";
-};
-
&sound_spdif {
status = "okay";
};
-&spdif {
- status = "okay";
-};
-
-&uart1 {
- status = "okay";
-};
-
-&uart2 {
- status = "okay";
-};
-
-&uart4 {
- status = "okay";
-};
-
-&uart5 {
- status = "okay";
-};
-
-&usbh1 {
- disable-over-current;
- vbus-supply = <&reg_usb_host_vbus>;
- status = "okay";
-};
-
-&usbotg {
- disable-over-current;
- vbus-supply = <&reg_usb_otg_vbus>;
- status = "okay";
-};
-
/* MMC1 */
&usdhc1 {
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-apalis-eval.dtsi b/arch/arm/boot/dts/nxp/imx/imx6q-apalis-eval.dtsi
new file mode 100644
index 000000000000..b6c45ad3f430
--- /dev/null
+++ b/arch/arm/boot/dts/nxp/imx/imx6q-apalis-eval.dtsi
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2014-2024 Toradex
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "imx6q.dtsi"
+#include "imx6qdl-apalis.dtsi"
+
+/ {
+ aliases {
+ i2c0 = &i2c1;
+ i2c1 = &i2c3;
+ i2c2 = &i2c2;
+ rtc0 = &rtc_i2c;
+ rtc1 = &snvs_rtc;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ reg_3v3_sw: regulator-3v3-sw {
+ compatible = "regulator-fixed";
+ regulator-always-on;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "3.3V_SW";
+ };
+};
+
+&i2c1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ /* M41T0M6 real time clock on carrier board */
+ rtc_i2c: rtc@68 {
+ compatible = "st,m41t0";
+ reg = <0x68>;
+ };
+};
+
+/*
+ * I2C3_SDA/SCL (CAM) on MXM3 pin 201/203 (e.g. camera sensor on carrier
+ * board)
+ */
+&i2c3 {
+ status = "okay";
+};
+
+&pcie {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reset_moci>;
+ /* active-high meaning opposite of regular PERST# active-low polarity */
+ reset-gpio = <&gpio1 28 GPIO_ACTIVE_HIGH>;
+ reset-gpio-active-high;
+};
+
+&pwm1 {
+ status = "okay";
+};
+
+&pwm2 {
+ status = "okay";
+};
+
+&pwm3 {
+ status = "okay";
+};
+
+&pwm4 {
+ status = "okay";
+};
+
+&reg_usb_host_vbus {
+ status = "okay";
+};
+
+&reg_usb_otg_vbus {
+ status = "okay";
+};
+
+&sata {
+ status = "okay";
+};
+
+&spdif {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&uart4 {
+ status = "okay";
+};
+
+&uart5 {
+ status = "okay";
+};
+
+&usbh1 {
+ disable-over-current;
+ vbus-supply = <&reg_usb_host_vbus>;
+ status = "okay";
+};
+
+&usbotg {
+ disable-over-current;
+ vbus-supply = <&reg_usb_otg_vbus>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-hummingboard.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-hummingboard.dtsi
index bfade7149080..a955c77cd499 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-hummingboard.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-hummingboard.dtsi
@@ -41,6 +41,11 @@
#include <dt-bindings/sound/fsl-imx-audmux.h>
/ {
+ aliases {
+ rtc0 = &carrier_rtc;
+ rtc1 = &snvs_rtc;
+ };
+
/* Will be filled by the bootloader */
memory@10000000 {
device_type = "memory";
@@ -187,7 +192,7 @@
status = "okay";
/* Pro baseboard model */
- rtc@68 {
+ carrier_rtc: rtc@68 {
compatible = "nxp,pcf8523";
reg = <0x68>;
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-hummingboard2.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-hummingboard2.dtsi
index 0883ef99cded..e6017f9bf640 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-hummingboard2.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-hummingboard2.dtsi
@@ -41,6 +41,11 @@
#include <dt-bindings/sound/fsl-imx-audmux.h>
/ {
+ aliases {
+ rtc0 = &pcf8523;
+ rtc1 = &snvs_rtc;
+ };
+
/* Will be filled by the bootloader */
memory@10000000 {
device_type = "memory";
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 2731faede1cb..d59d5d0e1d19 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-skov-cpu.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-skov-cpu.dtsi
@@ -13,10 +13,14 @@
aliases {
can0 = &can1;
can1 = &can2;
+ ethernet0 = &fec;
+ ethernet1 = &lan1;
+ ethernet2 = &lan2;
mdio-gpio0 = &mdio;
nand = &gpmi;
rtc0 = &i2c_rtc;
rtc1 = &snvs;
+ switch0 = &switch;
usb0 = &usbh1;
usb1 = &usbotg;
};
@@ -60,7 +64,7 @@
gpios = <&gpio1 31 GPIO_ACTIVE_HIGH>,
<&gpio1 22 GPIO_ACTIVE_HIGH>;
- switch@0 {
+ switch: switch@0 {
compatible = "microchip,ksz8873";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_switch>;
@@ -73,13 +77,13 @@
#address-cells = <1>;
#size-cells = <0>;
- ports@0 {
+ lan1: ports@0 {
reg = <0>;
phy-mode = "internal";
label = "lan1";
};
- ports@1 {
+ lan2: ports@1 {
reg = <1>;
phy-mode = "internal";
label = "lan2";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
index 81142c523fa8..8431b8a994f4 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
@@ -1158,7 +1158,7 @@
status = "disabled";
};
- weim: weim@21b8000 {
+ weim: memory-controller@21b8000 {
#address-cells = <2>;
#size-cells = <1>;
compatible = "fsl,imx6q-weim";
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 815119c12bd4..5636fb3661e8 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6sl-tolino-shine2hd.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6sl-tolino-shine2hd.dts
@@ -141,8 +141,10 @@
interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
vdd-supply = <&ldo1_reg>;
reset-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>;
- x-size = <1072>;
- y-size = <1448>;
+ touchscreen-size-x = <1072>;
+ touchscreen-size-y = <1448>;
+ touchscreen-swapped-x-y;
+ touchscreen-inverted-x;
};
/* TODO: TPS65185 PMIC for E Ink at 0x68 */
diff --git a/arch/arm/boot/dts/nxp/imx/imx6sl.dtsi b/arch/arm/boot/dts/nxp/imx/imx6sl.dtsi
index 28111efb19a6..6aa61235e39e 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6sl.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6sl.dtsi
@@ -949,7 +949,7 @@
clocks = <&clks IMX6SL_CLK_DUMMY>;
};
- weim: weim@21b8000 {
+ weim: memory-controller@21b8000 {
#address-cells = <2>;
#size-cells = <1>;
reg = <0x021b8000 0x4000>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6sx.dtsi b/arch/arm/boot/dts/nxp/imx/imx6sx.dtsi
index df3a375f0a3e..0de359d62a47 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6sx.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6sx.dtsi
@@ -1107,7 +1107,7 @@
status = "disabled";
};
- weim: weim@21b8000 {
+ weim: memory-controller@21b8000 {
#address-cells = <2>;
#size-cells = <1>;
compatible = "fsl,imx6sx-weim", "fsl,imx6q-weim";
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 2ac40d69425b..f10f0525490b 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi
@@ -321,7 +321,7 @@
&tsc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_tsc>;
- xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
+ xnur-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
measure-delay-time = <0xffff>;
pre-charge-time = <0xfff>;
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 875ae699c5cb..2ca18f3dad0a 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts
@@ -203,7 +203,7 @@
&tsc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_tsc>;
- xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
+ xnur-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
};
&sai2 {
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 18cac19aa9b0..af337f18a266 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6uldev.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6uldev.dtsi
@@ -156,7 +156,7 @@
&tsc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_tsc>;
- xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
+ xnur-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
measure-delay-time = <0xffff>;
pre-charge-time = <0xffff>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
index a27a7554c2e7..235aa676618b 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul.dtsi
@@ -370,7 +370,7 @@
};
};
- tsc: tsc@2040000 {
+ tsc: touchscreen@2040000 {
compatible = "fsl,imx6ul-tsc";
reg = <0x02040000 0x4000>, <0x0219c000 0x4000>;
interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
@@ -538,6 +538,8 @@
fsl,num-rx-queues = <1>;
fsl,stop-mode = <&gpr 0x10 4>;
fsl,magic-packet;
+ nvmem-cells = <&fec2_mac_addr>;
+ nvmem-cell-names = "mac-address";
status = "disabled";
};
@@ -638,6 +640,7 @@
nvmem-cells = <&tempmon_calib>, <&tempmon_temp_grade>;
nvmem-cell-names = "calib", "temp_grade";
clocks = <&clks IMX6UL_CLK_PLL3_USB_OTG>;
+ #thermal-sensor-cells = <0>;
};
};
@@ -855,7 +858,6 @@
clocks = <&clks IMX6UL_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>;
@@ -897,6 +899,8 @@
fsl,num-rx-queues = <1>;
fsl,stop-mode = <&gpr 0x10 3>;
fsl,magic-packet;
+ nvmem-cells = <&fec1_mac_addr>;
+ nvmem-cell-names = "mac-address";
status = "disabled";
};
@@ -975,7 +979,7 @@
clocks = <&clks IMX6UL_CLK_MMDC_P0_IPG>;
};
- weim: weim@21b8000 {
+ weim: memory-controller@21b8000 {
#address-cells = <2>;
#size-cells = <1>;
compatible = "fsl,imx6ul-weim", "fsl,imx6q-weim";
@@ -1004,6 +1008,14 @@
cpu_speed_grade: speed-grade@10 {
reg = <0x10 4>;
};
+
+ fec1_mac_addr: mac-addr@88 {
+ reg = <0x88 6>;
+ };
+
+ fec2_mac_addr: mac-addr@8e {
+ reg = <0x8e 6>;
+ };
};
csi: csi@21c4000 {
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-dhcom-som-cfg-sdcard.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ull-dhcom-som-cfg-sdcard.dtsi
index 040421f9c970..5e39f8dc1351 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ull-dhcom-som-cfg-sdcard.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-dhcom-som-cfg-sdcard.dtsi
@@ -14,10 +14,12 @@
*/
/*
- * To use usdhc1 as SD card, the WiFi node must be deleted.
+ * To use usdhc1 as SD card, the WiFi node must be deleted. The associated
+ * pwrseq node is also deleted in order to ensure that GPIO H is released.
* BT is also not available, so remove BT from the UART node.
*/
/delete-node/ &brcmf;
+/delete-node/ &usdhc1_pwrseq;
/delete-node/ &bluetooth;
/ {
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-dhcom-som.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ull-dhcom-som.dtsi
index 830b5a5064f2..a74f5273f9b3 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ull-dhcom-som.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-dhcom-som.dtsi
@@ -52,7 +52,7 @@
};
/* SoM with WiFi/BT: WiFi pin WL_REG_ON is connected to a DHCOM GPIO */
- /omit-if-no-ref/ usdhc1_pwrseq: usdhc1-pwrseq {
+ usdhc1_pwrseq: usdhc1-pwrseq {
compatible = "mmc-pwrseq-simple";
reset-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>; /* GPIO H */
};
@@ -273,7 +273,7 @@
pinctrl-names = "default";
pre-charge-time = <0xfff>;
touchscreen-average-samples = <32>;
- xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
+ xnur-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
};
/* DHCOM UART1 */
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-dhcor-som.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ull-dhcor-som.dtsi
index 45315adfaa86..75486e1b0c15 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ull-dhcor-som.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull-dhcor-som.dtsi
@@ -28,10 +28,14 @@
/*
* Due to the design as a solderable SOM, there are no capacitors
* below the SoC, therefore higher voltages are required.
+ * Due to CPU lifetime consideration of the SoC manufacturer and
+ * the preferred area of operation in the industrial related
+ * environment, set the maximum frequency for each DHCOM i.MX6ULL
+ * to 792MHz, as with the industrial type.
*/
+ clock-frequency = <792000000>;
operating-points = <
/* kHz uV */
- 900000 1275000
792000 1250000 /* Voltage increased */
528000 1175000
396000 1025000
@@ -39,7 +43,6 @@
>;
fsl,soc-operating-points = <
/* KHz uV */
- 900000 1250000
792000 1250000 /* Voltage increased */
528000 1175000
396000 1175000
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ull.dtsi
index 2bccd45e9fc2..8a1776067ecc 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ull.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ull.dtsi
@@ -75,7 +75,7 @@
clocks = <&clks IMX6UL_CLK_DUMMY>;
};
- iomuxc_snvs: iomuxc-snvs@2290000 {
+ iomuxc_snvs: pinctrl@2290000 {
compatible = "fsl,imx6ull-iomuxc-snvs";
reg = <0x02290000 0x4000>;
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx7-mba7.dtsi b/arch/arm/boot/dts/nxp/imx/imx7-mba7.dtsi
index 3df6dff7734a..1235a71c6abe 100644
--- a/arch/arm/boot/dts/nxp/imx/imx7-mba7.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx7-mba7.dtsi
@@ -18,6 +18,8 @@
mmc0 = &usdhc3;
mmc1 = &usdhc1;
/delete-property/ mmc2;
+ rtc0 = &ds1339;
+ rtc1 = &snvs_rtc;
};
beeper {
@@ -32,11 +34,18 @@
gpio_buttons: gpio-keys {
compatible = "gpio-keys";
+ /*
+ * NOTE: These buttons are attached to a GPIO-expander.
+ * Enabling wakeup-source, enables wakeup on all inputs.
+ * If PE_GPIO[3..6] are used as inputs, they cause a
+ * wakeup as well.
+ */
button-0 {
/* #SWITCH_A */
label = "S11";
linux,code = <KEY_1>;
gpios = <&pca9555 13 GPIO_ACTIVE_LOW>;
+ wakeup-source;
};
button-1 {
@@ -44,6 +53,7 @@
label = "S12";
linux,code = <KEY_2>;
gpios = <&pca9555 14 GPIO_ACTIVE_LOW>;
+ wakeup-source;
};
button-2 {
@@ -51,6 +61,7 @@
label = "S13";
linux,code = <KEY_3>;
gpios = <&pca9555 15 GPIO_ACTIVE_LOW>;
+ wakeup-source;
};
};
@@ -171,6 +182,14 @@
regulator-always-on;
};
+ reg_vcc_3v3: regulator-vcc-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
sound {
compatible = "fsl,imx-audio-tlv320aic32x4";
model = "imx-audio-tlv320aic32x4";
@@ -198,9 +217,9 @@
&ecspi1 {
pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_ecspi1>;
+ pinctrl-0 = <&pinctrl_ecspi1>, <&pinctrl_ecspi1_ss0>;
cs-gpios = <&gpio4 0 GPIO_ACTIVE_LOW>, <&gpio4 1 GPIO_ACTIVE_LOW>,
- <&gpio4 2 GPIO_ACTIVE_LOW>;
+ <&gpio4 2 GPIO_ACTIVE_LOW>, <&gpio4 19 GPIO_ACTIVE_LOW>;
status = "okay";
};
@@ -214,8 +233,6 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet1>;
phy-mode = "rgmii-id";
- phy-reset-gpios = <&gpio7 15 GPIO_ACTIVE_LOW>;
- phy-reset-duration = <1>;
phy-supply = <&reg_fec1_pwdn>;
phy-handle = <&ethphy1_0>;
fsl,magic-packet;
@@ -228,10 +245,15 @@
ethphy1_0: ethernet-phy@0 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet1_phy>;
ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_50_NS>;
ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_50_NS>;
ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
ti,clk-output-sel = <DP83867_CLK_O_SEL_OFF>;
+ reset-gpios = <&gpio7 15 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <1000>;
+ reset-deassert-us = <500>;
};
};
};
@@ -290,13 +312,17 @@
lm75: temperature-sensor@49 {
compatible = "national,lm75";
reg = <0x49>;
+ vs-supply = <&reg_vcc_3v3>;
};
};
&i2c2 {
clock-frequency = <100000>;
- pinctrl-names = "default";
+ pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_i2c2>;
+ pinctrl-1 = <&pinctrl_i2c2_recovery>;
+ scl-gpios = <&gpio4 10 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio4 11 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
status = "okay";
tlv320aic32x4: audio-codec@18 {
@@ -319,13 +345,17 @@
interrupts = <12 IRQ_TYPE_EDGE_FALLING>;
interrupt-controller;
#interrupt-cells = <2>;
+ vcc-supply = <&reg_vcc_3v3>;
};
};
&i2c3 {
clock-frequency = <100000>;
- pinctrl-names = "default";
+ pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_i2c3>;
+ pinctrl-1 = <&pinctrl_i2c3_recovery>;
+ scl-gpios = <&gpio4 12 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio4 13 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
status = "okay";
};
@@ -334,213 +364,213 @@
pinctrl-0 = <&pinctrl_hog_mba7_1>;
pinctrl_ecspi1: ecspi1grp {
+ fsl,pins =
+ <MX7D_PAD_ECSPI1_MISO__ECSPI1_MISO 0x7c>,
+ <MX7D_PAD_ECSPI1_MOSI__ECSPI1_MOSI 0x74>,
+ <MX7D_PAD_ECSPI1_SCLK__ECSPI1_SCLK 0x74>,
+ <MX7D_PAD_UART1_RX_DATA__GPIO4_IO0 0x74>,
+ <MX7D_PAD_UART1_TX_DATA__GPIO4_IO1 0x74>,
+ <MX7D_PAD_UART2_RX_DATA__GPIO4_IO2 0x74>;
+ };
+
+ pinctrl_ecspi1_ss0: ecspi1ss0grp {
fsl,pins = <
- MX7D_PAD_ECSPI1_MISO__ECSPI1_MISO 0x7c
- MX7D_PAD_ECSPI1_MOSI__ECSPI1_MOSI 0x74
- MX7D_PAD_ECSPI1_SCLK__ECSPI1_SCLK 0x74
- MX7D_PAD_UART1_RX_DATA__GPIO4_IO0 0x74
- MX7D_PAD_UART1_TX_DATA__GPIO4_IO1 0x74
- MX7D_PAD_UART2_RX_DATA__GPIO4_IO2 0x74
+ MX7D_PAD_ECSPI1_SS0__GPIO4_IO19 0x74
>;
};
pinctrl_ecspi2: ecspi2grp {
- fsl,pins = <
- MX7D_PAD_ECSPI2_MISO__ECSPI2_MISO 0x7c
- MX7D_PAD_ECSPI2_MOSI__ECSPI2_MOSI 0x74
- MX7D_PAD_ECSPI2_SCLK__ECSPI2_SCLK 0x74
- MX7D_PAD_ECSPI2_SS0__ECSPI2_SS0 0x74
- >;
+ fsl,pins =
+ <MX7D_PAD_ECSPI2_MISO__ECSPI2_MISO 0x7c>,
+ <MX7D_PAD_ECSPI2_MOSI__ECSPI2_MOSI 0x74>,
+ <MX7D_PAD_ECSPI2_SCLK__ECSPI2_SCLK 0x74>,
+ <MX7D_PAD_ECSPI2_SS0__ECSPI2_SS0 0x74>;
};
pinctrl_enet1: enet1grp {
- fsl,pins = <
- MX7D_PAD_GPIO1_IO10__ENET1_MDIO 0x02
- MX7D_PAD_GPIO1_IO11__ENET1_MDC 0x00
- MX7D_PAD_ENET1_RGMII_TXC__ENET1_RGMII_TXC 0x71
- MX7D_PAD_ENET1_RGMII_TD0__ENET1_RGMII_TD0 0x71
- MX7D_PAD_ENET1_RGMII_TD1__ENET1_RGMII_TD1 0x71
- MX7D_PAD_ENET1_RGMII_TD2__ENET1_RGMII_TD2 0x71
- MX7D_PAD_ENET1_RGMII_TD3__ENET1_RGMII_TD3 0x71
- MX7D_PAD_ENET1_RGMII_TX_CTL__ENET1_RGMII_TX_CTL 0x71
- MX7D_PAD_ENET1_RGMII_RXC__ENET1_RGMII_RXC 0x79
- MX7D_PAD_ENET1_RGMII_RD0__ENET1_RGMII_RD0 0x79
- MX7D_PAD_ENET1_RGMII_RD1__ENET1_RGMII_RD1 0x79
- MX7D_PAD_ENET1_RGMII_RD2__ENET1_RGMII_RD2 0x79
- MX7D_PAD_ENET1_RGMII_RD3__ENET1_RGMII_RD3 0x79
- MX7D_PAD_ENET1_RGMII_RX_CTL__ENET1_RGMII_RX_CTL 0x79
+ fsl,pins =
+ <MX7D_PAD_GPIO1_IO10__ENET1_MDIO 0x02>,
+ <MX7D_PAD_GPIO1_IO11__ENET1_MDC 0x00>,
+ <MX7D_PAD_ENET1_RGMII_TXC__ENET1_RGMII_TXC 0x71>,
+ <MX7D_PAD_ENET1_RGMII_TD0__ENET1_RGMII_TD0 0x71>,
+ <MX7D_PAD_ENET1_RGMII_TD1__ENET1_RGMII_TD1 0x71>,
+ <MX7D_PAD_ENET1_RGMII_TD2__ENET1_RGMII_TD2 0x71>,
+ <MX7D_PAD_ENET1_RGMII_TD3__ENET1_RGMII_TD3 0x71>,
+ <MX7D_PAD_ENET1_RGMII_TX_CTL__ENET1_RGMII_TX_CTL 0x71>,
+ <MX7D_PAD_ENET1_RGMII_RXC__ENET1_RGMII_RXC 0x79>,
+ <MX7D_PAD_ENET1_RGMII_RD0__ENET1_RGMII_RD0 0x79>,
+ <MX7D_PAD_ENET1_RGMII_RD1__ENET1_RGMII_RD1 0x79>,
+ <MX7D_PAD_ENET1_RGMII_RD2__ENET1_RGMII_RD2 0x79>,
+ <MX7D_PAD_ENET1_RGMII_RD3__ENET1_RGMII_RD3 0x79>,
+ <MX7D_PAD_ENET1_RGMII_RX_CTL__ENET1_RGMII_RX_CTL 0x79>;
+ };
+
+ pinctrl_enet1_phy: enet1phygrp {
+ fsl,pins =
/* Reset: SION, 100kPU, SRE_FAST, DSE_X1 */
- MX7D_PAD_ENET1_COL__GPIO7_IO15 0x40000070
+ <MX7D_PAD_ENET1_COL__GPIO7_IO15 0x40000070>,
/* INT/PWDN: SION, 100kPU, HYS, SRE_FAST, DSE_X1 */
- MX7D_PAD_GPIO1_IO09__GPIO1_IO9 0x40000078
- >;
+ <MX7D_PAD_GPIO1_IO09__GPIO1_IO9 0x40000078>;
};
pinctrl_flexcan1: flexcan1grp {
- fsl,pins = <
- MX7D_PAD_GPIO1_IO12__FLEXCAN1_RX 0x5a
- MX7D_PAD_GPIO1_IO13__FLEXCAN1_TX 0x52
- >;
+ fsl,pins =
+ <MX7D_PAD_GPIO1_IO12__FLEXCAN1_RX 0x5a>,
+ <MX7D_PAD_GPIO1_IO13__FLEXCAN1_TX 0x52>;
};
pinctrl_flexcan2: flexcan2grp {
- fsl,pins = <
- MX7D_PAD_GPIO1_IO14__FLEXCAN2_RX 0x5a
- MX7D_PAD_GPIO1_IO15__FLEXCAN2_TX 0x52
- >;
+ fsl,pins =
+ <MX7D_PAD_GPIO1_IO14__FLEXCAN2_RX 0x5a>,
+ <MX7D_PAD_GPIO1_IO15__FLEXCAN2_TX 0x52>;
};
pinctrl_hog_mba7_1: hogmba71grp {
- fsl,pins = <
+ fsl,pins =
/* Limitation: WDOG2_B / WDOG2_RESET not usable */
- MX7D_PAD_ENET1_RX_CLK__GPIO7_IO13 0x4000007c
- MX7D_PAD_ENET1_CRS__GPIO7_IO14 0x40000074
+ <MX7D_PAD_ENET1_RX_CLK__GPIO7_IO13 0x4000007c>,
+ <MX7D_PAD_ENET1_CRS__GPIO7_IO14 0x40000074>,
/* #BOOT_EN */
- MX7D_PAD_UART2_TX_DATA__GPIO4_IO3 0x40000010
- >;
+ <MX7D_PAD_UART2_TX_DATA__GPIO4_IO3 0x40000010>;
};
pinctrl_i2c2: i2c2grp {
- fsl,pins = <
- MX7D_PAD_I2C2_SCL__I2C2_SCL 0x40000078
- MX7D_PAD_I2C2_SDA__I2C2_SDA 0x40000078
- >;
+ fsl,pins =
+ <MX7D_PAD_I2C2_SCL__I2C2_SCL 0x40000078>,
+ <MX7D_PAD_I2C2_SDA__I2C2_SDA 0x40000078>;
+ };
+
+ pinctrl_i2c2_recovery: i2c2recoverygrp {
+ fsl,pins =
+ <MX7D_PAD_I2C2_SCL__GPIO4_IO10 0x40000078>,
+ <MX7D_PAD_I2C2_SDA__GPIO4_IO11 0x40000078>;
};
pinctrl_i2c3: i2c3grp {
- fsl,pins = <
- MX7D_PAD_I2C3_SCL__I2C3_SCL 0x40000078
- MX7D_PAD_I2C3_SDA__I2C3_SDA 0x40000078
- >;
+ fsl,pins =
+ <MX7D_PAD_I2C3_SCL__I2C3_SCL 0x40000078>,
+ <MX7D_PAD_I2C3_SDA__I2C3_SDA 0x40000078>;
+ };
+
+ pinctrl_i2c3_recovery: i2c3recoverygrp {
+ fsl,pins =
+ <MX7D_PAD_I2C3_SCL__GPIO4_IO12 0x40000078>,
+ <MX7D_PAD_I2C3_SDA__GPIO4_IO13 0x40000078>;
};
pinctrl_pca9555: pca95550grp {
- fsl,pins = <
- MX7D_PAD_ENET1_TX_CLK__GPIO7_IO12 0x78
- >;
+ fsl,pins =
+ <MX7D_PAD_ENET1_TX_CLK__GPIO7_IO12 0x78>;
};
pinctrl_sai1: sai1grp {
- fsl,pins = <
- MX7D_PAD_SAI1_MCLK__SAI1_MCLK 0x11
- MX7D_PAD_SAI1_RX_BCLK__SAI1_RX_BCLK 0x1c
- MX7D_PAD_SAI1_RX_DATA__SAI1_RX_DATA0 0x1c
- MX7D_PAD_SAI1_RX_SYNC__SAI2_RX_SYNC 0x1c
-
- MX7D_PAD_SAI1_TX_BCLK__SAI1_TX_BCLK 0x1c
- MX7D_PAD_SAI1_TX_DATA__SAI1_TX_DATA0 0x14
- MX7D_PAD_SAI1_TX_SYNC__SAI1_TX_SYNC 0x14
- >;
+ fsl,pins =
+ <MX7D_PAD_SAI1_MCLK__SAI1_MCLK 0x11>,
+ <MX7D_PAD_SAI1_RX_BCLK__SAI1_RX_BCLK 0x1c>,
+ <MX7D_PAD_SAI1_RX_DATA__SAI1_RX_DATA0 0x1c>,
+ <MX7D_PAD_SAI1_RX_SYNC__SAI2_RX_SYNC 0x1c>,
+
+ <MX7D_PAD_SAI1_TX_BCLK__SAI1_TX_BCLK 0x1c>,
+ <MX7D_PAD_SAI1_TX_DATA__SAI1_TX_DATA0 0x14>,
+ <MX7D_PAD_SAI1_TX_SYNC__SAI1_TX_SYNC 0x14>;
};
pinctrl_uart3: uart3grp {
- fsl,pins = <
- MX7D_PAD_UART3_RX_DATA__UART3_DCE_RX 0x7e
- MX7D_PAD_UART3_TX_DATA__UART3_DCE_TX 0x76
- MX7D_PAD_UART3_CTS_B__UART3_DCE_CTS 0x76
- MX7D_PAD_UART3_RTS_B__UART3_DCE_RTS 0x7e
- >;
+ fsl,pins =
+ <MX7D_PAD_UART3_RX_DATA__UART3_DCE_RX 0x7e>,
+ <MX7D_PAD_UART3_TX_DATA__UART3_DCE_TX 0x76>,
+ <MX7D_PAD_UART3_CTS_B__UART3_DCE_CTS 0x76>,
+ <MX7D_PAD_UART3_RTS_B__UART3_DCE_RTS 0x7e>;
};
pinctrl_uart4: uart4grp {
- fsl,pins = <
- MX7D_PAD_SAI2_TX_SYNC__UART4_DCE_RX 0x7e
- MX7D_PAD_SAI2_TX_BCLK__UART4_DCE_TX 0x76
- MX7D_PAD_SAI2_RX_DATA__UART4_DCE_CTS 0x76
- MX7D_PAD_SAI2_TX_DATA__UART4_DCE_RTS 0x7e
- >;
+ fsl,pins =
+ <MX7D_PAD_SAI2_TX_SYNC__UART4_DCE_RX 0x7e>,
+ <MX7D_PAD_SAI2_TX_BCLK__UART4_DCE_TX 0x76>,
+ <MX7D_PAD_SAI2_RX_DATA__UART4_DCE_CTS 0x76>,
+ <MX7D_PAD_SAI2_TX_DATA__UART4_DCE_RTS 0x7e>;
};
pinctrl_uart5: uart5grp {
- fsl,pins = <
- MX7D_PAD_I2C4_SCL__UART5_DCE_RX 0x7e
- MX7D_PAD_I2C4_SDA__UART5_DCE_TX 0x76
- >;
+ fsl,pins =
+ <MX7D_PAD_I2C4_SCL__UART5_DCE_RX 0x7e>,
+ <MX7D_PAD_I2C4_SDA__UART5_DCE_TX 0x76>;
};
pinctrl_uart6: uart6grp {
- fsl,pins = <
- MX7D_PAD_EPDC_DATA08__UART6_DCE_RX 0x7d
- MX7D_PAD_EPDC_DATA09__UART6_DCE_TX 0x75
- MX7D_PAD_EPDC_DATA11__UART6_DCE_CTS 0x75
- MX7D_PAD_EPDC_DATA10__UART6_DCE_RTS 0x7d
- >;
+ fsl,pins =
+ <MX7D_PAD_EPDC_DATA08__UART6_DCE_RX 0x7d>,
+ <MX7D_PAD_EPDC_DATA09__UART6_DCE_TX 0x75>,
+ <MX7D_PAD_EPDC_DATA11__UART6_DCE_CTS 0x75>,
+ <MX7D_PAD_EPDC_DATA10__UART6_DCE_RTS 0x7d>;
};
pinctrl_uart7: uart7grp {
- fsl,pins = <
- MX7D_PAD_EPDC_DATA12__UART7_DCE_RX 0x7e
- MX7D_PAD_EPDC_DATA13__UART7_DCE_TX 0x76
- MX7D_PAD_EPDC_DATA15__UART7_DCE_CTS 0x76
+ fsl,pins =
+ <MX7D_PAD_EPDC_DATA12__UART7_DCE_RX 0x7e>,
+ <MX7D_PAD_EPDC_DATA13__UART7_DCE_TX 0x76>,
+ <MX7D_PAD_EPDC_DATA15__UART7_DCE_CTS 0x76>,
/* Limitation: RTS is not connected */
- MX7D_PAD_EPDC_DATA14__UART7_DCE_RTS 0x7e
- >;
+ <MX7D_PAD_EPDC_DATA14__UART7_DCE_RTS 0x7e>;
};
- pinctrl_usdhc1_gpio: usdhc1grp_gpio {
- fsl,pins = <
+ pinctrl_usdhc1_gpio: usdhc1_gpiogrp {
+ fsl,pins =
/* WP */
- MX7D_PAD_SD1_WP__GPIO5_IO1 0x7c
+ <MX7D_PAD_SD1_WP__GPIO5_IO1 0x7c>,
/* CD */
- MX7D_PAD_SD1_CD_B__GPIO5_IO0 0x7c
+ <MX7D_PAD_SD1_CD_B__GPIO5_IO0 0x7c>,
/* VSELECT */
- MX7D_PAD_GPIO1_IO08__SD1_VSELECT 0x59
- >;
+ <MX7D_PAD_GPIO1_IO08__SD1_VSELECT 0x59>;
};
pinctrl_usdhc1: usdhc1grp {
- fsl,pins = <
- MX7D_PAD_SD1_CMD__SD1_CMD 0x5e
- MX7D_PAD_SD1_CLK__SD1_CLK 0x57
- MX7D_PAD_SD1_DATA0__SD1_DATA0 0x5e
- MX7D_PAD_SD1_DATA1__SD1_DATA1 0x5e
- MX7D_PAD_SD1_DATA2__SD1_DATA2 0x5e
- MX7D_PAD_SD1_DATA3__SD1_DATA3 0x5e
- >;
- };
-
- pinctrl_usdhc1_100mhz: usdhc1grp_100mhz {
- fsl,pins = <
- MX7D_PAD_SD1_CMD__SD1_CMD 0x5a
- MX7D_PAD_SD1_CLK__SD1_CLK 0x57
- MX7D_PAD_SD1_DATA0__SD1_DATA0 0x5a
- MX7D_PAD_SD1_DATA1__SD1_DATA1 0x5a
- MX7D_PAD_SD1_DATA2__SD1_DATA2 0x5a
- MX7D_PAD_SD1_DATA3__SD1_DATA3 0x5a
- >;
- };
-
- pinctrl_usdhc1_200mhz: usdhc1grp_200mhz {
- fsl,pins = <
- MX7D_PAD_SD1_CMD__SD1_CMD 0x5b
- MX7D_PAD_SD1_CLK__SD1_CLK 0x57
- MX7D_PAD_SD1_DATA0__SD1_DATA0 0x5b
- MX7D_PAD_SD1_DATA1__SD1_DATA1 0x5b
- MX7D_PAD_SD1_DATA2__SD1_DATA2 0x5b
- MX7D_PAD_SD1_DATA3__SD1_DATA3 0x5b
- >;
+ fsl,pins =
+ <MX7D_PAD_SD1_CMD__SD1_CMD 0x5e>,
+ <MX7D_PAD_SD1_CLK__SD1_CLK 0x57>,
+ <MX7D_PAD_SD1_DATA0__SD1_DATA0 0x5e>,
+ <MX7D_PAD_SD1_DATA1__SD1_DATA1 0x5e>,
+ <MX7D_PAD_SD1_DATA2__SD1_DATA2 0x5e>,
+ <MX7D_PAD_SD1_DATA3__SD1_DATA3 0x5e>;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1_100mhzgrp {
+ fsl,pins =
+ <MX7D_PAD_SD1_CMD__SD1_CMD 0x5a>,
+ <MX7D_PAD_SD1_CLK__SD1_CLK 0x57>,
+ <MX7D_PAD_SD1_DATA0__SD1_DATA0 0x5a>,
+ <MX7D_PAD_SD1_DATA1__SD1_DATA1 0x5a>,
+ <MX7D_PAD_SD1_DATA2__SD1_DATA2 0x5a>,
+ <MX7D_PAD_SD1_DATA3__SD1_DATA3 0x5a>;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1_200mhzgrp {
+ fsl,pins =
+ <MX7D_PAD_SD1_CMD__SD1_CMD 0x5b>,
+ <MX7D_PAD_SD1_CLK__SD1_CLK 0x57>,
+ <MX7D_PAD_SD1_DATA0__SD1_DATA0 0x5b>,
+ <MX7D_PAD_SD1_DATA1__SD1_DATA1 0x5b>,
+ <MX7D_PAD_SD1_DATA2__SD1_DATA2 0x5b>,
+ <MX7D_PAD_SD1_DATA3__SD1_DATA3 0x5b>;
};
};
&iomuxc_lpsr {
pinctrl_pwm1: pwm1grp {
- fsl,pins = <
+ fsl,pins =
/* LCD_CONTRAST */
- MX7D_PAD_LPSR_GPIO1_IO01__PWM1_OUT 0x50
- >;
+ <MX7D_PAD_LPSR_GPIO1_IO01__PWM1_OUT 0x50>;
};
pinctrl_usbotg1: usbotg1grp {
- fsl,pins = <
- MX7D_PAD_LPSR_GPIO1_IO04__USB_OTG1_OC 0x5c
- MX7D_PAD_LPSR_GPIO1_IO05__GPIO1_IO5 0x59
- >;
+ fsl,pins =
+ <MX7D_PAD_LPSR_GPIO1_IO04__USB_OTG1_OC 0x5c>,
+ <MX7D_PAD_LPSR_GPIO1_IO05__GPIO1_IO5 0x59>;
};
pinctrl_wdog1: wdog1grp {
- fsl,pins = <
- MX7D_PAD_LPSR_GPIO1_IO00__WDOG1_WDOG_B 0x30
- >;
+ fsl,pins =
+ <MX7D_PAD_LPSR_GPIO1_IO00__WDOG1_WDOG_B 0x30>;
};
};
@@ -560,6 +590,10 @@
status = "okay";
};
+&snvs_pwrkey {
+ status = "okay";
+};
+
&uart3 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart3>;
@@ -605,6 +639,7 @@
};
&usbh {
+ disable-over-current;
status = "okay";
};
@@ -630,6 +665,8 @@
vmmc-supply = <&reg_sd1_vmmc>;
bus-width = <4>;
no-1-8-v;
+ no-sdio;
+ no-emmc;
status = "okay";
};
diff --git a/arch/arm/boot/dts/nxp/imx/imx7-tqma7.dtsi b/arch/arm/boot/dts/nxp/imx/imx7-tqma7.dtsi
index 3fc3130f9def..028961eb7108 100644
--- a/arch/arm/boot/dts/nxp/imx/imx7-tqma7.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx7-tqma7.dtsi
@@ -30,8 +30,11 @@
};
&i2c1 {
- pinctrl-names = "default";
+ pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_i2c1>;
+ pinctrl-1 = <&pinctrl_i2c1_recovery>;
+ scl-gpios = <&gpio4 8 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio4 9 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
clock-frequency = <100000>;
status = "okay";
@@ -109,7 +112,7 @@
};
vgen4_reg: v33 {
- regulator-min-microvolt = <2850000>;
+ regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
@@ -135,7 +138,7 @@
};
/* NXP SE97BTP with temperature sensor + eeprom, TQMa7x 02xx */
- se97b: temperature-sensor-eeprom@1e {
+ se97b: temperature-sensor@1e {
compatible = "nxp,se97b", "jedec,jc-42.4-temp";
reg = <0x1e>;
};
@@ -143,15 +146,18 @@
/* ST M24C64 */
m24c64: eeprom@50 {
compatible = "atmel,24c64";
+ read-only;
reg = <0x50>;
pagesize = <32>;
+ vcc-supply = <&vgen4_reg>;
status = "okay";
};
at24c02: eeprom@56 {
- compatible = "atmel,24c02";
+ compatible = "nxp,se97b", "atmel,24c02";
reg = <0x56>;
pagesize = <16>;
+ vcc-supply = <&vgen4_reg>;
status = "okay";
};
@@ -163,91 +169,89 @@
&iomuxc {
pinctrl_i2c1: i2c1grp {
- fsl,pins = <
- MX7D_PAD_I2C1_SDA__I2C1_SDA 0x40000078
- MX7D_PAD_I2C1_SCL__I2C1_SCL 0x40000078
- >;
+ fsl,pins =
+ <MX7D_PAD_I2C1_SDA__I2C1_SDA 0x40000078>,
+ <MX7D_PAD_I2C1_SCL__I2C1_SCL 0x40000078>;
+ };
+
+ pinctrl_i2c1_recovery: i2c1recoverygrp {
+ fsl,pins =
+ <MX7D_PAD_I2C1_SDA__GPIO4_IO9 0x40000078>,
+ <MX7D_PAD_I2C1_SCL__GPIO4_IO8 0x40000078>;
};
pinctrl_pmic1: pmic1grp {
- fsl,pins = <
- MX7D_PAD_SD2_RESET_B__GPIO5_IO11 0x4000005C
- >;
+ fsl,pins =
+ <MX7D_PAD_SD2_RESET_B__GPIO5_IO11 0x4000005C>;
};
pinctrl_qspi: qspigrp {
- fsl,pins = <
- MX7D_PAD_EPDC_DATA00__QSPI_A_DATA0 0x5A
- MX7D_PAD_EPDC_DATA01__QSPI_A_DATA1 0x5A
- MX7D_PAD_EPDC_DATA02__QSPI_A_DATA2 0x5A
- MX7D_PAD_EPDC_DATA03__QSPI_A_DATA3 0x5A
- MX7D_PAD_EPDC_DATA05__QSPI_A_SCLK 0x11
- MX7D_PAD_EPDC_DATA06__QSPI_A_SS0_B 0x54
- MX7D_PAD_EPDC_DATA07__QSPI_A_SS1_B 0x54
- >;
+ fsl,pins =
+ <MX7D_PAD_EPDC_DATA00__QSPI_A_DATA0 0x5A>,
+ <MX7D_PAD_EPDC_DATA01__QSPI_A_DATA1 0x5A>,
+ <MX7D_PAD_EPDC_DATA02__QSPI_A_DATA2 0x5A>,
+ <MX7D_PAD_EPDC_DATA03__QSPI_A_DATA3 0x5A>,
+ <MX7D_PAD_EPDC_DATA05__QSPI_A_SCLK 0x11>,
+ <MX7D_PAD_EPDC_DATA06__QSPI_A_SS0_B 0x54>,
+ <MX7D_PAD_EPDC_DATA07__QSPI_A_SS1_B 0x54>;
};
pinctrl_qspi_reset: qspi_resetgrp {
- fsl,pins = <
+ fsl,pins =
/* #QSPI_RESET */
- MX7D_PAD_EPDC_DATA04__GPIO2_IO4 0x52
- >;
+ <MX7D_PAD_EPDC_DATA04__GPIO2_IO4 0x52>;
};
pinctrl_usdhc3: usdhc3grp {
- fsl,pins = <
- MX7D_PAD_SD3_CMD__SD3_CMD 0x59
- MX7D_PAD_SD3_CLK__SD3_CLK 0x56
- MX7D_PAD_SD3_DATA0__SD3_DATA0 0x59
- MX7D_PAD_SD3_DATA1__SD3_DATA1 0x59
- MX7D_PAD_SD3_DATA2__SD3_DATA2 0x59
- MX7D_PAD_SD3_DATA3__SD3_DATA3 0x59
- MX7D_PAD_SD3_DATA4__SD3_DATA4 0x59
- MX7D_PAD_SD3_DATA5__SD3_DATA5 0x59
- MX7D_PAD_SD3_DATA6__SD3_DATA6 0x59
- MX7D_PAD_SD3_DATA7__SD3_DATA7 0x59
- MX7D_PAD_SD3_STROBE__SD3_STROBE 0x19
- >;
+ fsl,pins =
+ <MX7D_PAD_SD3_CMD__SD3_CMD 0x59>,
+ <MX7D_PAD_SD3_CLK__SD3_CLK 0x56>,
+ <MX7D_PAD_SD3_DATA0__SD3_DATA0 0x59>,
+ <MX7D_PAD_SD3_DATA1__SD3_DATA1 0x59>,
+ <MX7D_PAD_SD3_DATA2__SD3_DATA2 0x59>,
+ <MX7D_PAD_SD3_DATA3__SD3_DATA3 0x59>,
+ <MX7D_PAD_SD3_DATA4__SD3_DATA4 0x59>,
+ <MX7D_PAD_SD3_DATA5__SD3_DATA5 0x59>,
+ <MX7D_PAD_SD3_DATA6__SD3_DATA6 0x59>,
+ <MX7D_PAD_SD3_DATA7__SD3_DATA7 0x59>,
+ <MX7D_PAD_SD3_STROBE__SD3_STROBE 0x19>;
};
- pinctrl_usdhc3_100mhz: usdhc3grp_100mhz {
- fsl,pins = <
- MX7D_PAD_SD3_CMD__SD3_CMD 0x5a
- MX7D_PAD_SD3_CLK__SD3_CLK 0x51
- MX7D_PAD_SD3_DATA0__SD3_DATA0 0x5a
- MX7D_PAD_SD3_DATA1__SD3_DATA1 0x5a
- MX7D_PAD_SD3_DATA2__SD3_DATA2 0x5a
- MX7D_PAD_SD3_DATA3__SD3_DATA3 0x5a
- MX7D_PAD_SD3_DATA4__SD3_DATA4 0x5a
- MX7D_PAD_SD3_DATA5__SD3_DATA5 0x5a
- MX7D_PAD_SD3_DATA6__SD3_DATA6 0x5a
- MX7D_PAD_SD3_DATA7__SD3_DATA7 0x5a
- MX7D_PAD_SD3_STROBE__SD3_STROBE 0x1a
- >;
+ pinctrl_usdhc3_100mhz: usdhc3_100mhzgrp {
+ fsl,pins =
+ <MX7D_PAD_SD3_CMD__SD3_CMD 0x5a>,
+ <MX7D_PAD_SD3_CLK__SD3_CLK 0x51>,
+ <MX7D_PAD_SD3_DATA0__SD3_DATA0 0x5a>,
+ <MX7D_PAD_SD3_DATA1__SD3_DATA1 0x5a>,
+ <MX7D_PAD_SD3_DATA2__SD3_DATA2 0x5a>,
+ <MX7D_PAD_SD3_DATA3__SD3_DATA3 0x5a>,
+ <MX7D_PAD_SD3_DATA4__SD3_DATA4 0x5a>,
+ <MX7D_PAD_SD3_DATA5__SD3_DATA5 0x5a>,
+ <MX7D_PAD_SD3_DATA6__SD3_DATA6 0x5a>,
+ <MX7D_PAD_SD3_DATA7__SD3_DATA7 0x5a>,
+ <MX7D_PAD_SD3_STROBE__SD3_STROBE 0x1a>;
};
- pinctrl_usdhc3_200mhz: usdhc3grp_200mhz {
- fsl,pins = <
- MX7D_PAD_SD3_CMD__SD3_CMD 0x5b
- MX7D_PAD_SD3_CLK__SD3_CLK 0x51
- MX7D_PAD_SD3_DATA0__SD3_DATA0 0x5b
- MX7D_PAD_SD3_DATA1__SD3_DATA1 0x5b
- MX7D_PAD_SD3_DATA2__SD3_DATA2 0x5b
- MX7D_PAD_SD3_DATA3__SD3_DATA3 0x5b
- MX7D_PAD_SD3_DATA4__SD3_DATA4 0x5b
- MX7D_PAD_SD3_DATA5__SD3_DATA5 0x5b
- MX7D_PAD_SD3_DATA6__SD3_DATA6 0x5b
- MX7D_PAD_SD3_DATA7__SD3_DATA7 0x5b
- MX7D_PAD_SD3_STROBE__SD3_STROBE 0x1b
- >;
+ pinctrl_usdhc3_200mhz: usdhc3_200mhzgrp {
+ fsl,pins =
+ <MX7D_PAD_SD3_CMD__SD3_CMD 0x5b>,
+ <MX7D_PAD_SD3_CLK__SD3_CLK 0x51>,
+ <MX7D_PAD_SD3_DATA0__SD3_DATA0 0x5b>,
+ <MX7D_PAD_SD3_DATA1__SD3_DATA1 0x5b>,
+ <MX7D_PAD_SD3_DATA2__SD3_DATA2 0x5b>,
+ <MX7D_PAD_SD3_DATA3__SD3_DATA3 0x5b>,
+ <MX7D_PAD_SD3_DATA4__SD3_DATA4 0x5b>,
+ <MX7D_PAD_SD3_DATA5__SD3_DATA5 0x5b>,
+ <MX7D_PAD_SD3_DATA6__SD3_DATA6 0x5b>,
+ <MX7D_PAD_SD3_DATA7__SD3_DATA7 0x5b>,
+ <MX7D_PAD_SD3_STROBE__SD3_STROBE 0x1b>;
};
};
&iomuxc_lpsr {
pinctrl_wdog1: wdog1grp {
- fsl,pins = <
- MX7D_PAD_LPSR_GPIO1_IO00__WDOG1_WDOG_B 0x30
- >;
+ fsl,pins =
+ <MX7D_PAD_LPSR_GPIO1_IO00__WDOG1_WDOG_B 0x30>;
};
};
@@ -265,10 +269,6 @@
};
};
-&sdma {
- status = "okay";
-};
-
&usdhc3 {
pinctrl-names = "default", "state_100mhz", "state_200mhz";
pinctrl-0 = <&pinctrl_usdhc3>;
@@ -278,6 +278,8 @@
assigned-clock-rates = <400000000>;
bus-width = <8>;
non-removable;
+ no-sd;
+ no-sdio;
vmmc-supply = <&vgen4_reg>;
vqmmc-supply = <&sw2_reg>;
status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-mba7.dts b/arch/arm/boot/dts/nxp/imx/imx7d-mba7.dts
index 32bf9fa9d00e..0443faa3dfae 100644
--- a/arch/arm/boot/dts/nxp/imx/imx7d-mba7.dts
+++ b/arch/arm/boot/dts/nxp/imx/imx7d-mba7.dts
@@ -21,8 +21,6 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet2>;
phy-mode = "rgmii-id";
- phy-reset-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>;
- phy-reset-duration = <1>;
phy-supply = <&reg_fec2_pwdn>;
phy-handle = <&ethphy2_0>;
fsl,magic-packet;
@@ -35,59 +33,85 @@
ethphy2_0: ethernet-phy@0 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet2_phy>;
ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_50_NS>;
ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_50_NS>;
ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
ti,clk-output-sel = <DP83867_CLK_O_SEL_OFF>;
+ reset-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <1000>;
+ reset-deassert-us = <500>;
};
};
};
+&gpio2 {
+ pcie-dis-hog {
+ gpio-hog;
+ gpios = <29 GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "pcie-dis";
+ };
+
+ pcie-rst-hog {
+ gpio-hog;
+ gpios = <12 GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "pcie-rst";
+ };
+};
+
&iomuxc {
pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_hog_mba7_1>;
+ pinctrl-0 = <&pinctrl_hog_mba7_1>, <&pinctrl_hog_pcie>;
pinctrl_enet2: enet2grp {
- fsl,pins = <
- MX7D_PAD_SD2_CD_B__ENET2_MDIO 0x02
- MX7D_PAD_SD2_WP__ENET2_MDC 0x00
- MX7D_PAD_EPDC_GDSP__ENET2_RGMII_TXC 0x71
- MX7D_PAD_EPDC_SDCE2__ENET2_RGMII_TD0 0x71
- MX7D_PAD_EPDC_SDCE3__ENET2_RGMII_TD1 0x71
- MX7D_PAD_EPDC_GDCLK__ENET2_RGMII_TD2 0x71
- MX7D_PAD_EPDC_GDOE__ENET2_RGMII_TD3 0x71
- MX7D_PAD_EPDC_GDRL__ENET2_RGMII_TX_CTL 0x71
- MX7D_PAD_EPDC_SDCE1__ENET2_RGMII_RXC 0x79
- MX7D_PAD_EPDC_SDCLK__ENET2_RGMII_RD0 0x79
- MX7D_PAD_EPDC_SDLE__ENET2_RGMII_RD1 0x79
- MX7D_PAD_EPDC_SDOE__ENET2_RGMII_RD2 0x79
- MX7D_PAD_EPDC_SDSHR__ENET2_RGMII_RD3 0x79
- MX7D_PAD_EPDC_SDCE0__ENET2_RGMII_RX_CTL 0x79
+ fsl,pins =
+ <MX7D_PAD_SD2_CD_B__ENET2_MDIO 0x02>,
+ <MX7D_PAD_SD2_WP__ENET2_MDC 0x00>,
+ <MX7D_PAD_EPDC_GDSP__ENET2_RGMII_TXC 0x71>,
+ <MX7D_PAD_EPDC_SDCE2__ENET2_RGMII_TD0 0x71>,
+ <MX7D_PAD_EPDC_SDCE3__ENET2_RGMII_TD1 0x71>,
+ <MX7D_PAD_EPDC_GDCLK__ENET2_RGMII_TD2 0x71>,
+ <MX7D_PAD_EPDC_GDOE__ENET2_RGMII_TD3 0x71>,
+ <MX7D_PAD_EPDC_GDRL__ENET2_RGMII_TX_CTL 0x71>,
+ <MX7D_PAD_EPDC_SDCE1__ENET2_RGMII_RXC 0x79>,
+ <MX7D_PAD_EPDC_SDCLK__ENET2_RGMII_RD0 0x79>,
+ <MX7D_PAD_EPDC_SDLE__ENET2_RGMII_RD1 0x79>,
+ <MX7D_PAD_EPDC_SDOE__ENET2_RGMII_RD2 0x79>,
+ <MX7D_PAD_EPDC_SDSHR__ENET2_RGMII_RD3 0x79>,
+ <MX7D_PAD_EPDC_SDCE0__ENET2_RGMII_RX_CTL 0x79>;
+ };
+
+ pinctrl_enet2_phy: enet2phygrp {
+ fsl,pins =
/* Reset: SION, 100kPU, SRE_FAST, DSE_X1 */
- MX7D_PAD_EPDC_BDR0__GPIO2_IO28 0x40000070
+ <MX7D_PAD_EPDC_BDR0__GPIO2_IO28 0x40000070>,
/* INT/PWDN: SION, 100kPU, HYS, SRE_FAST, DSE_X1 */
- MX7D_PAD_EPDC_PWR_STAT__GPIO2_IO31 0x40000078
- >;
+ <MX7D_PAD_EPDC_PWR_STAT__GPIO2_IO31 0x40000078>;
};
- pinctrl_pcie: pciegrp {
- fsl,pins = <
- /* #pcie_wake */
- MX7D_PAD_EPDC_PWR_COM__GPIO2_IO30 0x70
+ pinctrl_hog_pcie: hogpciegrp {
+ fsl,pins =
/* #pcie_rst */
- MX7D_PAD_SD2_CLK__GPIO5_IO12 0x70
+ <MX7D_PAD_SD2_CLK__GPIO5_IO12 0x70>,
/* #pcie_dis */
- MX7D_PAD_EPDC_BDR1__GPIO2_IO29 0x70
- >;
+ <MX7D_PAD_EPDC_BDR1__GPIO2_IO29 0x70>;
+ };
+
+ pinctrl_pcie: pciegrp {
+ fsl,pins =
+ /* #pcie_wake */
+ <MX7D_PAD_EPDC_PWR_COM__GPIO2_IO30 0x70>;
};
};
&iomuxc_lpsr {
pinctrl_usbotg2: usbotg2grp {
- fsl,pins = <
- MX7D_PAD_LPSR_GPIO1_IO06__USB_OTG2_OC 0x5c
- MX7D_PAD_LPSR_GPIO1_IO07__GPIO1_IO7 0x59
- >;
+ fsl,pins =
+ <MX7D_PAD_LPSR_GPIO1_IO06__USB_OTG2_OC 0x5c>,
+ <MX7D_PAD_LPSR_GPIO1_IO07__GPIO1_IO7 0x59>;
};
};
@@ -98,16 +122,14 @@
/* probe deferral not supported */
/* pcie-bus-supply = <&reg_mpcie_1v5>; */
reset-gpio = <&gpio5 12 GPIO_ACTIVE_LOW>;
- status = "okay";
+ status = "disabled";
};
&usbotg2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usbotg2>;
vbus-supply = <&reg_usb_otg2_vbus>;
- srp-disable;
- hnp-disable;
- adp-disable;
+ disable-over-current;
dr_mode = "host";
status = "okay";
};
diff --git a/arch/arm/boot/dts/nxp/ls/ls1021a.dtsi b/arch/arm/boot/dts/nxp/ls/ls1021a.dtsi
index d471cc5efa94..e86998ca77d6 100644
--- a/arch/arm/boot/dts/nxp/ls/ls1021a.dtsi
+++ b/arch/arm/boot/dts/nxp/ls/ls1021a.dtsi
@@ -808,7 +808,9 @@
dr_mode = "host";
snps,quirk-frame-length-adjustment = <0x20>;
snps,dis_rxdet_inp3_quirk;
+ usb3-lpm-capable;
snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>;
+ snps,host-vbus-glitches;
};
pcie@3400000 {
diff --git a/arch/arm/boot/dts/nxp/mxs/imx28-evk.dts b/arch/arm/boot/dts/nxp/mxs/imx28-evk.dts
index 9ebb7371e235..330d3aff6b6c 100644
--- a/arch/arm/boot/dts/nxp/mxs/imx28-evk.dts
+++ b/arch/arm/boot/dts/nxp/mxs/imx28-evk.dts
@@ -198,7 +198,7 @@
clocks = <&saif0>;
};
- at24@51 {
+ eeprom@51 {
compatible = "atmel,24c32";
pagesize = <32>;
reg = <0x51>;
diff --git a/arch/arm/boot/dts/qcom/Makefile b/arch/arm/boot/dts/qcom/Makefile
index 9cc1e14e6cd0..6478a39b3be5 100644
--- a/arch/arm/boot/dts/qcom/Makefile
+++ b/arch/arm/boot/dts/qcom/Makefile
@@ -36,6 +36,7 @@ dtb-$(CONFIG_ARCH_QCOM) += \
qcom-msm8926-microsoft-superman-lte.dtb \
qcom-msm8926-microsoft-tesla.dtb \
qcom-msm8926-motorola-peregrine.dtb \
+ qcom-msm8926-samsung-matisselte.dtb \
qcom-msm8960-cdp.dtb \
qcom-msm8960-samsung-expressatt.dtb \
qcom-msm8974-lge-nexus5-hammerhead.dtb \
diff --git a/arch/arm/boot/dts/qcom/qcom-apq8026-lg-lenok.dts b/arch/arm/boot/dts/qcom/qcom-apq8026-lg-lenok.dts
index 0a1fd5eb3c6d..a70de21bf139 100644
--- a/arch/arm/boot/dts/qcom/qcom-apq8026-lg-lenok.dts
+++ b/arch/arm/boot/dts/qcom/qcom-apq8026-lg-lenok.dts
@@ -7,6 +7,7 @@
#include "qcom-msm8226.dtsi"
#include "pm8226.dtsi"
+#include <dt-bindings/clock/qcom,mmcc-msm8974.h>
/delete-node/ &adsp_region;
@@ -56,6 +57,29 @@
pinctrl-names = "default";
pinctrl-0 = <&wlan_regulator_default_state>;
};
+
+ pwm_vibrator: pwm {
+ compatible = "clk-pwm";
+ clocks = <&mmcc CAMSS_GP0_CLK>;
+
+ pinctrl-0 = <&vibrator_clk_default_state>;
+ pinctrl-names = "default";
+
+ #pwm-cells = <2>;
+ };
+
+ vibrator {
+ compatible = "pwm-vibrator";
+
+ pwms = <&pwm_vibrator 0 10000>;
+ pwm-names = "enable";
+
+ vcc-supply = <&pm8226_l28>;
+ enable-gpios = <&tlmm 62 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-0 = <&vibrator_en_default_state>;
+ pinctrl-names = "default";
+ };
};
&adsp {
@@ -330,6 +354,20 @@
};
};
+ vibrator_clk_default_state: vibrator-clk-default-state {
+ pins = "gpio33";
+ function = "gp0_clk";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ vibrator_en_default_state: vibrator-en-default-state {
+ pins = "gpio62";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
wlan_hostwake_default_state: wlan-hostwake-default-state {
pins = "gpio37";
function = "gpio";
diff --git a/arch/arm/boot/dts/qcom/qcom-apq8026-samsung-matisse-wifi.dts b/arch/arm/boot/dts/qcom/qcom-apq8026-samsung-matisse-wifi.dts
index cffc069712b2..da3be658e822 100644
--- a/arch/arm/boot/dts/qcom/qcom-apq8026-samsung-matisse-wifi.dts
+++ b/arch/arm/boot/dts/qcom/qcom-apq8026-samsung-matisse-wifi.dts
@@ -5,142 +5,13 @@
/dts-v1/;
-#include <dt-bindings/input/input.h>
-#include "qcom-msm8226.dtsi"
-#include "pm8226.dtsi"
-
-/delete-node/ &adsp_region;
-/delete-node/ &smem_region;
+#include "qcom-msm8226-samsung-matisse-common.dtsi"
/ {
model = "Samsung Galaxy Tab 4 10.1";
compatible = "samsung,matisse-wifi", "qcom,apq8026";
chassis-type = "tablet";
- aliases {
- mmc0 = &sdhc_1; /* SDC1 eMMC slot */
- mmc1 = &sdhc_2; /* SDC2 SD card slot */
- display0 = &framebuffer0;
- };
-
- chosen {
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
-
- stdout-path = "display0";
-
- framebuffer0: framebuffer@3200000 {
- compatible = "simple-framebuffer";
- reg = <0x03200000 0x800000>;
- width = <1280>;
- height = <800>;
- stride = <(1280 * 3)>;
- format = "r8g8b8";
- };
- };
-
- gpio-hall-sensor {
- compatible = "gpio-keys";
-
- event-hall-sensor {
- label = "Hall Effect Sensor";
- gpios = <&tlmm 110 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>;
-
- dev-ctrl = /bits/ 8 <0x80>;
- init-brt = /bits/ 8 <0x3f>;
-
- pwms = <&backlight_pwm 0 100000>;
- pwm-names = "lp8556";
-
- rom-a0h {
- rom-addr = /bits/ 8 <0xa0>;
- rom-val = /bits/ 8 <0x44>;
- };
-
- rom-a1h {
- rom-addr = /bits/ 8 <0xa1>;
- rom-val = /bits/ 8 <0x6c>;
- };
-
- rom-a5h {
- rom-addr = /bits/ 8 <0xa5>;
- rom-val = /bits/ 8 <0x24>;
- };
- };
- };
-
- backlight_pwm: pwm {
- compatible = "clk-pwm";
- #pwm-cells = <2>;
- clocks = <&mmcc CAMSS_GP0_CLK>;
- pinctrl-0 = <&backlight_pwm_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 31 GPIO_ACTIVE_HIGH>;
- enable-active-high;
-
- pinctrl-names = "default";
- pinctrl-0 = <&tsp_en_default_state>;
- };
-
reg_tsp_3p3v: regulator-tsp-3p3v {
compatible = "regulator-fixed";
regulator-name = "tsp_3p3v";
@@ -153,74 +24,6 @@
pinctrl-names = "default";
pinctrl-0 = <&tsp_en1_default_state>;
};
-
- reserved-memory {
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
-
- framebuffer@3200000 {
- reg = <0x03200000 0x800000>;
- no-map;
- };
-
- mpss@8400000 {
- reg = <0x08400000 0x1f00000>;
- no-map;
- };
-
- mba@a300000 {
- reg = <0x0a300000 0x100000>;
- no-map;
- };
-
- reserved@cb00000 {
- reg = <0x0cb00000 0x700000>;
- no-map;
- };
-
- 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>;
- };
- };
-};
-
-&adsp {
- status = "okay";
};
&blsp1_i2c2 {
@@ -243,21 +46,6 @@
};
};
-&blsp1_i2c4 {
- status = "okay";
-
- muic: usb-switch@25 {
- compatible = "siliconmitus,sm5502-muic";
- reg = <0x25>;
-
- interrupt-parent = <&tlmm>;
- interrupts = <67 IRQ_TYPE_EDGE_FALLING>;
-
- pinctrl-names = "default";
- pinctrl-0 = <&muic_int_default_state>;
- };
-};
-
&blsp1_i2c5 {
status = "okay";
@@ -268,6 +56,13 @@
interrupt-parent = <&tlmm>;
interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
+ linux,keycodes = <KEY_RESERVED>,
+ <KEY_RESERVED>,
+ <KEY_RESERVED>,
+ <KEY_RESERVED>,
+ <KEY_APPSELECT>,
+ <KEY_BACK>;
+
pinctrl-names = "default";
pinctrl-0 = <&tsp_int_rst_default_state>;
@@ -278,242 +73,19 @@
};
};
-&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";
+&pm8226_l3 {
+ regulator-max-microvolt = <1337500>;
};
-&sdhc_2 {
- vmmc-supply = <&pm8226_l18>;
- vqmmc-supply = <&pm8226_l21>;
-
- bus-width = <4>;
- cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>;
-
- status = "okay";
+&pm8226_s4 {
+ regulator-max-microvolt = <1800000>;
};
&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_pwm_default_state: backlight-pwm-default-state {
- pins = "gpio33";
- function = "gp0_clk";
- };
-
- muic_int_default_state: muic-int-default-state {
- pins = "gpio67";
- 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 = "gpio73";
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 3faf57035d54..9a5ba978775a 100644
--- a/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi
+++ b/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi
@@ -190,7 +190,7 @@
cpu-pmu {
compatible = "qcom,krait-pmu";
- interrupts = <1 10 0x304>;
+ interrupts = <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
};
clocks {
@@ -244,7 +244,7 @@
modem_smsm: modem@1 {
reg = <1>;
- interrupts = <0 38 IRQ_TYPE_EDGE_RISING>;
+ interrupts = <GIC_SPI 38 IRQ_TYPE_EDGE_RISING>;
interrupt-controller;
#interrupt-cells = <2>;
@@ -252,7 +252,7 @@
q6_smsm: q6@2 {
reg = <2>;
- interrupts = <0 89 IRQ_TYPE_EDGE_RISING>;
+ interrupts = <GIC_SPI 89 IRQ_TYPE_EDGE_RISING>;
interrupt-controller;
#interrupt-cells = <2>;
@@ -260,7 +260,7 @@
wcnss_smsm: wcnss@3 {
reg = <3>;
- interrupts = <0 204 IRQ_TYPE_EDGE_RISING>;
+ interrupts = <GIC_SPI 204 IRQ_TYPE_EDGE_RISING>;
interrupt-controller;
#interrupt-cells = <2>;
@@ -268,7 +268,7 @@
dsps_smsm: dsps@4 {
reg = <4>;
- interrupts = <0 137 IRQ_TYPE_EDGE_RISING>;
+ interrupts = <GIC_SPI 137 IRQ_TYPE_EDGE_RISING>;
interrupt-controller;
#interrupt-cells = <2>;
@@ -299,7 +299,7 @@
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
- interrupts = <0 16 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&ps_hold>;
@@ -321,9 +321,9 @@
timer@200a000 {
compatible = "qcom,kpss-wdt-apq8064", "qcom,kpss-timer",
"qcom,msm-timer";
- interrupts = <1 1 0x301>,
- <1 2 0x301>,
- <1 3 0x301>;
+ interrupts = <GIC_PPI 1 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_EDGE_RISING)>,
+ <GIC_PPI 2 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_EDGE_RISING)>,
+ <GIC_PPI 3 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_EDGE_RISING)>;
reg = <0x0200a000 0x100>;
clock-frequency = <27000000>;
cpu-offset = <0x80000>;
@@ -365,28 +365,44 @@
#clock-cells = <0>;
};
- saw0: power-controller@2089000 {
+ saw0: power-manager@2089000 {
compatible = "qcom,apq8064-saw2-v1.1-cpu", "qcom,saw2";
reg = <0x02089000 0x1000>, <0x02009000 0x1000>;
- regulator;
+
+ saw0_vreg: regulator {
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1300000>;
+ };
};
- saw1: power-controller@2099000 {
+ saw1: power-manager@2099000 {
compatible = "qcom,apq8064-saw2-v1.1-cpu", "qcom,saw2";
reg = <0x02099000 0x1000>, <0x02009000 0x1000>;
- regulator;
+
+ saw1_vreg: regulator {
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1300000>;
+ };
};
- saw2: power-controller@20a9000 {
+ saw2: power-manager@20a9000 {
compatible = "qcom,apq8064-saw2-v1.1-cpu", "qcom,saw2";
reg = <0x020a9000 0x1000>, <0x02009000 0x1000>;
- regulator;
+
+ saw2_vreg: regulator {
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1300000>;
+ };
};
- saw3: power-controller@20b9000 {
+ saw3: power-manager@20b9000 {
compatible = "qcom,apq8064-saw2-v1.1-cpu", "qcom,saw2";
reg = <0x020b9000 0x1000>, <0x02009000 0x1000>;
- regulator;
+
+ saw3_vreg: regulator {
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1300000>;
+ };
};
sps_sic_non_secure: sps-sic-non-secure@12100000 {
@@ -411,7 +427,7 @@
compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
reg = <0x12450000 0x100>,
<0x12400000 0x03>;
- interrupts = <0 193 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GSBI1_UART_CLK>, <&gcc GSBI1_H_CLK>;
clock-names = "core", "iface";
status = "disabled";
@@ -423,7 +439,7 @@
pinctrl-1 = <&i2c1_pins_sleep>;
pinctrl-names = "default", "sleep";
reg = <0x12460000 0x1000>;
- interrupts = <0 194 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GSBI1_QUP_CLK>, <&gcc GSBI1_H_CLK>;
clock-names = "core", "iface";
#address-cells = <1>;
@@ -452,7 +468,7 @@
pinctrl-0 = <&i2c2_pins>;
pinctrl-1 = <&i2c2_pins_sleep>;
pinctrl-names = "default", "sleep";
- interrupts = <0 196 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GSBI2_QUP_CLK>, <&gcc GSBI2_H_CLK>;
clock-names = "core", "iface";
#address-cells = <1>;
@@ -539,7 +555,7 @@
compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
reg = <0x1a240000 0x100>,
<0x1a200000 0x03>;
- interrupts = <0 154 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GSBI5_UART_CLK>, <&gcc GSBI5_H_CLK>;
clock-names = "core", "iface";
status = "disabled";
@@ -548,7 +564,7 @@
gsbi5_spi: spi@1a280000 {
compatible = "qcom,spi-qup-v1.1.1";
reg = <0x1a280000 0x1000>;
- interrupts = <0 155 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
pinctrl-0 = <&spi5_default>;
pinctrl-1 = <&spi5_sleep>;
pinctrl-names = "default", "sleep";
@@ -575,7 +591,7 @@
compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
reg = <0x16540000 0x100>,
<0x16500000 0x03>;
- interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GSBI6_UART_CLK>, <&gcc GSBI6_H_CLK>;
clock-names = "core", "iface";
status = "disabled";
@@ -611,7 +627,7 @@
compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
reg = <0x16640000 0x1000>,
<0x16600000 0x1000>;
- interrupts = <0 158 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GSBI7_UART_CLK>, <&gcc GSBI7_H_CLK>;
clock-names = "core", "iface";
status = "disabled";
@@ -908,7 +924,7 @@
sdcc3bam: dma-controller@12182000 {
compatible = "qcom,bam-v1.3.0";
reg = <0x12182000 0x8000>;
- interrupts = <0 96 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc SDC3_H_CLK>;
clock-names = "bam_clk";
#dma-cells = <1>;
@@ -936,7 +952,7 @@
sdcc4bam: dma-controller@121c2000 {
compatible = "qcom,bam-v1.3.0";
reg = <0x121c2000 0x8000>;
- interrupts = <0 95 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc SDC4_H_CLK>;
clock-names = "bam_clk";
#dma-cells = <1>;
@@ -965,7 +981,7 @@
sdcc1bam: dma-controller@12402000 {
compatible = "qcom,bam-v1.3.0";
reg = <0x12402000 0x8000>;
- interrupts = <0 98 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc SDC1_H_CLK>;
clock-names = "bam_clk";
#dma-cells = <1>;
diff --git a/arch/arm/boot/dts/qcom/qcom-apq8084.dtsi b/arch/arm/boot/dts/qcom/qcom-apq8084.dtsi
index 2b1f9d0fb510..8204e64d9a97 100644
--- a/arch/arm/boot/dts/qcom/qcom-apq8084.dtsi
+++ b/arch/arm/boot/dts/qcom/qcom-apq8084.dtsi
@@ -629,30 +629,29 @@
};
};
- saw0: power-controller@f9089000 {
+ saw0: power-manager@f9089000 {
compatible = "qcom,apq8084-saw2-v2.1-cpu", "qcom,saw2";
reg = <0xf9089000 0x1000>, <0xf9009000 0x1000>;
};
- saw1: power-controller@f9099000 {
+ saw1: power-manager@f9099000 {
compatible = "qcom,apq8084-saw2-v2.1-cpu", "qcom,saw2";
reg = <0xf9099000 0x1000>, <0xf9009000 0x1000>;
};
- saw2: power-controller@f90a9000 {
+ saw2: power-manager@f90a9000 {
compatible = "qcom,apq8084-saw2-v2.1-cpu", "qcom,saw2";
reg = <0xf90a9000 0x1000>, <0xf9009000 0x1000>;
};
- saw3: power-controller@f90b9000 {
+ saw3: power-manager@f90b9000 {
compatible = "qcom,apq8084-saw2-v2.1-cpu", "qcom,saw2";
reg = <0xf90b9000 0x1000>, <0xf9009000 0x1000>;
};
- saw_l2: power-controller@f9012000 {
- compatible = "qcom,saw2";
+ saw_l2: power-manager@f9012000 {
+ compatible = "qcom,apq8084-saw2-v2.1-l2", "qcom,saw2";
reg = <0xf9012000 0x1000>;
- regulator;
};
acc0: power-manager@f9088000 {
diff --git a/arch/arm/boot/dts/qcom/qcom-ipq4019-ap.dk01.1.dtsi b/arch/arm/boot/dts/qcom/qcom-ipq4019-ap.dk01.1.dtsi
index 0505270cf508..f7ac8f9d0b6f 100644
--- a/arch/arm/boot/dts/qcom/qcom-ipq4019-ap.dk01.1.dtsi
+++ b/arch/arm/boot/dts/qcom/qcom-ipq4019-ap.dk01.1.dtsi
@@ -27,87 +27,83 @@
chosen {
stdout-path = "serial0:115200n8";
};
+};
- soc {
- rng@22000 {
- status = "okay";
- };
-
- pinctrl@1000000 {
- serial_pins: serial_pinmux {
- mux {
- pins = "gpio60", "gpio61";
- function = "blsp_uart0";
- bias-disable;
- };
- };
-
- spi_0_pins: spi_0_pinmux {
- pinmux {
- function = "blsp_spi0";
- pins = "gpio55", "gpio56", "gpio57";
- };
- pinmux_cs {
- function = "gpio";
- pins = "gpio54";
- };
- pinconf {
- pins = "gpio55", "gpio56", "gpio57";
- drive-strength = <12>;
- bias-disable;
- };
- pinconf_cs {
- pins = "gpio54";
- drive-strength = <2>;
- bias-disable;
- output-high;
- };
- };
- };
+&prng {
+ status = "okay";
+};
- blsp_dma: dma-controller@7884000 {
- status = "okay";
+&tlmm {
+ serial_pins: serial_pinmux {
+ mux {
+ pins = "gpio60", "gpio61";
+ function = "blsp_uart0";
+ bias-disable;
};
+ };
- spi@78b5000 {
- pinctrl-0 = <&spi_0_pins>;
- pinctrl-names = "default";
- status = "okay";
- cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>;
-
- mx25l25635e@0 {
- #address-cells = <1>;
- #size-cells = <1>;
- reg = <0>;
- compatible = "mx25l25635e";
- spi-max-frequency = <24000000>;
- };
+ spi_0_pins: spi_0_pinmux {
+ pinmux {
+ function = "blsp_spi0";
+ pins = "gpio55", "gpio56", "gpio57";
};
-
- serial@78af000 {
- pinctrl-0 = <&serial_pins>;
- pinctrl-names = "default";
- status = "okay";
+ pinmux_cs {
+ function = "gpio";
+ pins = "gpio54";
};
-
- cryptobam: dma-controller@8e04000 {
- status = "okay";
+ pinconf {
+ pins = "gpio55", "gpio56", "gpio57";
+ drive-strength = <12>;
+ bias-disable;
};
-
- crypto@8e3a000 {
- status = "okay";
+ pinconf_cs {
+ pins = "gpio54";
+ drive-strength = <2>;
+ bias-disable;
+ output-high;
};
+ };
+};
- watchdog@b017000 {
- status = "okay";
- };
+&blsp_dma {
+ status = "okay";
+};
- wifi@a000000 {
- status = "okay";
- };
+&blsp1_spi1 {
+ pinctrl-0 = <&spi_0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>;
- wifi@a800000 {
- status = "okay";
- };
+ flash@0 {
+ reg = <0>;
+ compatible = "jedec,spi-nor";
+ spi-max-frequency = <24000000>;
};
};
+
+&blsp1_uart1 {
+ pinctrl-0 = <&serial_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&cryptobam {
+ status = "okay";
+};
+
+&crypto {
+ status = "okay";
+};
+
+&watchdog {
+ status = "okay";
+};
+
+&wifi0 {
+ status = "okay";
+};
+
+&wifi1 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/qcom/qcom-ipq4019.dtsi b/arch/arm/boot/dts/qcom/qcom-ipq4019.dtsi
index f989bd741cd1..681cb3fc8085 100644
--- a/arch/arm/boot/dts/qcom/qcom-ipq4019.dtsi
+++ b/arch/arm/boot/dts/qcom/qcom-ipq4019.dtsi
@@ -162,10 +162,10 @@
timer {
compatible = "arm,armv7-timer";
- interrupts = <1 2 0xf08>,
- <1 3 0xf08>,
- <1 4 0xf08>,
- <1 1 0xf08>;
+ interrupts = <GIC_PPI 2 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 3 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 4 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 1 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
clock-frequency = <48000000>;
always-on;
};
@@ -350,34 +350,29 @@
reg = <0x0b0b8000 0x1000>, <0xb008000 0x1000>;
};
- saw0: regulator@b089000 {
- compatible = "qcom,saw2";
+ saw0: power-manager@b089000 {
+ compatible = "qcom,ipq4019-saw2-cpu", "qcom,saw2";
reg = <0x0b089000 0x1000>, <0x0b009000 0x1000>;
- regulator;
};
- saw1: regulator@b099000 {
- compatible = "qcom,saw2";
+ saw1: power-manager@b099000 {
+ compatible = "qcom,ipq4019-saw2-cpu", "qcom,saw2";
reg = <0x0b099000 0x1000>, <0x0b009000 0x1000>;
- regulator;
};
- saw2: regulator@b0a9000 {
- compatible = "qcom,saw2";
+ saw2: power-manager@b0a9000 {
+ compatible = "qcom,ipq4019-saw2-cpu", "qcom,saw2";
reg = <0x0b0a9000 0x1000>, <0x0b009000 0x1000>;
- regulator;
};
- saw3: regulator@b0b9000 {
- compatible = "qcom,saw2";
+ saw3: power-manager@b0b9000 {
+ compatible = "qcom,ipq4019-saw2-cpu", "qcom,saw2";
reg = <0x0b0b9000 0x1000>, <0x0b009000 0x1000>;
- regulator;
};
- saw_l2: regulator@b012000 {
- compatible = "qcom,saw2";
+ saw_l2: power-manager@b012000 {
+ compatible = "qcom,ipq4019-saw2-l2", "qcom,saw2";
reg = <0xb012000 0x1000>;
- regulator;
};
blsp1_uart1: serial@78af000 {
@@ -684,7 +679,7 @@
clocks = <&gcc GCC_USB2_MASTER_CLK>,
<&gcc GCC_USB2_SLEEP_CLK>,
<&gcc GCC_USB2_MOCK_UTMI_CLK>;
- clock-names = "master", "sleep", "mock_utmi";
+ clock-names = "core", "sleep", "mock_utmi";
ranges;
status = "disabled";
diff --git a/arch/arm/boot/dts/qcom/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom/qcom-ipq8064.dtsi
index 6a7f4dd0f775..2eb6758b6a3a 100644
--- a/arch/arm/boot/dts/qcom/qcom-ipq8064.dtsi
+++ b/arch/arm/boot/dts/qcom/qcom-ipq8064.dtsi
@@ -586,10 +586,9 @@
#clock-cells = <0>;
};
- saw0: regulator@2089000 {
- compatible = "qcom,saw2";
+ saw0: power-manager@2089000 {
+ compatible = "qcom,ipq8064-saw2-cpu", "qcom,saw2";
reg = <0x02089000 0x1000>, <0x02009000 0x1000>;
- regulator;
};
acc1: clock-controller@2098000 {
@@ -601,10 +600,9 @@
#clock-cells = <0>;
};
- saw1: regulator@2099000 {
- compatible = "qcom,saw2";
+ saw1: power-manager@2099000 {
+ compatible = "qcom,ipq8064-saw2-cpu", "qcom,saw2";
reg = <0x02099000 0x1000>, <0x02009000 0x1000>;
- regulator;
};
nss_common: syscon@3000000 {
@@ -623,7 +621,6 @@
ranges;
resets = <&gcc USB30_0_MASTER_RESET>;
- reset-names = "master";
status = "disabled";
@@ -669,7 +666,6 @@
ranges;
resets = <&gcc USB30_1_MASTER_RESET>;
- reset-names = "master";
status = "disabled";
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8226-samsung-matisse-common.dtsi b/arch/arm/boot/dts/qcom/qcom-msm8226-samsung-matisse-common.dtsi
new file mode 100644
index 000000000000..a15a44fc0181
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/qcom-msm8226-samsung-matisse-common.dtsi
@@ -0,0 +1,457 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2022, Matti Lehtimäki <matti.lehtimaki@gmail.com>
+ */
+
+#include <dt-bindings/input/input.h>
+#include "qcom-msm8226.dtsi"
+#include "pm8226.dtsi"
+
+/delete-node/ &adsp_region;
+/delete-node/ &smem_region;
+
+/ {
+ aliases {
+ mmc0 = &sdhc_1; /* SDC1 eMMC slot */
+ mmc1 = &sdhc_2; /* SDC2 SD card slot */
+ display0 = &framebuffer0;
+ };
+
+ chosen {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ stdout-path = "display0";
+
+ framebuffer0: framebuffer@3200000 {
+ compatible = "simple-framebuffer";
+ reg = <0x03200000 0x800000>;
+ width = <1280>;
+ height = <800>;
+ stride = <(1280 * 3)>;
+ format = "r8g8b8";
+ };
+ };
+
+ gpio-hall-sensor {
+ compatible = "gpio-keys";
+
+ event-hall-sensor {
+ label = "Hall Effect Sensor";
+ gpios = <&tlmm 110 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>;
+
+ dev-ctrl = /bits/ 8 <0x80>;
+ init-brt = /bits/ 8 <0x3f>;
+
+ pwms = <&backlight_pwm 0 100000>;
+ pwm-names = "lp8556";
+
+ rom-a0h {
+ rom-addr = /bits/ 8 <0xa0>;
+ rom-val = /bits/ 8 <0x44>;
+ };
+
+ rom-a1h {
+ rom-addr = /bits/ 8 <0xa1>;
+ rom-val = /bits/ 8 <0x6c>;
+ };
+
+ rom-a5h {
+ rom-addr = /bits/ 8 <0xa5>;
+ rom-val = /bits/ 8 <0x24>;
+ };
+ };
+ };
+
+ backlight_pwm: pwm {
+ compatible = "clk-pwm";
+ #pwm-cells = <2>;
+ clocks = <&mmcc CAMSS_GP0_CLK>;
+ pinctrl-0 = <&backlight_pwm_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 31 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&tsp_en_default_state>;
+ };
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ framebuffer@3200000 {
+ reg = <0x03200000 0x800000>;
+ no-map;
+ };
+
+ mpss@8400000 {
+ reg = <0x08400000 0x1f00000>;
+ no-map;
+ };
+
+ mba@a300000 {
+ reg = <0x0a300000 0x100000>;
+ no-map;
+ };
+
+ reserved@cb00000 {
+ reg = <0x0cb00000 0x700000>;
+ no-map;
+ };
+
+ 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>;
+ };
+ };
+};
+
+&adsp {
+ status = "okay";
+};
+
+&blsp1_i2c4 {
+ status = "okay";
+
+ muic: usb-switch@25 {
+ compatible = "siliconmitus,sm5502-muic";
+ reg = <0x25>;
+
+ interrupt-parent = <&tlmm>;
+ interrupts = <67 IRQ_TYPE_EDGE_FALLING>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&muic_int_default_state>;
+ };
+};
+
+&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 = <1350000>;
+ 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>;
+
+ 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_pwm_default_state: backlight-pwm-default-state {
+ pins = "gpio33";
+ function = "gp0_clk";
+ };
+
+ muic_int_default_state: muic-int-default-state {
+ pins = "gpio67";
+ 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_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-msm8226.dtsi b/arch/arm/boot/dts/qcom/qcom-msm8226.dtsi
index b492c95e5d30..270973e85625 100644
--- a/arch/arm/boot/dts/qcom/qcom-msm8226.dtsi
+++ b/arch/arm/boot/dts/qcom/qcom-msm8226.dtsi
@@ -20,11 +20,6 @@
chosen { };
- memory@0 {
- device_type = "memory";
- reg = <0x0 0x0>;
- };
-
clocks {
xo_board: xo_board {
compatible = "fixed-clock";
@@ -39,6 +34,57 @@
};
};
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ CPU0: cpu@0 {
+ compatible = "arm,cortex-a7";
+ enable-method = "qcom,msm8226-smp";
+ device_type = "cpu";
+ reg = <0>;
+ next-level-cache = <&L2>;
+ qcom,acc = <&acc0>;
+ qcom,saw = <&saw0>;
+ };
+
+ CPU1: cpu@1 {
+ compatible = "arm,cortex-a7";
+ enable-method = "qcom,msm8226-smp";
+ device_type = "cpu";
+ reg = <1>;
+ next-level-cache = <&L2>;
+ qcom,acc = <&acc1>;
+ qcom,saw = <&saw1>;
+ };
+
+ CPU2: cpu@2 {
+ compatible = "arm,cortex-a7";
+ enable-method = "qcom,msm8226-smp";
+ device_type = "cpu";
+ reg = <2>;
+ next-level-cache = <&L2>;
+ qcom,acc = <&acc2>;
+ qcom,saw = <&saw2>;
+ };
+
+ CPU3: cpu@3 {
+ compatible = "arm,cortex-a7";
+ enable-method = "qcom,msm8226-smp";
+ device_type = "cpu";
+ reg = <3>;
+ next-level-cache = <&L2>;
+ qcom,acc = <&acc3>;
+ qcom,saw = <&saw3>;
+ };
+
+ L2: l2-cache {
+ compatible = "cache";
+ cache-level = <2>;
+ cache-unified;
+ };
+ };
+
firmware {
scm {
compatible = "qcom,scm-msm8226", "qcom,scm";
@@ -47,6 +93,11 @@
};
};
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x0>;
+ };
+
pmu {
compatible = "arm,cortex-a7-pmu";
interrupts = <GIC_PPI 7 (GIC_CPU_MASK_SIMPLE(4) |
@@ -185,6 +236,117 @@
reg = <0xf9011000 0x1000>;
};
+ saw_l2: power-manager@f9012000 {
+ compatible = "qcom,msm8226-saw2-v2.1-l2", "qcom,saw2";
+ reg = <0xf9012000 0x1000>;
+ };
+
+ watchdog@f9017000 {
+ compatible = "qcom,apss-wdt-msm8226", "qcom,kpss-wdt";
+ reg = <0xf9017000 0x1000>;
+ interrupts = <GIC_SPI 3 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 4 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&sleep_clk>;
+ };
+
+ timer@f9020000 {
+ compatible = "arm,armv7-timer-mem";
+ reg = <0xf9020000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ frame@f9021000 {
+ frame-number = <0>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xf9021000 0x1000>,
+ <0xf9022000 0x1000>;
+ };
+
+ frame@f9023000 {
+ frame-number = <1>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xf9023000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9024000 {
+ frame-number = <2>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xf9024000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9025000 {
+ frame-number = <3>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xf9025000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9026000 {
+ frame-number = <4>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xf9026000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9027000 {
+ frame-number = <5>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xf9027000 0x1000>;
+ status = "disabled";
+ };
+
+ frame@f9028000 {
+ frame-number = <6>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+ reg = <0xf9028000 0x1000>;
+ status = "disabled";
+ };
+ };
+
+ acc0: power-manager@f9088000 {
+ compatible = "qcom,kpss-acc-v2";
+ reg = <0xf9088000 0x1000>, <0xf9008000 0x1000>;
+ };
+
+ saw0: power-manager@f9089000 {
+ compatible = "qcom,msm8226-saw2-v2.1-cpu", "qcom,saw2";
+ reg = <0xf9089000 0x1000>;
+ };
+
+ acc1: power-manager@f9098000 {
+ compatible = "qcom,kpss-acc-v2";
+ reg = <0xf9098000 0x1000>, <0xf9008000 0x1000>;
+ };
+
+ saw1: power-manager@f9099000 {
+ compatible = "qcom,msm8226-saw2-v2.1-cpu", "qcom,saw2";
+ reg = <0xf9099000 0x1000>;
+ };
+
+ acc2: power-manager@f90a8000 {
+ compatible = "qcom,kpss-acc-v2";
+ reg = <0xf90a8000 0x1000>, <0xf9008000 0x1000>;
+ };
+
+ saw2: power-manager@f90a9000 {
+ compatible = "qcom,msm8226-saw2-v2.1-cpu", "qcom,saw2";
+ reg = <0xf90a9000 0x1000>;
+ };
+
+ acc3: power-manager@f90b8000 {
+ compatible = "qcom,kpss-acc-v2";
+ reg = <0xf90b8000 0x1000>, <0xf9008000 0x1000>;
+ };
+
+ saw3: power-manager@f90b9000 {
+ compatible = "qcom,msm8226-saw2-v2.1-cpu", "qcom,saw2";
+ reg = <0xf90b9000 0x1000>;
+ };
+
sdhc_1: mmc@f9824900 {
compatible = "qcom,msm8226-sdhci", "qcom,sdhci-msm-v4";
reg = <0xf9824900 0x11c>, <0xf9824000 0x800>;
@@ -201,35 +363,35 @@
status = "disabled";
};
- sdhc_2: mmc@f98a4900 {
+ sdhc_3: mmc@f9864900 {
compatible = "qcom,msm8226-sdhci", "qcom,sdhci-msm-v4";
- reg = <0xf98a4900 0x11c>, <0xf98a4000 0x800>;
+ reg = <0xf9864900 0x11c>, <0xf9864000 0x800>;
reg-names = "hc", "core";
- interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "hc_irq", "pwr_irq";
- clocks = <&gcc GCC_SDCC2_AHB_CLK>,
- <&gcc GCC_SDCC2_APPS_CLK>,
+ clocks = <&gcc GCC_SDCC3_AHB_CLK>,
+ <&gcc GCC_SDCC3_APPS_CLK>,
<&rpmcc RPM_SMD_XO_CLK_SRC>;
clock-names = "iface", "core", "xo";
pinctrl-names = "default";
- pinctrl-0 = <&sdhc2_default_state>;
+ pinctrl-0 = <&sdhc3_default_state>;
status = "disabled";
};
- sdhc_3: mmc@f9864900 {
+ sdhc_2: mmc@f98a4900 {
compatible = "qcom,msm8226-sdhci", "qcom,sdhci-msm-v4";
- reg = <0xf9864900 0x11c>, <0xf9864000 0x800>;
+ reg = <0xf98a4900 0x11c>, <0xf98a4000 0x800>;
reg-names = "hc", "core";
- interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "hc_irq", "pwr_irq";
- clocks = <&gcc GCC_SDCC3_AHB_CLK>,
- <&gcc GCC_SDCC3_APPS_CLK>,
+ clocks = <&gcc GCC_SDCC2_AHB_CLK>,
+ <&gcc GCC_SDCC2_APPS_CLK>,
<&rpmcc RPM_SMD_XO_CLK_SRC>;
clock-names = "iface", "core", "xo";
pinctrl-names = "default";
- pinctrl-0 = <&sdhc3_default_state>;
+ pinctrl-0 = <&sdhc2_default_state>;
status = "disabled";
};
@@ -272,7 +434,6 @@
};
blsp1_i2c1: i2c@f9923000 {
- status = "disabled";
compatible = "qcom,i2c-qup-v2.1.1";
reg = <0xf9923000 0x1000>;
interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
@@ -282,10 +443,10 @@
pinctrl-0 = <&blsp1_i2c1_pins>;
#address-cells = <1>;
#size-cells = <0>;
+ status = "disabled";
};
blsp1_i2c2: i2c@f9924000 {
- status = "disabled";
compatible = "qcom,i2c-qup-v2.1.1";
reg = <0xf9924000 0x1000>;
interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
@@ -295,10 +456,10 @@
pinctrl-0 = <&blsp1_i2c2_pins>;
#address-cells = <1>;
#size-cells = <0>;
+ status = "disabled";
};
blsp1_i2c3: i2c@f9925000 {
- status = "disabled";
compatible = "qcom,i2c-qup-v2.1.1";
reg = <0xf9925000 0x1000>;
interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
@@ -308,10 +469,10 @@
pinctrl-0 = <&blsp1_i2c3_pins>;
#address-cells = <1>;
#size-cells = <0>;
+ status = "disabled";
};
blsp1_i2c4: i2c@f9926000 {
- status = "disabled";
compatible = "qcom,i2c-qup-v2.1.1";
reg = <0xf9926000 0x1000>;
interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
@@ -321,10 +482,10 @@
pinctrl-0 = <&blsp1_i2c4_pins>;
#address-cells = <1>;
#size-cells = <0>;
+ status = "disabled";
};
blsp1_i2c5: i2c@f9927000 {
- status = "disabled";
compatible = "qcom,i2c-qup-v2.1.1";
reg = <0xf9927000 0x1000>;
interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>;
@@ -334,6 +495,7 @@
pinctrl-0 = <&blsp1_i2c5_pins>;
#address-cells = <1>;
#size-cells = <0>;
+ status = "disabled";
};
blsp1_i2c6: i2c@f9928000 {
@@ -351,33 +513,6 @@
status = "disabled";
};
- cci: cci@fda0c000 {
- compatible = "qcom,msm8226-cci";
- #address-cells = <1>;
- #size-cells = <0>;
- reg = <0xfda0c000 0x1000>;
- interrupts = <GIC_SPI 50 IRQ_TYPE_EDGE_RISING>;
- clocks = <&mmcc CAMSS_TOP_AHB_CLK>,
- <&mmcc CAMSS_CCI_CCI_AHB_CLK>,
- <&mmcc CAMSS_CCI_CCI_CLK>;
- clock-names = "camss_top_ahb",
- "cci_ahb",
- "cci";
-
- pinctrl-names = "default", "sleep";
- pinctrl-0 = <&cci_default>;
- pinctrl-1 = <&cci_sleep>;
-
- status = "disabled";
-
- cci_i2c0: i2c-bus@0 {
- reg = <0>;
- clock-frequency = <400000>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- };
-
usb: usb@f9a55000 {
compatible = "qcom,ci-hdrc";
reg = <0xf9a55000 0x200>,
@@ -417,6 +552,18 @@
};
};
+ rng@f9bff000 {
+ compatible = "qcom,prng";
+ reg = <0xf9bff000 0x200>;
+ clocks = <&gcc GCC_PRNG_AHB_CLK>;
+ clock-names = "core";
+ };
+
+ sram@fc190000 {
+ compatible = "qcom,msm8226-rpm-stats";
+ reg = <0xfc190000 0x10000>;
+ };
+
gcc: clock-controller@fc400000 {
compatible = "qcom,gcc-msm8226";
reg = <0xfc400000 0x4000>;
@@ -430,146 +577,28 @@
"sleep_clk";
};
- mmcc: clock-controller@fd8c0000 {
- compatible = "qcom,mmcc-msm8226";
- reg = <0xfd8c0000 0x6000>;
- #clock-cells = <1>;
- #reset-cells = <1>;
- #power-domain-cells = <1>;
-
- clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>,
- <&gcc GCC_MMSS_GPLL0_CLK_SRC>,
- <&gcc GPLL0_VOTE>,
- <&gcc GPLL1_VOTE>,
- <&rpmcc RPM_SMD_GFX3D_CLK_SRC>,
- <&mdss_dsi0_phy 1>,
- <&mdss_dsi0_phy 0>;
- clock-names = "xo",
- "mmss_gpll0_vote",
- "gpll0_vote",
- "gpll1_vote",
- "gfx3d_clk_src",
- "dsi0pll",
- "dsi0pllbyte";
- };
-
- tlmm: pinctrl@fd510000 {
- compatible = "qcom,msm8226-pinctrl";
- reg = <0xfd510000 0x4000>;
- gpio-controller;
- #gpio-cells = <2>;
- gpio-ranges = <&tlmm 0 0 117>;
- interrupt-controller;
- #interrupt-cells = <2>;
- interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
-
- blsp1_i2c1_pins: blsp1-i2c1-state {
- pins = "gpio2", "gpio3";
- function = "blsp_i2c1";
- drive-strength = <2>;
- bias-disable;
- };
-
- blsp1_i2c2_pins: blsp1-i2c2-state {
- pins = "gpio6", "gpio7";
- function = "blsp_i2c2";
- drive-strength = <2>;
- bias-disable;
- };
-
- blsp1_i2c3_pins: blsp1-i2c3-state {
- pins = "gpio10", "gpio11";
- function = "blsp_i2c3";
- drive-strength = <2>;
- bias-disable;
- };
-
- blsp1_i2c4_pins: blsp1-i2c4-state {
- pins = "gpio14", "gpio15";
- function = "blsp_i2c4";
- drive-strength = <2>;
- bias-disable;
- };
-
- blsp1_i2c5_pins: blsp1-i2c5-state {
- pins = "gpio18", "gpio19";
- function = "blsp_i2c5";
- drive-strength = <2>;
- bias-disable;
- };
-
- blsp1_i2c6_pins: blsp1-i2c6-state {
- pins = "gpio22", "gpio23";
- function = "blsp_i2c6";
- drive-strength = <2>;
- bias-disable;
- };
-
- cci_default: cci-default-state {
- pins = "gpio29", "gpio30";
- function = "cci_i2c0";
-
- drive-strength = <2>;
- bias-disable;
- };
+ rpm_msg_ram: sram@fc428000 {
+ compatible = "qcom,rpm-msg-ram";
+ reg = <0xfc428000 0x4000>;
- cci_sleep: cci-sleep-state {
- pins = "gpio29", "gpio30";
- function = "gpio";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0xfc428000 0x4000>;
- drive-strength = <2>;
- bias-disable;
+ apss_master_stats: sram@150 {
+ reg = <0x150 0x14>;
};
- sdhc1_default_state: sdhc1-default-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;
- };
+ mpss_master_stats: sram@b50 {
+ reg = <0xb50 0x14>;
};
- sdhc2_default_state: sdhc2-default-state {
- clk-pins {
- pins = "sdc2_clk";
- drive-strength = <10>;
- bias-disable;
- };
-
- cmd-data-pins {
- pins = "sdc2_cmd", "sdc2_data";
- drive-strength = <10>;
- bias-pull-up;
- };
+ lpss_master_stats: sram@1550 {
+ reg = <0x1550 0x14>;
};
- sdhc3_default_state: sdhc3-default-state {
- clk-pins {
- pins = "gpio44";
- function = "sdc3";
- drive-strength = <8>;
- bias-disable;
- };
-
- cmd-pins {
- pins = "gpio43";
- function = "sdc3";
- drive-strength = <8>;
- bias-pull-up;
- };
-
- data-pins {
- pins = "gpio39", "gpio40", "gpio41", "gpio42";
- function = "sdc3";
- drive-strength = <8>;
- bias-pull-up;
- };
+ pronto_master_stats: sram@1f50 {
+ reg = <0x1f50 0x14>;
};
};
@@ -714,170 +743,153 @@
#interrupt-cells = <4>;
};
- rng@f9bff000 {
- compatible = "qcom,prng";
- reg = <0xf9bff000 0x200>;
- clocks = <&gcc GCC_PRNG_AHB_CLK>;
- clock-names = "core";
+ tcsr_mutex: hwlock@fd484000 {
+ compatible = "qcom,msm8226-tcsr-mutex", "qcom,tcsr-mutex";
+ reg = <0xfd484000 0x1000>;
+ #hwlock-cells = <1>;
};
- timer@f9020000 {
- compatible = "arm,armv7-timer-mem";
- reg = <0xf9020000 0x1000>;
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
-
- frame@f9021000 {
- frame-number = <0>;
- interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
- reg = <0xf9021000 0x1000>,
- <0xf9022000 0x1000>;
- };
+ tlmm: pinctrl@fd510000 {
+ compatible = "qcom,msm8226-pinctrl";
+ reg = <0xfd510000 0x4000>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&tlmm 0 0 117>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
- frame@f9023000 {
- frame-number = <1>;
- interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
- reg = <0xf9023000 0x1000>;
- status = "disabled";
+ blsp1_i2c1_pins: blsp1-i2c1-state {
+ pins = "gpio2", "gpio3";
+ function = "blsp_i2c1";
+ drive-strength = <2>;
+ bias-disable;
};
- frame@f9024000 {
- frame-number = <2>;
- interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
- reg = <0xf9024000 0x1000>;
- status = "disabled";
+ blsp1_i2c2_pins: blsp1-i2c2-state {
+ pins = "gpio6", "gpio7";
+ function = "blsp_i2c2";
+ drive-strength = <2>;
+ bias-disable;
};
- frame@f9025000 {
- frame-number = <3>;
- interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
- reg = <0xf9025000 0x1000>;
- status = "disabled";
+ blsp1_i2c3_pins: blsp1-i2c3-state {
+ pins = "gpio10", "gpio11";
+ function = "blsp_i2c3";
+ drive-strength = <2>;
+ bias-disable;
};
- frame@f9026000 {
- frame-number = <4>;
- interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
- reg = <0xf9026000 0x1000>;
- status = "disabled";
+ blsp1_i2c4_pins: blsp1-i2c4-state {
+ pins = "gpio14", "gpio15";
+ function = "blsp_i2c4";
+ drive-strength = <2>;
+ bias-disable;
};
- frame@f9027000 {
- frame-number = <5>;
- interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
- reg = <0xf9027000 0x1000>;
- status = "disabled";
+ blsp1_i2c5_pins: blsp1-i2c5-state {
+ pins = "gpio18", "gpio19";
+ function = "blsp_i2c5";
+ drive-strength = <2>;
+ bias-disable;
};
- frame@f9028000 {
- frame-number = <6>;
- interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
- reg = <0xf9028000 0x1000>;
- status = "disabled";
+ blsp1_i2c6_pins: blsp1-i2c6-state {
+ pins = "gpio22", "gpio23";
+ function = "blsp_i2c6";
+ drive-strength = <2>;
+ bias-disable;
};
- };
-
- sram@fc190000 {
- compatible = "qcom,msm8226-rpm-stats";
- reg = <0xfc190000 0x10000>;
- };
-
- rpm_msg_ram: sram@fc428000 {
- compatible = "qcom,rpm-msg-ram";
- reg = <0xfc428000 0x4000>;
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0 0xfc428000 0x4000>;
-
- apss_master_stats: sram@150 {
- reg = <0x150 0x14>;
- };
+ cci_default: cci-default-state {
+ pins = "gpio29", "gpio30";
+ function = "cci_i2c0";
- mpss_master_stats: sram@b50 {
- reg = <0xb50 0x14>;
+ drive-strength = <2>;
+ bias-disable;
};
- lpss_master_stats: sram@1550 {
- reg = <0x1550 0x14>;
- };
+ cci_sleep: cci-sleep-state {
+ pins = "gpio29", "gpio30";
+ function = "gpio";
- pronto_master_stats: sram@1f50 {
- reg = <0x1f50 0x14>;
+ drive-strength = <2>;
+ bias-disable;
};
- };
-
- tcsr_mutex: hwlock@fd484000 {
- compatible = "qcom,msm8226-tcsr-mutex", "qcom,tcsr-mutex";
- reg = <0xfd484000 0x1000>;
- #hwlock-cells = <1>;
- };
- adsp: remoteproc@fe200000 {
- compatible = "qcom,msm8226-adsp-pil";
- reg = <0xfe200000 0x100>;
-
- interrupts-extended = <&intc GIC_SPI 162 IRQ_TYPE_EDGE_RISING>,
- <&adsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
- <&adsp_smp2p_in 1 IRQ_TYPE_EDGE_RISING>,
- <&adsp_smp2p_in 2 IRQ_TYPE_EDGE_RISING>,
- <&adsp_smp2p_in 3 IRQ_TYPE_EDGE_RISING>;
- interrupt-names = "wdog", "fatal", "ready", "handover", "stop-ack";
-
- power-domains = <&rpmpd MSM8226_VDDCX>;
- power-domain-names = "cx";
-
- clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>;
- clock-names = "xo";
-
- memory-region = <&adsp_region>;
-
- qcom,smem-states = <&adsp_smp2p_out 0>;
- qcom,smem-state-names = "stop";
-
- status = "disabled";
+ sdhc1_default_state: sdhc1-default-state {
+ clk-pins {
+ pins = "sdc1_clk";
+ drive-strength = <10>;
+ bias-disable;
+ };
- smd-edge {
- interrupts = <GIC_SPI 156 IRQ_TYPE_EDGE_RISING>;
+ cmd-data-pins {
+ pins = "sdc1_cmd", "sdc1_data";
+ drive-strength = <10>;
+ bias-pull-up;
+ };
+ };
- qcom,ipc = <&apcs 8 8>;
- qcom,smd-edge = <1>;
+ sdhc2_default_state: sdhc2-default-state {
+ clk-pins {
+ pins = "sdc2_clk";
+ drive-strength = <10>;
+ bias-disable;
+ };
- label = "lpass";
+ cmd-data-pins {
+ pins = "sdc2_cmd", "sdc2_data";
+ drive-strength = <10>;
+ bias-pull-up;
+ };
};
- };
- sram@fdd00000 {
- compatible = "qcom,msm8226-ocmem";
- reg = <0xfdd00000 0x2000>,
- <0xfec00000 0x20000>;
- reg-names = "ctrl", "mem";
- ranges = <0 0xfec00000 0x20000>;
- clocks = <&rpmcc RPM_SMD_OCMEMGX_CLK>;
- clock-names = "core";
+ sdhc3_default_state: sdhc3-default-state {
+ clk-pins {
+ pins = "gpio44";
+ function = "sdc3";
+ drive-strength = <8>;
+ bias-disable;
+ };
- #address-cells = <1>;
- #size-cells = <1>;
+ cmd-pins {
+ pins = "gpio43";
+ function = "sdc3";
+ drive-strength = <8>;
+ bias-pull-up;
+ };
- gmu_sram: gmu-sram@0 {
- reg = <0x0 0x20000>;
+ data-pins {
+ pins = "gpio39", "gpio40", "gpio41", "gpio42";
+ function = "sdc3";
+ drive-strength = <8>;
+ bias-pull-up;
+ };
};
};
- sram@fe805000 {
- compatible = "qcom,msm8226-imem", "syscon", "simple-mfd";
- reg = <0xfe805000 0x1000>;
-
- reboot-mode {
- compatible = "syscon-reboot-mode";
- offset = <0x65c>;
+ mmcc: clock-controller@fd8c0000 {
+ compatible = "qcom,mmcc-msm8226";
+ reg = <0xfd8c0000 0x6000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ #power-domain-cells = <1>;
- mode-bootloader = <0x77665500>;
- mode-normal = <0x77665501>;
- mode-recovery = <0x77665502>;
- };
+ clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>,
+ <&gcc GCC_MMSS_GPLL0_CLK_SRC>,
+ <&gcc GPLL0_VOTE>,
+ <&gcc GPLL1_VOTE>,
+ <&rpmcc RPM_SMD_GFX3D_CLK_SRC>,
+ <&mdss_dsi0_phy 1>,
+ <&mdss_dsi0_phy 0>;
+ clock-names = "xo",
+ "mmss_gpll0_vote",
+ "gpll0_vote",
+ "gpll1_vote",
+ "gfx3d_clk_src",
+ "dsi0pll",
+ "dsi0pllbyte";
};
mdss: display-subsystem@fd900000 {
@@ -1007,6 +1019,33 @@
};
};
+ cci: cci@fda0c000 {
+ compatible = "qcom,msm8226-cci";
+ reg = <0xfda0c000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <GIC_SPI 50 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&mmcc CAMSS_TOP_AHB_CLK>,
+ <&mmcc CAMSS_CCI_CCI_AHB_CLK>,
+ <&mmcc CAMSS_CCI_CCI_CLK>;
+ clock-names = "camss_top_ahb",
+ "cci_ahb",
+ "cci";
+
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&cci_default>;
+ pinctrl-1 = <&cci_sleep>;
+
+ status = "disabled";
+
+ cci_i2c0: i2c-bus@0 {
+ reg = <0>;
+ clock-frequency = <400000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
gpu: adreno@fdb00000 {
compatible = "qcom,adreno-305.18", "qcom,adreno";
reg = <0xfdb00000 0x10000>;
@@ -1046,6 +1085,71 @@
};
};
};
+
+ sram@fdd00000 {
+ compatible = "qcom,msm8226-ocmem";
+ reg = <0xfdd00000 0x2000>,
+ <0xfec00000 0x20000>;
+ reg-names = "ctrl", "mem";
+ ranges = <0 0xfec00000 0x20000>;
+ clocks = <&rpmcc RPM_SMD_OCMEMGX_CLK>;
+ clock-names = "core";
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ gmu_sram: gmu-sram@0 {
+ reg = <0x0 0x20000>;
+ };
+ };
+
+ adsp: remoteproc@fe200000 {
+ compatible = "qcom,msm8226-adsp-pil";
+ reg = <0xfe200000 0x100>;
+
+ interrupts-extended = <&intc GIC_SPI 162 IRQ_TYPE_EDGE_RISING>,
+ <&adsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
+ <&adsp_smp2p_in 1 IRQ_TYPE_EDGE_RISING>,
+ <&adsp_smp2p_in 2 IRQ_TYPE_EDGE_RISING>,
+ <&adsp_smp2p_in 3 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "wdog", "fatal", "ready", "handover", "stop-ack";
+
+ power-domains = <&rpmpd MSM8226_VDDCX>;
+ power-domain-names = "cx";
+
+ clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>;
+ clock-names = "xo";
+
+ memory-region = <&adsp_region>;
+
+ qcom,smem-states = <&adsp_smp2p_out 0>;
+ qcom,smem-state-names = "stop";
+
+ status = "disabled";
+
+ smd-edge {
+ interrupts = <GIC_SPI 156 IRQ_TYPE_EDGE_RISING>;
+
+ qcom,ipc = <&apcs 8 8>;
+ qcom,smd-edge = <1>;
+
+ label = "lpass";
+ };
+ };
+
+ sram@fe805000 {
+ compatible = "qcom,msm8226-imem", "syscon", "simple-mfd";
+ reg = <0xfe805000 0x1000>;
+
+ reboot-mode {
+ compatible = "syscon-reboot-mode";
+ offset = <0x65c>;
+
+ mode-bootloader = <0x77665500>;
+ mode-normal = <0x77665501>;
+ mode-recovery = <0x77665502>;
+ };
+ };
};
thermal-zones {
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8660.dtsi b/arch/arm/boot/dts/qcom/qcom-msm8660.dtsi
index a7c245b9c8f9..455ba4bf1bf4 100644
--- a/arch/arm/boot/dts/qcom/qcom-msm8660.dtsi
+++ b/arch/arm/boot/dts/qcom/qcom-msm8660.dtsi
@@ -47,7 +47,7 @@
cpu-pmu {
compatible = "qcom,scorpion-mp-pmu";
- interrupts = <1 9 0x304>;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
};
clocks {
@@ -89,12 +89,11 @@
timer@2000000 {
compatible = "qcom,scss-timer", "qcom,msm-timer";
- interrupts = <1 0 0x301>,
- <1 1 0x301>,
- <1 2 0x301>;
+ interrupts = <GIC_PPI 0 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_EDGE_RISING)>,
+ <GIC_PPI 1 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_EDGE_RISING)>,
+ <GIC_PPI 2 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_EDGE_RISING)>;
reg = <0x02000000 0x100>;
- clock-frequency = <27000000>,
- <32768>;
+ clock-frequency = <27000000>;
cpu-offset = <0x40000>;
};
@@ -105,7 +104,7 @@
gpio-controller;
gpio-ranges = <&tlmm 0 0 173>;
#gpio-cells = <2>;
- interrupts = <0 16 0x4>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;
#interrupt-cells = <2>;
@@ -283,7 +282,7 @@
compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
reg = <0x19c40000 0x1000>,
<0x19c00000 0x1000>;
- interrupts = <0 195 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GSBI12_UART_CLK>, <&gcc GSBI12_H_CLK>;
clock-names = "core", "iface";
status = "disabled";
@@ -292,7 +291,7 @@
gsbi12_i2c: i2c@19c80000 {
compatible = "qcom,i2c-qup-v1.1.1";
reg = <0x19c80000 0x1000>;
- interrupts = <0 196 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GSBI12_QUP_CLK>, <&gcc GSBI12_H_CLK>;
clock-names = "core", "iface";
#address-cells = <1>;
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8926-htc-memul.dts b/arch/arm/boot/dts/qcom/qcom-msm8926-htc-memul.dts
index ed328b24335f..3037344eb240 100644
--- a/arch/arm/boot/dts/qcom/qcom-msm8926-htc-memul.dts
+++ b/arch/arm/boot/dts/qcom/qcom-msm8926-htc-memul.dts
@@ -107,7 +107,20 @@
};
unknown@fb00000 {
- reg = <0x0fb00000 0x1b00000>;
+ reg = <0x0fb00000 0x280000>;
+ no-map;
+ };
+
+ rmtfs@fd80000 {
+ compatible = "qcom,rmtfs-mem";
+ reg = <0x0fd80000 0x180000>;
+ no-map;
+
+ qcom,client-id = <1>;
+ };
+
+ unknown@ff00000 {
+ reg = <0x0ff00000 0x1700000>;
no-map;
};
};
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8926-samsung-matisselte.dts b/arch/arm/boot/dts/qcom/qcom-msm8926-samsung-matisselte.dts
new file mode 100644
index 000000000000..d0e1bc39f8ef
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/qcom-msm8926-samsung-matisselte.dts
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2022, Matti Lehtimäki <matti.lehtimaki@gmail.com>
+ * Copyright (c) 2023, Stefan Hansson <newbyte@postmarketos.org>
+ */
+
+/dts-v1/;
+
+#include "qcom-msm8226-samsung-matisse-common.dtsi"
+
+/ {
+ model = "Samsung Galaxy Tab 4 10.1 LTE";
+ compatible = "samsung,matisselte", "qcom,msm8926", "qcom,msm8226";
+ chassis-type = "tablet";
+
+ reg_tsp_3p3v: regulator-tsp-3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "tsp_3p3v";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&tlmm 32 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&tsp_en1_default_state>;
+ };
+};
+
+&tlmm {
+ tsp_en1_default_state: tsp-en1-default-state {
+ pins = "gpio32";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8960-pins.dtsi b/arch/arm/boot/dts/qcom/qcom-msm8960-pins.dtsi
new file mode 100644
index 000000000000..4fa982771288
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/qcom-msm8960-pins.dtsi
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+&msmgpio {
+ i2c3_default_state: i2c3-default-state {
+ i2c3-pins {
+ pins = "gpio16", "gpio17";
+ function = "gsbi3";
+ drive-strength = <8>;
+ bias-disable;
+ };
+ };
+
+ i2c3_sleep_state: i2c3-sleep-state {
+ i2c3-pins {
+ pins = "gpio16", "gpio17";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-bus-hold;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8960-samsung-expressatt.dts b/arch/arm/boot/dts/qcom/qcom-msm8960-samsung-expressatt.dts
index 1a5116336ff0..af6cc6393d74 100644
--- a/arch/arm/boot/dts/qcom/qcom-msm8960-samsung-expressatt.dts
+++ b/arch/arm/boot/dts/qcom/qcom-msm8960-samsung-expressatt.dts
@@ -4,6 +4,9 @@
#include "qcom-msm8960.dtsi"
#include "pm8921.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+#include <dt-bindings/input/gpio-keys.h>
/ {
model = "Samsung Galaxy Express SGH-I437";
@@ -19,6 +22,36 @@
chosen {
stdout-path = "serial0:115200n8";
};
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpio_keys_pin_a>;
+
+ key-home {
+ label = "Home";
+ gpios = <&msmgpio 40 GPIO_ACTIVE_LOW>;
+ debounce-interval = <5>;
+ linux,code = <KEY_HOMEPAGE>;
+ wakeup-event-action = <EV_ACT_ASSERTED>;
+ wakeup-source;
+ };
+
+ key-volume-up {
+ label = "Volume Up";
+ gpios = <&msmgpio 50 GPIO_ACTIVE_LOW>;
+ debounce-interval = <5>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+
+ key-volume-down {
+ label = "Volume Down";
+ gpios = <&msmgpio 81 GPIO_ACTIVE_LOW>;
+ debounce-interval = <5>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+ };
};
&gsbi5 {
@@ -52,6 +85,27 @@
status = "okay";
};
+&gsbi3 {
+ qcom,mode = <GSBI_PROT_I2C>;
+ status = "okay";
+};
+
+&gsbi3_i2c {
+ status = "okay";
+
+ // Atmel mXT224S touchscreen
+ touchscreen@4a {
+ compatible = "atmel,maxtouch";
+ reg = <0x4a>;
+ interrupt-parent = <&msmgpio>;
+ interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
+ vdda-supply = <&pm8921_lvs6>;
+ vdd-supply = <&pm8921_l17>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&touchscreen>;
+ };
+};
+
&msmgpio {
spi1_default: spi1-default-state {
mosi-pins {
@@ -83,6 +137,21 @@
bias-disable;
};
};
+
+ gpio_keys_pin_a: gpio-keys-active-state {
+ pins = "gpio40", "gpio50", "gpio81";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-disable;
+ };
+
+ touchscreen: touchscreen-int-state {
+ pins = "gpio11";
+ function = "gpio";
+ output-enable;
+ bias-disable;
+ drive-strength = <2>;
+ };
};
&pm8921 {
@@ -245,7 +314,7 @@
};
pm8921_l17: l17 {
- regulator-min-microvolt = <1800000>;
+ regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
bias-pull-down;
};
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8960.dtsi b/arch/arm/boot/dts/qcom/qcom-msm8960.dtsi
index f420740e068e..922f9e49468a 100644
--- a/arch/arm/boot/dts/qcom/qcom-msm8960.dtsi
+++ b/arch/arm/boot/dts/qcom/qcom-msm8960.dtsi
@@ -220,16 +220,24 @@
#clock-cells = <0>;
};
- saw0: regulator@2089000 {
- compatible = "qcom,saw2";
+ saw0: power-manager@2089000 {
+ compatible = "qcom,msm8960-saw2-cpu", "qcom,saw2";
reg = <0x02089000 0x1000>, <0x02009000 0x1000>;
- regulator;
+
+ saw0_vreg: regulator {
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1300000>;
+ };
};
- saw1: regulator@2099000 {
- compatible = "qcom,saw2";
+ saw1: power-manager@2099000 {
+ compatible = "qcom,msm8960-saw2-cpu", "qcom,saw2";
reg = <0x02099000 0x1000>, <0x02009000 0x1000>;
- regulator;
+
+ saw1_vreg: regulator {
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1300000>;
+ };
};
gsbi5: gsbi@16400000 {
@@ -359,5 +367,33 @@
};
};
};
+
+ gsbi3: gsbi@16200000 {
+ compatible = "qcom,gsbi-v1.0.0";
+ reg = <0x16200000 0x100>;
+ ranges;
+ cell-index = <3>;
+ clocks = <&gcc GSBI3_H_CLK>;
+ clock-names = "iface";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ status = "disabled";
+
+ gsbi3_i2c: i2c@16280000 {
+ compatible = "qcom,i2c-qup-v1.1.1";
+ reg = <0x16280000 0x1000>;
+ pinctrl-0 = <&i2c3_default_state>;
+ pinctrl-1 = <&i2c3_sleep_state>;
+ pinctrl-names = "default", "sleep";
+ interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gcc GSBI3_QUP_CLK>,
+ <&gcc GSBI3_H_CLK>;
+ clock-names = "core", "iface";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+ };
};
};
+#include "qcom-msm8960-pins.dtsi"
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom/qcom-msm8974.dtsi
index b1413983787c..5efc38d712cc 100644
--- a/arch/arm/boot/dts/qcom/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom/qcom-msm8974.dtsi
@@ -31,7 +31,7 @@
cpus {
#address-cells = <1>;
#size-cells = <0>;
- interrupts = <GIC_PPI 9 0xf04>;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
CPU0: cpu@0 {
compatible = "qcom,krait";
@@ -110,7 +110,7 @@
pmu {
compatible = "qcom,krait-pmu";
- interrupts = <GIC_PPI 7 0xf04>;
+ interrupts = <GIC_PPI 7 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
};
rpm: remoteproc {
@@ -346,10 +346,9 @@
reg = <0xf9011000 0x1000>;
};
- saw_l2: power-controller@f9012000 {
- compatible = "qcom,saw2";
+ saw_l2: power-manager@f9012000 {
+ compatible = "qcom,msm8974-saw2-v2.1-l2", "qcom,saw2";
reg = <0xf9012000 0x1000>;
- regulator;
};
watchdog@f9017000 {
@@ -424,7 +423,7 @@
reg = <0xf9088000 0x1000>, <0xf9008000 0x1000>;
};
- saw0: power-controller@f9089000 {
+ saw0: power-manager@f9089000 {
compatible = "qcom,msm8974-saw2-v2.1-cpu", "qcom,saw2";
reg = <0xf9089000 0x1000>, <0xf9009000 0x1000>;
};
@@ -434,7 +433,7 @@
reg = <0xf9098000 0x1000>, <0xf9008000 0x1000>;
};
- saw1: power-controller@f9099000 {
+ saw1: power-manager@f9099000 {
compatible = "qcom,msm8974-saw2-v2.1-cpu", "qcom,saw2";
reg = <0xf9099000 0x1000>, <0xf9009000 0x1000>;
};
@@ -444,7 +443,7 @@
reg = <0xf90a8000 0x1000>, <0xf9008000 0x1000>;
};
- saw2: power-controller@f90a9000 {
+ saw2: power-manager@f90a9000 {
compatible = "qcom,msm8974-saw2-v2.1-cpu", "qcom,saw2";
reg = <0xf90a9000 0x1000>, <0xf9009000 0x1000>;
};
@@ -454,7 +453,7 @@
reg = <0xf90b8000 0x1000>, <0xf9008000 0x1000>;
};
- saw3: power-controller@f90b9000 {
+ saw3: power-manager@f90b9000 {
compatible = "qcom,msm8974-saw2-v2.1-cpu", "qcom,saw2";
reg = <0xf90b9000 0x1000>, <0xf9009000 0x1000>;
};
@@ -538,7 +537,7 @@
status = "disabled";
compatible = "qcom,i2c-qup-v2.1.1";
reg = <0xf9923000 0x1000>;
- interrupts = <0 95 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_BLSP1_QUP1_I2C_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
clock-names = "core", "iface";
pinctrl-names = "default", "sleep";
@@ -566,7 +565,7 @@
status = "disabled";
compatible = "qcom,i2c-qup-v2.1.1";
reg = <0xf9925000 0x1000>;
- interrupts = <0 97 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_BLSP1_QUP3_I2C_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
clock-names = "core", "iface";
pinctrl-names = "default", "sleep";
@@ -666,7 +665,7 @@
status = "disabled";
compatible = "qcom,i2c-qup-v2.1.1";
reg = <0xf9968000 0x1000>;
- interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_BLSP2_QUP6_I2C_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>;
clock-names = "core", "iface";
pinctrl-names = "default", "sleep";
@@ -1234,7 +1233,7 @@
qfprom: qfprom@fc4bc000 {
compatible = "qcom,msm8974-qfprom", "qcom,qfprom";
- reg = <0xfc4bc000 0x1000>;
+ reg = <0xfc4bc000 0x2100>;
#address-cells = <1>;
#size-cells = <1>;
@@ -2403,10 +2402,10 @@
timer {
compatible = "arm,armv7-timer";
- interrupts = <GIC_PPI 2 0xf08>,
- <GIC_PPI 3 0xf08>,
- <GIC_PPI 4 0xf08>,
- <GIC_PPI 1 0xf08>;
+ interrupts = <GIC_PPI 2 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 3 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 4 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 1 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
clock-frequency = <19200000>;
};
};
diff --git a/arch/arm/boot/dts/qcom/qcom-sdx55.dtsi b/arch/arm/boot/dts/qcom/qcom-sdx55.dtsi
index 27429d0fedfb..edc9aaf828c8 100644
--- a/arch/arm/boot/dts/qcom/qcom-sdx55.dtsi
+++ b/arch/arm/boot/dts/qcom/qcom-sdx55.dtsi
@@ -580,12 +580,16 @@
<&gcc GCC_USB30_MASTER_CLK>;
assigned-clock-rates = <19200000>, <200000000>;
- interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
- <&pdc 51 IRQ_TYPE_LEVEL_HIGH>,
+ interrupts-extended = <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <&pdc 10 IRQ_TYPE_EDGE_BOTH>,
<&pdc 11 IRQ_TYPE_EDGE_BOTH>,
- <&pdc 10 IRQ_TYPE_EDGE_BOTH>;
- interrupt-names = "hs_phy_irq", "ss_phy_irq",
- "dm_hs_phy_irq", "dp_hs_phy_irq";
+ <&pdc 51 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_GDSC>;
@@ -727,57 +731,57 @@
frame@17821000 {
frame-number = <0>;
- interrupts = <GIC_SPI 7 0x4>,
- <GIC_SPI 6 0x4>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x17821000 0x1000>,
<0x17822000 0x1000>;
};
frame@17823000 {
frame-number = <1>;
- interrupts = <GIC_SPI 8 0x4>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x17823000 0x1000>;
status = "disabled";
};
frame@17824000 {
frame-number = <2>;
- interrupts = <GIC_SPI 9 0x4>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x17824000 0x1000>;
status = "disabled";
};
frame@17825000 {
frame-number = <3>;
- interrupts = <GIC_SPI 10 0x4>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x17825000 0x1000>;
status = "disabled";
};
frame@17826000 {
frame-number = <4>;
- interrupts = <GIC_SPI 11 0x4>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x17826000 0x1000>;
status = "disabled";
};
frame@17827000 {
frame-number = <5>;
- interrupts = <GIC_SPI 12 0x4>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x17827000 0x1000>;
status = "disabled";
};
frame@17828000 {
frame-number = <6>;
- interrupts = <GIC_SPI 13 0x4>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x17828000 0x1000>;
status = "disabled";
};
frame@17829000 {
frame-number = <7>;
- interrupts = <GIC_SPI 14 0x4>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x17829000 0x1000>;
status = "disabled";
};
diff --git a/arch/arm/boot/dts/qcom/qcom-sdx65.dtsi b/arch/arm/boot/dts/qcom/qcom-sdx65.dtsi
index 40591a4da6a4..a949454212e9 100644
--- a/arch/arm/boot/dts/qcom/qcom-sdx65.dtsi
+++ b/arch/arm/boot/dts/qcom/qcom-sdx65.dtsi
@@ -492,23 +492,25 @@
clocks = <&gcc GCC_USB30_SLV_AHB_CLK>,
<&gcc GCC_USB30_MASTER_CLK>,
<&gcc GCC_USB30_MSTR_AXI_CLK>,
- <&gcc GCC_USB30_MOCK_UTMI_CLK>,
- <&gcc GCC_USB30_SLEEP_CLK>;
- clock-names = "cfg_noc", "core", "iface", "mock_utmi",
- "sleep";
+ <&gcc GCC_USB30_SLEEP_CLK>,
+ <&gcc GCC_USB30_MOCK_UTMI_CLK>;
+ clock-names = "cfg_noc", "core", "iface", "sleep",
+ "mock_utmi";
assigned-clocks = <&gcc GCC_USB30_MOCK_UTMI_CLK>,
<&gcc GCC_USB30_MASTER_CLK>;
assigned-clock-rates = <19200000>, <200000000>;
- interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
- <&pdc 76 IRQ_TYPE_LEVEL_HIGH>,
+ interrupts-extended = <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <&pdc 19 IRQ_TYPE_EDGE_BOTH>,
<&pdc 18 IRQ_TYPE_EDGE_BOTH>,
- <&pdc 19 IRQ_TYPE_EDGE_BOTH>;
- interrupt-names = "hs_phy_irq",
- "ss_phy_irq",
+ <&pdc 76 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";
power-domains = <&gcc USB30_GDSC>;
@@ -667,57 +669,57 @@
frame@17821000 {
frame-number = <0>;
- interrupts = <GIC_SPI 7 0x4>,
- <GIC_SPI 6 0x4>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x17821000 0x1000>,
<0x17822000 0x1000>;
};
frame@17823000 {
frame-number = <1>;
- interrupts = <GIC_SPI 8 0x4>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x17823000 0x1000>;
status = "disabled";
};
frame@17824000 {
frame-number = <2>;
- interrupts = <GIC_SPI 9 0x4>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x17824000 0x1000>;
status = "disabled";
};
frame@17825000 {
frame-number = <3>;
- interrupts = <GIC_SPI 10 0x4>;
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x17825000 0x1000>;
status = "disabled";
};
frame@17826000 {
frame-number = <4>;
- interrupts = <GIC_SPI 11 0x4>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x17826000 0x1000>;
status = "disabled";
};
frame@17827000 {
frame-number = <5>;
- interrupts = <GIC_SPI 12 0x4>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x17827000 0x1000>;
status = "disabled";
};
frame@17828000 {
frame-number = <6>;
- interrupts = <GIC_SPI 13 0x4>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x17828000 0x1000>;
status = "disabled";
};
frame@17829000 {
frame-number = <7>;
- interrupts = <GIC_SPI 14 0x4>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x17829000 0x1000>;
status = "disabled";
};
@@ -804,10 +806,10 @@
timer {
compatible = "arm,armv7-timer";
- interrupts = <1 13 0xf08>,
- <1 12 0xf08>,
- <1 10 0xf08>,
- <1 11 0xf08>;
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 12 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
clock-frequency = <19200000>;
};
};
diff --git a/arch/arm/boot/dts/renesas/r8a73a4-ape6evm.dts b/arch/arm/boot/dts/renesas/r8a73a4-ape6evm.dts
index ed75c01dbee1..3d02f065f71c 100644
--- a/arch/arm/boot/dts/renesas/r8a73a4-ape6evm.dts
+++ b/arch/arm/boot/dts/renesas/r8a73a4-ape6evm.dts
@@ -209,6 +209,18 @@
status = "okay";
};
+&extal1_clk {
+ clock-frequency = <26000000>;
+};
+
+&extal2_clk {
+ clock-frequency = <48000000>;
+};
+
+&extalr_clk {
+ clock-frequency = <32768>;
+};
+
&pfc {
scifa0_pins: scifa0 {
groups = "scifa0_data";
diff --git a/arch/arm/boot/dts/renesas/r8a73a4.dtsi b/arch/arm/boot/dts/renesas/r8a73a4.dtsi
index c39066967053..ac654ff45d0e 100644
--- a/arch/arm/boot/dts/renesas/r8a73a4.dtsi
+++ b/arch/arm/boot/dts/renesas/r8a73a4.dtsi
@@ -450,17 +450,20 @@
extalr_clk: extalr {
compatible = "fixed-clock";
#clock-cells = <0>;
- clock-frequency = <32768>;
+ /* This value must be overridden by the board. */
+ clock-frequency = <0>;
};
extal1_clk: extal1 {
compatible = "fixed-clock";
#clock-cells = <0>;
- clock-frequency = <25000000>;
+ /* This value must be overridden by the board. */
+ clock-frequency = <0>;
};
extal2_clk: extal2 {
compatible = "fixed-clock";
#clock-cells = <0>;
- clock-frequency = <48000000>;
+ /* This value must be overridden by the board. */
+ clock-frequency = <0>;
};
fsiack_clk: fsiack {
compatible = "fixed-clock";
@@ -621,6 +624,13 @@
clock-div = <2>;
clock-mult = <1>;
};
+ cp_clk: cp {
+ compatible = "fixed-factor-clock";
+ clocks = <&main_div2_clk>;
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ };
pll0_div2_clk: pll0_div2 {
compatible = "fixed-factor-clock";
clocks = <&cpg_clocks R8A73A4_CLK_PLL0>;
@@ -686,9 +696,8 @@
mstp4_clks: mstp4_clks@e6150140 {
compatible = "renesas,r8a73a4-mstp-clocks", "renesas,cpg-mstp-clocks";
reg = <0 0xe6150140 0 4>, <0 0xe615004c 0 4>;
- clocks = <&main_div2_clk>, <&cpg_clocks R8A73A4_CLK_ZS>,
- <&main_div2_clk>,
- <&cpg_clocks R8A73A4_CLK_HP>,
+ clocks = <&cp_clk>, <&cpg_clocks R8A73A4_CLK_ZS>,
+ <&cp_clk>, <&cpg_clocks R8A73A4_CLK_HP>,
<&cpg_clocks R8A73A4_CLK_HP>;
#clock-cells = <1>;
clock-indices = <
@@ -702,7 +711,7 @@
mstp5_clks: mstp5_clks@e6150144 {
compatible = "renesas,r8a73a4-mstp-clocks", "renesas,cpg-mstp-clocks";
reg = <0 0xe6150144 0 4>, <0 0xe615003c 0 4>;
- clocks = <&extal2_clk>, <&cpg_clocks R8A73A4_CLK_HP>;
+ clocks = <&cp_clk>, <&cpg_clocks R8A73A4_CLK_HP>;
#clock-cells = <1>;
clock-indices = <
R8A73A4_CLK_THERMAL R8A73A4_CLK_IIC8
diff --git a/arch/arm/boot/dts/renesas/r8a7740.dtsi b/arch/arm/boot/dts/renesas/r8a7740.dtsi
index 55884ec701f8..d13ab86c3ab4 100644
--- a/arch/arm/boot/dts/renesas/r8a7740.dtsi
+++ b/arch/arm/boot/dts/renesas/r8a7740.dtsi
@@ -459,6 +459,7 @@
interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
clocks = <&mstp1_clks R8A7740_CLK_TMU0>;
clock-names = "fck";
power-domains = <&pd_a4r>;
@@ -474,6 +475,7 @@
interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
clocks = <&mstp1_clks R8A7740_CLK_TMU1>;
clock-names = "fck";
power-domains = <&pd_a4r>;
diff --git a/arch/arm/boot/dts/renesas/r8a7778.dtsi b/arch/arm/boot/dts/renesas/r8a7778.dtsi
index 8d4530ed2fc6..b80e832c9277 100644
--- a/arch/arm/boot/dts/renesas/r8a7778.dtsi
+++ b/arch/arm/boot/dts/renesas/r8a7778.dtsi
@@ -199,7 +199,9 @@
reg = <0xffd80000 0x30>;
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+ <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&mstp0_clks R8A7778_CLK_TMU0>;
clock-names = "fck";
power-domains = <&cpg_clocks>;
@@ -214,7 +216,9 @@
reg = <0xffd81000 0x30>;
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+ <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&mstp0_clks R8A7778_CLK_TMU1>;
clock-names = "fck";
power-domains = <&cpg_clocks>;
@@ -230,6 +234,7 @@
interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
clocks = <&mstp0_clks R8A7778_CLK_TMU2>;
clock-names = "fck";
power-domains = <&cpg_clocks>;
@@ -250,6 +255,8 @@
reg = <0xffd90000 0x1000>, /* SRU */
<0xffd91000 0x240>, /* SSI */
<0xfffe0000 0x24>; /* ADG */
+ reg-names = "sru", "ssi", "adg";
+
clocks = <&mstp3_clks R8A7778_CLK_SSI8>,
<&mstp3_clks R8A7778_CLK_SSI7>,
<&mstp3_clks R8A7778_CLK_SSI6>,
diff --git a/arch/arm/boot/dts/renesas/r8a7779.dtsi b/arch/arm/boot/dts/renesas/r8a7779.dtsi
index 7743af5e2a6f..1944703cba4f 100644
--- a/arch/arm/boot/dts/renesas/r8a7779.dtsi
+++ b/arch/arm/boot/dts/renesas/r8a7779.dtsi
@@ -402,7 +402,9 @@
reg = <0xffd80000 0x30>;
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+ <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&mstp0_clks R8A7779_CLK_TMU0>;
clock-names = "fck";
power-domains = <&sysc R8A7779_PD_ALWAYS_ON>;
@@ -417,7 +419,9 @@
reg = <0xffd81000 0x30>;
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+ <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&mstp0_clks R8A7779_CLK_TMU1>;
clock-names = "fck";
power-domains = <&sysc R8A7779_PD_ALWAYS_ON>;
@@ -433,6 +437,7 @@
interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
clocks = <&mstp0_clks R8A7779_CLK_TMU2>;
clock-names = "fck";
power-domains = <&sysc R8A7779_PD_ALWAYS_ON>;
diff --git a/arch/arm/boot/dts/rockchip/rk3128-xpi-3128.dts b/arch/arm/boot/dts/rockchip/rk3128-xpi-3128.dts
index 03a97881519a..21c1678f4e91 100644
--- a/arch/arm/boot/dts/rockchip/rk3128-xpi-3128.dts
+++ b/arch/arm/boot/dts/rockchip/rk3128-xpi-3128.dts
@@ -47,6 +47,17 @@
regulator-boot-on;
};
+ hdmi-connnector {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&hdmi_connector_out>;
+ };
+ };
+ };
+
/*
* This is a vbus-supply, which also supplies the GL852G usb hub,
* thus has to be always-on
@@ -239,6 +250,10 @@
cpu-supply = <&vdd_arm>;
};
+&display_subsystem {
+ status = "okay";
+};
+
&emmc {
bus-width = <8>;
vmmc-supply = <&vcc_io>;
@@ -328,6 +343,16 @@
status = "okay";
};
+&hdmi {
+ status = "okay";
+};
+
+&hdmi_out {
+ hdmi_connector_out: endpoint {
+ remote-endpoint = <&hdmi_connector_in>;
+ };
+};
+
&mdio {
phy0: ethernet-phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
@@ -423,3 +448,7 @@
&usb2phy_otg {
status = "okay";
};
+
+&vop {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/rockchip/rk3128.dtsi b/arch/arm/boot/dts/rockchip/rk3128.dtsi
index e2264c40b924..fb98873fd94e 100644
--- a/arch/arm/boot/dts/rockchip/rk3128.dtsi
+++ b/arch/arm/boot/dts/rockchip/rk3128.dtsi
@@ -115,6 +115,12 @@
};
};
+ display_subsystem: display-subsystem {
+ compatible = "rockchip,display-subsystem";
+ ports = <&vop_out>;
+ status = "disabled";
+ };
+
gpu_opp_table: opp-table-1 {
compatible = "operating-points-v2";
@@ -246,6 +252,32 @@
};
};
+ vop: vop@1010e000 {
+ compatible = "rockchip,rk3126-vop";
+ reg = <0x1010e000 0x300>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru ACLK_LCDC0>, <&cru DCLK_VOP>,
+ <&cru HCLK_LCDC0>;
+ clock-names = "aclk_vop", "dclk_vop",
+ "hclk_vop";
+ resets = <&cru SRST_VOP_A>, <&cru SRST_VOP_H>,
+ <&cru SRST_VOP_D>;
+ reset-names = "axi", "ahb",
+ "dclk";
+ power-domains = <&power RK3128_PD_VIO>;
+ status = "disabled";
+
+ vop_out: port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vop_out_hdmi: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&hdmi_in_vop>;
+ };
+ };
+ };
+
qos_gpu: qos@1012d000 {
compatible = "rockchip,rk3128-qos", "syscon";
reg = <0x1012d000 0x20>;
@@ -436,6 +468,34 @@
};
};
+ hdmi: hdmi@20034000 {
+ compatible = "rockchip,rk3128-inno-hdmi";
+ reg = <0x20034000 0x4000>;
+ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_HDMI>, <&cru DCLK_VOP>;
+ clock-names = "pclk", "ref";
+ pinctrl-names = "default";
+ pinctrl-0 = <&hdmii2c_xfer &hdmi_hpd &hdmi_cec>;
+ power-domains = <&power RK3128_PD_VIO>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ hdmi_in: port@0 {
+ reg = <0>;
+ hdmi_in_vop: endpoint {
+ remote-endpoint = <&vop_out_hdmi>;
+ };
+ };
+
+ hdmi_out: port@1 {
+ reg = <1>;
+ };
+ };
+ };
+
timer0: timer@20044000 {
compatible = "rockchip,rk3128-timer", "rockchip,rk3288-timer";
reg = <0x20044000 0x20>;
diff --git a/arch/arm/boot/dts/rockchip/rk322x.dtsi b/arch/arm/boot/dts/rockchip/rk322x.dtsi
index 831561fc1814..96421355c274 100644
--- a/arch/arm/boot/dts/rockchip/rk322x.dtsi
+++ b/arch/arm/boot/dts/rockchip/rk322x.dtsi
@@ -736,14 +736,20 @@
status = "disabled";
ports {
- hdmi_in: port {
- #address-cells = <1>;
- #size-cells = <0>;
- hdmi_in_vop: endpoint@0 {
- reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ hdmi_in: port@0 {
+ reg = <0>;
+
+ hdmi_in_vop: endpoint {
remote-endpoint = <&vop_out_hdmi>;
};
};
+
+ hdmi_out: port@1 {
+ reg = <1>;
+ };
};
};
diff --git a/arch/arm/boot/dts/rockchip/rk3288.dtsi b/arch/arm/boot/dts/rockchip/rk3288.dtsi
index ead343dc3df1..3f1d640afafa 100644
--- a/arch/arm/boot/dts/rockchip/rk3288.dtsi
+++ b/arch/arm/boot/dts/rockchip/rk3288.dtsi
@@ -1240,27 +1240,37 @@
compatible = "rockchip,rk3288-dw-hdmi";
reg = <0x0 0xff980000 0x0 0x20000>;
reg-io-width = <4>;
- #sound-dai-cells = <0>;
- rockchip,grf = <&grf>;
interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_HDCP>, <&cru SCLK_HDMI_CEC>;
clock-names = "iahb", "isfr", "cec";
power-domains = <&power RK3288_PD_VIO>;
+ rockchip,grf = <&grf>;
+ #sound-dai-cells = <0>;
status = "disabled";
ports {
- hdmi_in: port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ hdmi_in: port@0 {
+ reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
+
hdmi_in_vopb: endpoint@0 {
reg = <0>;
remote-endpoint = <&vopb_out_hdmi>;
};
+
hdmi_in_vopl: endpoint@1 {
reg = <1>;
remote-endpoint = <&vopl_out_hdmi>;
};
};
+
+ hdmi_out: port@1 {
+ reg = <1>;
+ };
};
};
diff --git a/arch/arm/boot/dts/rockchip/rv1126-sonoff-ihost.dtsi b/arch/arm/boot/dts/rockchip/rv1126-sonoff-ihost.dtsi
index 32b329e87a0c..9a87dc0d5f66 100644
--- a/arch/arm/boot/dts/rockchip/rv1126-sonoff-ihost.dtsi
+++ b/arch/arm/boot/dts/rockchip/rv1126-sonoff-ihost.dtsi
@@ -8,6 +8,8 @@
aliases {
ethernet0 = &gmac;
mmc0 = &emmc;
+ mmc1 = &sdio;
+ mmc2 = &sdmmc;
};
chosen {
@@ -325,7 +327,7 @@
pmuio1-supply = <&vcc3v3_sys>;
vccio1-supply = <&vcc_1v8>;
vccio2-supply = <&vccio_sd>;
- vccio3-supply = <&vcc_1v8>;
+ vccio3-supply = <&vcc3v3_sd>;
vccio4-supply = <&vcc_dovdd>;
vccio5-supply = <&vcc_1v8>;
vccio6-supply = <&vcc_1v8>;
@@ -343,14 +345,14 @@
cap-sd-highspeed;
cap-sdio-irq;
keep-power-in-suspend;
- max-frequency = <100000000>;
+ max-frequency = <50000000>;
mmc-pwrseq = <&sdio_pwrseq>;
non-removable;
pinctrl-names = "default";
pinctrl-0 = <&sdmmc1_clk &sdmmc1_cmd &sdmmc1_bus4>;
rockchip,default-sample-phase = <90>;
- sd-uhs-sdr104;
- vmmc-supply = <&vcc3v3_sys>;
+ sd-uhs-sdr50;
+ vmmc-supply = <&vcc3v3_sd>;
vqmmc-supply = <&vcc_1v8>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/samsung/exynos4412-i9300.dts b/arch/arm/boot/dts/samsung/exynos4412-i9300.dts
index 61aca5798f38..b79d456e976d 100644
--- a/arch/arm/boot/dts/samsung/exynos4412-i9300.dts
+++ b/arch/arm/boot/dts/samsung/exynos4412-i9300.dts
@@ -18,7 +18,7 @@
memory@40000000 {
device_type = "memory";
- reg = <0x40000000 0x40000000>;
+ reg = <0x40000000 0x3fc00000>;
};
};
diff --git a/arch/arm/boot/dts/samsung/exynos4412-i9305.dts b/arch/arm/boot/dts/samsung/exynos4412-i9305.dts
index 77083f1a8273..1048ef5d9bc3 100644
--- a/arch/arm/boot/dts/samsung/exynos4412-i9305.dts
+++ b/arch/arm/boot/dts/samsung/exynos4412-i9305.dts
@@ -11,7 +11,7 @@
memory@40000000 {
device_type = "memory";
- reg = <0x40000000 0x80000000>;
+ reg = <0x40000000 0x7fc00000>;
};
};
diff --git a/arch/arm/boot/dts/samsung/exynos4412-n710x.dts b/arch/arm/boot/dts/samsung/exynos4412-n710x.dts
index 0a151437fc73..eee1000dea92 100644
--- a/arch/arm/boot/dts/samsung/exynos4412-n710x.dts
+++ b/arch/arm/boot/dts/samsung/exynos4412-n710x.dts
@@ -9,7 +9,7 @@
memory@40000000 {
device_type = "memory";
- reg = <0x40000000 0x80000000>;
+ reg = <0x40000000 0x7fc00000>;
};
/* bootargs are passed in by bootloader */
diff --git a/arch/arm/boot/dts/samsung/exynos4412-p4note.dtsi b/arch/arm/boot/dts/samsung/exynos4412-p4note.dtsi
index 0b89d5682f85..28a605802733 100644
--- a/arch/arm/boot/dts/samsung/exynos4412-p4note.dtsi
+++ b/arch/arm/boot/dts/samsung/exynos4412-p4note.dtsi
@@ -23,7 +23,7 @@
memory@40000000 {
device_type = "memory";
- reg = <0x40000000 0x80000000>;
+ reg = <0x40000000 0x7fc00000>;
};
aliases {
@@ -362,6 +362,39 @@
status = "okay";
};
+&i2c_1 {
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-slave-addr = <0x10>;
+ samsung,i2c-max-bus-freq = <400000>;
+ pinctrl-0 = <&i2c1_bus>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ accelerometer@19 {
+ compatible = "st,lsm330dlc-accel";
+ reg = <0x19>;
+ interrupt-parent = <&gpx0>;
+ interrupts = <0 IRQ_TYPE_EDGE_RISING>;
+ pinctrl-0 = <&accelerometer_irq>;
+ pinctrl-names = "default";
+ mount-matrix = "1", "0", "0",
+ "0", "-1", "0",
+ "0", "0", "-1";
+ };
+
+ gyro@6b {
+ compatible = "st,lsm330dlc-gyro";
+ reg = <0x6b>;
+ interrupt-parent = <&gpx0>;
+ interrupts = <6 IRQ_TYPE_EDGE_RISING>;
+ pinctrl-0 = <&gyro_data_enable &gyro_irq>;
+ pinctrl-names = "default";
+ mount-matrix = "1", "0", "0",
+ "0", "-1", "0",
+ "0", "0", "-1";
+ };
+};
+
&i2c_3 {
samsung,i2c-sda-delay = <100>;
samsung,i2c-slave-addr = <0x10>;
@@ -844,6 +877,12 @@
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
+ gyro_data_enable: gyro-data-enable-pins {
+ samsung,pins = "gpl2-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+ };
+
uart_sel: uart-sel-pins {
samsung,pins = "gpl2-7";
samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
@@ -894,12 +933,24 @@
samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
};
+ accelerometer_irq: accelerometer-irq-pins {
+ samsung,pins = "gpx0-0";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ };
+
stmpe_adc_irq: stmpe-adc-irq-pins {
samsung,pins = "gpx0-1";
samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
};
+ gyro_irq: gyro-irq-pins {
+ samsung,pins = "gpx0-6";
+ samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ };
+
max77686_irq: max77686-irq-pins {
samsung,pins = "gpx0-7";
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
diff --git a/arch/arm/boot/dts/samsung/exynos5420-galaxy-tab-common.dtsi b/arch/arm/boot/dts/samsung/exynos5420-galaxy-tab-common.dtsi
index f525b2f5e4e0..246040967082 100644
--- a/arch/arm/boot/dts/samsung/exynos5420-galaxy-tab-common.dtsi
+++ b/arch/arm/boot/dts/samsung/exynos5420-galaxy-tab-common.dtsi
@@ -30,6 +30,7 @@
aliases {
mmc0 = &mmc_0;
+ mmc1 = &mmc_1;
mmc2 = &mmc_2;
};
@@ -39,7 +40,7 @@
memory@20000000 {
device_type = "memory";
- reg = <0x20000000 0xc0000000>;
+ reg = <0x20000000 0xbfa00000>;
};
firmware@2073000 {
@@ -87,6 +88,13 @@
linux,code = <KEY_VOLUMEDOWN>;
};
};
+
+ mmc1_pwrseq: pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&gpy7 7 GPIO_ACTIVE_LOW>;
+ clocks = <&s2mps11_osc S2MPS11_CLK_BT>;
+ clock-names = "ext_clock";
+ };
};
&cci {
@@ -620,6 +628,25 @@
vqmmc-supply = <&ldo3_reg>;
};
+/* WiFi */
+&mmc_1 {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ card-detect-delay = <200>;
+ keep-power-in-suspend;
+ mmc-pwrseq = <&mmc1_pwrseq>;
+ non-removable;
+ pinctrl-0 = <&sd1_clk>, <&sd1_cmd>, <&sd1_int>, <&sd1_bus1>,
+ <&sd1_bus4>, <&wifi_en>;
+ pinctrl-names = "default";
+ vqmmc-supply = <&ldo2_reg>;
+ samsung,dw-mshc-ciu-div = <1>;
+ samsung,dw-mshc-ddr-timing = <0 2>;
+ samsung,dw-mshc-sdr-timing = <0 1>;
+ status = "okay";
+};
+
/* External sdcard */
&mmc_2 {
status = "okay";
@@ -649,6 +676,11 @@
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
};
+
+ wifi_en: wifi-en-pins {
+ samsung,pins = "gpy7-7";
+ samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+ };
};
&rtc {
diff --git a/arch/arm/boot/dts/samsung/exynos5420-peach-pit.dts b/arch/arm/boot/dts/samsung/exynos5420-peach-pit.dts
index 4e757b6e28e1..3759742d38ca 100644
--- a/arch/arm/boot/dts/samsung/exynos5420-peach-pit.dts
+++ b/arch/arm/boot/dts/samsung/exynos5420-peach-pit.dts
@@ -967,6 +967,7 @@
reg = <0>;
spi-max-frequency = <3125000>;
google,has-vbc-nvram;
+ wakeup-source;
controller-data {
samsung,spi-feedback-delay = <1>;
diff --git a/arch/arm/boot/dts/samsung/exynos5422-odroidxu3-common.dtsi b/arch/arm/boot/dts/samsung/exynos5422-odroidxu3-common.dtsi
index b4a851aa8881..4a4c55a4beb3 100644
--- a/arch/arm/boot/dts/samsung/exynos5422-odroidxu3-common.dtsi
+++ b/arch/arm/boot/dts/samsung/exynos5422-odroidxu3-common.dtsi
@@ -55,7 +55,7 @@
thermal-zones {
cpu0_thermal: cpu0-thermal {
thermal-sensors = <&tmu_cpu0>;
- polling-delay-passive = <250>;
+ polling-delay-passive = <0>;
polling-delay = <0>;
trips {
cpu0_alert0: cpu-alert-0 {
@@ -78,12 +78,6 @@
hysteresis = <0>; /* millicelsius */
type = "critical";
};
- /*
- * Exynos542x supports only 4 trip-points
- * so for these polling mode is required.
- * Start polling at temperature level of last
- * interrupt-driven trip: cpu0_alert2
- */
cpu0_alert3: cpu-alert-3 {
temperature = <70000>; /* millicelsius */
hysteresis = <10000>; /* millicelsius */
@@ -144,7 +138,7 @@
};
cpu1_thermal: cpu1-thermal {
thermal-sensors = <&tmu_cpu1>;
- polling-delay-passive = <250>;
+ polling-delay-passive = <0>;
polling-delay = <0>;
trips {
cpu1_alert0: cpu-alert-0 {
@@ -217,7 +211,7 @@
};
cpu2_thermal: cpu2-thermal {
thermal-sensors = <&tmu_cpu2>;
- polling-delay-passive = <250>;
+ polling-delay-passive = <0>;
polling-delay = <0>;
trips {
cpu2_alert0: cpu-alert-0 {
@@ -290,7 +284,7 @@
};
cpu3_thermal: cpu3-thermal {
thermal-sensors = <&tmu_cpu3>;
- polling-delay-passive = <250>;
+ polling-delay-passive = <0>;
polling-delay = <0>;
trips {
cpu3_alert0: cpu-alert-0 {
@@ -363,7 +357,7 @@
};
gpu_thermal: gpu-thermal {
thermal-sensors = <&tmu_gpu>;
- polling-delay-passive = <250>;
+ polling-delay-passive = <0>;
polling-delay = <0>;
trips {
gpu_alert0: gpu-alert-0 {
diff --git a/arch/arm/boot/dts/samsung/exynos5800-peach-pi.dts b/arch/arm/boot/dts/samsung/exynos5800-peach-pi.dts
index f91bc4ae008e..9bbbdce9103a 100644
--- a/arch/arm/boot/dts/samsung/exynos5800-peach-pi.dts
+++ b/arch/arm/boot/dts/samsung/exynos5800-peach-pi.dts
@@ -949,6 +949,7 @@
reg = <0>;
spi-max-frequency = <3125000>;
google,has-vbc-nvram;
+ wakeup-source;
controller-data {
samsung,spi-feedback-delay = <1>;
diff --git a/arch/arm/boot/dts/st/Makefile b/arch/arm/boot/dts/st/Makefile
index 7892ad69b441..9fedd6776208 100644
--- a/arch/arm/boot/dts/st/Makefile
+++ b/arch/arm/boot/dts/st/Makefile
@@ -23,6 +23,7 @@ dtb-$(CONFIG_ARCH_STM32) += \
stm32f469-disco.dtb \
stm32f746-disco.dtb \
stm32f769-disco.dtb \
+ stm32f769-disco-mb1166-reva09.dtb \
stm32429i-eval.dtb \
stm32746g-eval.dtb \
stm32h743i-eval.dtb \
diff --git a/arch/arm/boot/dts/st/stih407-pinctrl.dtsi b/arch/arm/boot/dts/st/stih407-pinctrl.dtsi
index 7815669fe813..dcb821f567fa 100644
--- a/arch/arm/boot/dts/st/stih407-pinctrl.dtsi
+++ b/arch/arm/boot/dts/st/stih407-pinctrl.dtsi
@@ -462,14 +462,14 @@
serial0 {
pinctrl_serial0: serial0-0 {
st,pins {
- tx = <&pio17 0 ALT1 OUT>;
- rx = <&pio17 1 ALT1 IN>;
+ tx = <&pio17 0 ALT1 OUT>;
+ rx = <&pio17 1 ALT1 IN>;
};
};
pinctrl_serial0_hw_flowctrl: serial0-0_hw_flowctrl {
st,pins {
- tx = <&pio17 0 ALT1 OUT>;
- rx = <&pio17 1 ALT1 IN>;
+ tx = <&pio17 0 ALT1 OUT>;
+ rx = <&pio17 1 ALT1 IN>;
cts = <&pio17 2 ALT1 IN>;
rts = <&pio17 3 ALT1 OUT>;
};
diff --git a/arch/arm/boot/dts/st/stm32f769-disco-mb1166-reva09.dts b/arch/arm/boot/dts/st/stm32f769-disco-mb1166-reva09.dts
new file mode 100644
index 000000000000..ff7ff32371d0
--- /dev/null
+++ b/arch/arm/boot/dts/st/stm32f769-disco-mb1166-reva09.dts
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023 Dario Binacchi <dario.binacchi@amarulasolutions.com>
+ */
+
+#include "stm32f769-disco.dts"
+
+&panel0 {
+ compatible = "frida,frd400b25025", "novatek,nt35510";
+ vddi-supply = <&vcc_3v3>;
+ vdd-supply = <&vcc_3v3>;
+ /delete-property/power-supply;
+};
diff --git a/arch/arm/boot/dts/st/stm32f769-disco.dts b/arch/arm/boot/dts/st/stm32f769-disco.dts
index 5d12ae25b327..52c5baf58ab9 100644
--- a/arch/arm/boot/dts/st/stm32f769-disco.dts
+++ b/arch/arm/boot/dts/st/stm32f769-disco.dts
@@ -41,7 +41,7 @@
*/
/dts-v1/;
-#include "stm32f746.dtsi"
+#include "stm32f769.dtsi"
#include "stm32f769-pinctrl.dtsi"
#include <dt-bindings/input/input.h>
#include <dt-bindings/gpio/gpio.h>
@@ -60,6 +60,19 @@
reg = <0xC0000000 0x1000000>;
};
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ linux,dma {
+ compatible = "shared-dma-pool";
+ linux,dma-default;
+ no-map;
+ size = <0x100000>;
+ };
+ };
+
aliases {
serial0 = &usart1;
};
@@ -92,9 +105,9 @@
clock-names = "main_clk";
};
- mmc_vcard: mmc_vcard {
+ vcc_3v3: vcc-3v3 {
compatible = "regulator-fixed";
- regulator-name = "mmc_vcard";
+ regulator-name = "vcc_3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
@@ -114,6 +127,45 @@
clock-frequency = <25000000>;
};
+&dsi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ dsi_in: endpoint {
+ remote-endpoint = <&ltdc_out_dsi>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ dsi_out: endpoint {
+ remote-endpoint = <&dsi_panel_in>;
+ };
+ };
+ };
+
+ panel0: panel@0 {
+ compatible = "orisetech,otm8009a";
+ reg = <0>; /* dsi virtual channel (0..3) */
+ reset-gpios = <&gpioj 15 GPIO_ACTIVE_LOW>;
+ power-supply = <&vcc_3v3>;
+ status = "okay";
+
+ port {
+ dsi_panel_in: endpoint {
+ remote-endpoint = <&dsi_out>;
+ };
+ };
+ };
+};
+
&i2c1 {
pinctrl-0 = <&i2c1_pins_b>;
pinctrl-names = "default";
@@ -122,13 +174,23 @@
status = "okay";
};
+&ltdc {
+ status = "okay";
+
+ port {
+ ltdc_out_dsi: endpoint {
+ remote-endpoint = <&dsi_in>;
+ };
+ };
+};
+
&rtc {
status = "okay";
};
&sdio2 {
status = "okay";
- vmmc-supply = <&mmc_vcard>;
+ vmmc-supply = <&vcc_3v3>;
cd-gpios = <&gpioi 15 GPIO_ACTIVE_LOW>;
broken-cd;
pinctrl-names = "default", "opendrain", "sleep";
diff --git a/arch/arm/boot/dts/st/stm32f769.dtsi b/arch/arm/boot/dts/st/stm32f769.dtsi
new file mode 100644
index 000000000000..4e7d9032149c
--- /dev/null
+++ b/arch/arm/boot/dts/st/stm32f769.dtsi
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023 Dario Binacchi <dario.binacchi@amarulasolutions.com>
+ */
+
+#include "stm32f746.dtsi"
+
+/ {
+ soc {
+ dsi: dsi@40016c00 {
+ compatible = "st,stm32-dsi";
+ reg = <0x40016c00 0x800>;
+ clocks = <&rcc 1 CLK_F769_DSI>, <&clk_hse>;
+ clock-names = "pclk", "ref";
+ resets = <&rcc STM32F7_APB2_RESET(DSI)>;
+ reset-names = "apb";
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/st/stm32mp131.dtsi b/arch/arm/boot/dts/st/stm32mp131.dtsi
index b04d24c939c3..3900f32da797 100644
--- a/arch/arm/boot/dts/st/stm32mp131.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp131.dtsi
@@ -1315,6 +1315,13 @@
status = "disabled";
};
+ crc1: crc@58009000 {
+ compatible = "st,stm32f7-crc";
+ reg = <0x58009000 0x400>;
+ clocks = <&rcc CRC1>;
+ status = "disabled";
+ };
+
usbh_ohci: usb@5800c000 {
compatible = "generic-ohci";
reg = <0x5800c000 0x1000>;
diff --git a/arch/arm/boot/dts/st/stm32mp135f-dk.dts b/arch/arm/boot/dts/st/stm32mp135f-dk.dts
index eea740d097c7..52171214a308 100644
--- a/arch/arm/boot/dts/st/stm32mp135f-dk.dts
+++ b/arch/arm/boot/dts/st/stm32mp135f-dk.dts
@@ -93,6 +93,14 @@
};
};
+&crc1 {
+ status = "okay";
+};
+
+&cryp {
+ status = "okay";
+};
+
&i2c1 {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&i2c1_pins_a>;
diff --git a/arch/arm/boot/dts/st/stm32mp157.dtsi b/arch/arm/boot/dts/st/stm32mp157.dtsi
index 6197d878894d..97cd24227cef 100644
--- a/arch/arm/boot/dts/st/stm32mp157.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp157.dtsi
@@ -20,7 +20,7 @@
dsi: dsi@5a000000 {
compatible = "st,stm32-dsi";
reg = <0x5a000000 0x800>;
- clocks = <&rcc DSI_K>, <&clk_hse>, <&rcc DSI_PX>;
+ clocks = <&rcc DSI>, <&clk_hse>, <&rcc DSI_PX>;
clock-names = "pclk", "ref", "px_clk";
phy-dsi-supply = <&reg18>;
resets = <&rcc DSI_R>;
diff --git a/arch/arm/boot/dts/st/stm32mp157a-dk1-scmi.dts b/arch/arm/boot/dts/st/stm32mp157a-dk1-scmi.dts
index ce5937270aa1..306e1bc2a514 100644
--- a/arch/arm/boot/dts/st/stm32mp157a-dk1-scmi.dts
+++ b/arch/arm/boot/dts/st/stm32mp157a-dk1-scmi.dts
@@ -30,7 +30,7 @@
};
&dsi {
- clocks = <&rcc DSI_K>, <&scmi_clk CK_SCMI_HSE>, <&rcc DSI_PX>;
+ clocks = <&rcc DSI>, <&scmi_clk CK_SCMI_HSE>, <&rcc DSI_PX>;
};
&gpioz {
diff --git a/arch/arm/boot/dts/st/stm32mp157c-dk2-scmi.dts b/arch/arm/boot/dts/st/stm32mp157c-dk2-scmi.dts
index c20a73841c1f..956da5f26c1c 100644
--- a/arch/arm/boot/dts/st/stm32mp157c-dk2-scmi.dts
+++ b/arch/arm/boot/dts/st/stm32mp157c-dk2-scmi.dts
@@ -36,7 +36,7 @@
&dsi {
phy-dsi-supply = <&scmi_reg18>;
- clocks = <&rcc DSI_K>, <&scmi_clk CK_SCMI_HSE>, <&rcc DSI_PX>;
+ clocks = <&rcc DSI>, <&scmi_clk CK_SCMI_HSE>, <&rcc DSI_PX>;
};
&gpioz {
diff --git a/arch/arm/boot/dts/st/stm32mp157c-ed1-scmi.dts b/arch/arm/boot/dts/st/stm32mp157c-ed1-scmi.dts
index 5e2eaf57ce22..8e4b0db198c2 100644
--- a/arch/arm/boot/dts/st/stm32mp157c-ed1-scmi.dts
+++ b/arch/arm/boot/dts/st/stm32mp157c-ed1-scmi.dts
@@ -35,7 +35,7 @@
};
&dsi {
- clocks = <&rcc DSI_K>, <&scmi_clk CK_SCMI_HSE>, <&rcc DSI_PX>;
+ clocks = <&rcc DSI>, <&scmi_clk CK_SCMI_HSE>, <&rcc DSI_PX>;
};
&gpioz {
diff --git a/arch/arm/boot/dts/st/stm32mp157c-ev1-scmi.dts b/arch/arm/boot/dts/st/stm32mp157c-ev1-scmi.dts
index 3226fb945a8e..72b9cab2d990 100644
--- a/arch/arm/boot/dts/st/stm32mp157c-ev1-scmi.dts
+++ b/arch/arm/boot/dts/st/stm32mp157c-ev1-scmi.dts
@@ -36,7 +36,7 @@
&dsi {
phy-dsi-supply = <&scmi_reg18>;
- clocks = <&rcc DSI_K>, <&scmi_clk CK_SCMI_HSE>, <&rcc DSI_PX>;
+ clocks = <&rcc DSI>, <&scmi_clk CK_SCMI_HSE>, <&rcc DSI_PX>;
};
&gpioz {
diff --git a/arch/arm/boot/dts/st/stm32mp157c-lxa-tac-gen2.dts b/arch/arm/boot/dts/st/stm32mp157c-lxa-tac-gen2.dts
index 8a34d15e9005..4cc177031661 100644
--- a/arch/arm/boot/dts/st/stm32mp157c-lxa-tac-gen2.dts
+++ b/arch/arm/boot/dts/st/stm32mp157c-lxa-tac-gen2.dts
@@ -148,7 +148,7 @@
compatible = "ti,lmp92064";
reg = <0>;
- reset-gpios = <&gpioa 4 GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&gpioa 4 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
shunt-resistor-micro-ohms = <15000>;
spi-max-frequency = <5000000>;
vdd-supply = <&reg_pb_3v3>;
diff --git a/arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi b/arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi
index fc3a2386dbb9..cfaf8adde319 100644
--- a/arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi
+++ b/arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi
@@ -409,7 +409,7 @@ baseboard_eeprom: &sip_eeprom {
&spi2 {
pinctrl-names = "default";
pinctrl-0 = <&spi2_pins_c>;
- cs-gpios = <&gpiof 12 GPIO_ACTIVE_LOW>;
+ cs-gpios = <&gpiof 12 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
status = "okay";
};
@@ -471,6 +471,10 @@ baseboard_eeprom: &sip_eeprom {
interrupt-parent = <&gpioa>;
interrupts = <6 IRQ_TYPE_EDGE_RISING>;
+ /* Reduce RGMII EMI emissions by reducing drive strength */
+ microchip,hi-drive-strength-microamp = <2000>;
+ microchip,lo-drive-strength-microamp = <8000>;
+
ports {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/boot/dts/ti/davinci/da850.dtsi b/arch/arm/boot/dts/ti/davinci/da850.dtsi
index f759fdfe1b10..1d3fb5397ce3 100644
--- a/arch/arm/boot/dts/ti/davinci/da850.dtsi
+++ b/arch/arm/boot/dts/ti/davinci/da850.dtsi
@@ -536,7 +536,7 @@
reg = <0x40000 0x1000>;
cap-sd-highspeed;
cap-mmc-highspeed;
- interrupts = <16>;
+ interrupts = <16>, <17>;
dmas = <&edma0 16 0>, <&edma0 17 0>;
dma-names = "rx", "tx";
clocks = <&psc0 5>;
@@ -566,7 +566,7 @@
reg = <0x21b000 0x1000>;
cap-sd-highspeed;
cap-mmc-highspeed;
- interrupts = <72>;
+ interrupts = <72>, <73>;
dmas = <&edma1 28 0>, <&edma1 29 0>;
dma-names = "rx", "tx";
clocks = <&psc1 18>;
diff --git a/arch/arm/boot/dts/ti/keystone/keystone-clocks.dtsi b/arch/arm/boot/dts/ti/keystone/keystone-clocks.dtsi
index 0397c3423d2d..20bab90ee0ba 100644
--- a/arch/arm/boot/dts/ti/keystone/keystone-clocks.dtsi
+++ b/arch/arm/boot/dts/ti/keystone/keystone-clocks.dtsi
@@ -2,7 +2,7 @@
/*
* Device Tree Source for Keystone 2 clock tree
*
- * Copyright (C) 2013-2017 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2013-2017 Texas Instruments Incorporated - https://www.ti.com/
*/
clocks {
diff --git a/arch/arm/boot/dts/ti/keystone/keystone-k2e-clocks.dtsi b/arch/arm/boot/dts/ti/keystone/keystone-k2e-clocks.dtsi
index cf30e007fea3..74720dbf3110 100644
--- a/arch/arm/boot/dts/ti/keystone/keystone-k2e-clocks.dtsi
+++ b/arch/arm/boot/dts/ti/keystone/keystone-k2e-clocks.dtsi
@@ -2,7 +2,7 @@
/*
* Keystone 2 Edison SoC specific device tree
*
- * Copyright (C) 2014-2017 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2014-2017 Texas Instruments Incorporated - https://www.ti.com/
*/
clocks {
diff --git a/arch/arm/boot/dts/ti/keystone/keystone-k2e-evm.dts b/arch/arm/boot/dts/ti/keystone/keystone-k2e-evm.dts
index 6978d6a362f3..58099ce8d449 100644
--- a/arch/arm/boot/dts/ti/keystone/keystone-k2e-evm.dts
+++ b/arch/arm/boot/dts/ti/keystone/keystone-k2e-evm.dts
@@ -2,7 +2,7 @@
/*
* Keystone 2 Edison EVM device tree
*
- * Copyright (C) 2013-2017 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2013-2017 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/ti/keystone/keystone-k2e-netcp.dtsi b/arch/arm/boot/dts/ti/keystone/keystone-k2e-netcp.dtsi
index 5c88a90903b8..e586350ae4dc 100644
--- a/arch/arm/boot/dts/ti/keystone/keystone-k2e-netcp.dtsi
+++ b/arch/arm/boot/dts/ti/keystone/keystone-k2e-netcp.dtsi
@@ -2,7 +2,7 @@
/*
* Device Tree Source for Keystone 2 Edison Netcp driver
*
- * Copyright (C) 2015-2017 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2015-2017 Texas Instruments Incorporated - https://www.ti.com/
*/
qmss: qmss@2a40000 {
diff --git a/arch/arm/boot/dts/ti/keystone/keystone-k2e.dtsi b/arch/arm/boot/dts/ti/keystone/keystone-k2e.dtsi
index 65c32946c522..662aa33cba11 100644
--- a/arch/arm/boot/dts/ti/keystone/keystone-k2e.dtsi
+++ b/arch/arm/boot/dts/ti/keystone/keystone-k2e.dtsi
@@ -2,7 +2,7 @@
/*
* Keystone 2 Edison soc device tree
*
- * Copyright (C) 2013-2017 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2013-2017 Texas Instruments Incorporated - https://www.ti.com/
*/
#include <dt-bindings/reset/ti-syscon.h>
diff --git a/arch/arm/boot/dts/ti/keystone/keystone-k2g-evm.dts b/arch/arm/boot/dts/ti/keystone/keystone-k2g-evm.dts
index f0ddbbcdc972..bf5f67d70235 100644
--- a/arch/arm/boot/dts/ti/keystone/keystone-k2g-evm.dts
+++ b/arch/arm/boot/dts/ti/keystone/keystone-k2g-evm.dts
@@ -2,7 +2,7 @@
/*
* Device Tree Source for K2G EVM
*
- * Copyright (C) 2016-2017 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2016-2017 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/ti/keystone/keystone-k2g-ice.dts b/arch/arm/boot/dts/ti/keystone/keystone-k2g-ice.dts
index 6ceb0d5c6388..264e1e0d23c8 100644
--- a/arch/arm/boot/dts/ti/keystone/keystone-k2g-ice.dts
+++ b/arch/arm/boot/dts/ti/keystone/keystone-k2g-ice.dts
@@ -2,7 +2,7 @@
/*
* Device Tree Source for K2G Industrial Communication Engine EVM
*
- * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2017 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/ti/keystone/keystone-k2g-netcp.dtsi b/arch/arm/boot/dts/ti/keystone/keystone-k2g-netcp.dtsi
index 7109ca031617..974c8f2fa740 100644
--- a/arch/arm/boot/dts/ti/keystone/keystone-k2g-netcp.dtsi
+++ b/arch/arm/boot/dts/ti/keystone/keystone-k2g-netcp.dtsi
@@ -2,7 +2,7 @@
/*
* Device Tree Source for K2G Netcp driver
*
- * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2018 Texas Instruments Incorporated - https://www.ti.com/
*/
qmss: qmss@4020000 {
diff --git a/arch/arm/boot/dts/ti/keystone/keystone-k2g.dtsi b/arch/arm/boot/dts/ti/keystone/keystone-k2g.dtsi
index 102d59694d90..790b29ab0fa2 100644
--- a/arch/arm/boot/dts/ti/keystone/keystone-k2g.dtsi
+++ b/arch/arm/boot/dts/ti/keystone/keystone-k2g.dtsi
@@ -2,7 +2,7 @@
/*
* Device Tree Source for K2G SOC
*
- * Copyright (C) 2016-2017 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2016-2017 Texas Instruments Incorporated - https://www.ti.com/
*/
#include <dt-bindings/interrupt-controller/arm-gic.h>
diff --git a/arch/arm/boot/dts/ti/keystone/keystone-k2hk-clocks.dtsi b/arch/arm/boot/dts/ti/keystone/keystone-k2hk-clocks.dtsi
index 4ba6912176ef..3ca4722087c9 100644
--- a/arch/arm/boot/dts/ti/keystone/keystone-k2hk-clocks.dtsi
+++ b/arch/arm/boot/dts/ti/keystone/keystone-k2hk-clocks.dtsi
@@ -2,7 +2,7 @@
/*
* Keystone 2 Kepler/Hawking SoC clock nodes
*
- * Copyright (C) 2013-2017 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2013-2017 Texas Instruments Incorporated - https://www.ti.com/
*/
clocks {
diff --git a/arch/arm/boot/dts/ti/keystone/keystone-k2hk-evm.dts b/arch/arm/boot/dts/ti/keystone/keystone-k2hk-evm.dts
index 8dfb54295027..b824fad9a4ec 100644
--- a/arch/arm/boot/dts/ti/keystone/keystone-k2hk-evm.dts
+++ b/arch/arm/boot/dts/ti/keystone/keystone-k2hk-evm.dts
@@ -2,7 +2,7 @@
/*
* Keystone 2 Kepler/Hawking EVM device tree
*
- * Copyright (C) 2013-2017 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2013-2017 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/ti/keystone/keystone-k2hk-netcp.dtsi b/arch/arm/boot/dts/ti/keystone/keystone-k2hk-netcp.dtsi
index c2ee775eab6a..3ab1b5d6f9bc 100644
--- a/arch/arm/boot/dts/ti/keystone/keystone-k2hk-netcp.dtsi
+++ b/arch/arm/boot/dts/ti/keystone/keystone-k2hk-netcp.dtsi
@@ -2,7 +2,7 @@
/*
* Device Tree Source for Keystone 2 Hawking Netcp driver
*
- * Copyright (C) 2015-2017 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2015-2017 Texas Instruments Incorporated - https://www.ti.com/
*/
qmss: qmss@2a40000 {
diff --git a/arch/arm/boot/dts/ti/keystone/keystone-k2hk.dtsi b/arch/arm/boot/dts/ti/keystone/keystone-k2hk.dtsi
index da6d3934c2e8..4fdf4b30384f 100644
--- a/arch/arm/boot/dts/ti/keystone/keystone-k2hk.dtsi
+++ b/arch/arm/boot/dts/ti/keystone/keystone-k2hk.dtsi
@@ -2,7 +2,7 @@
/*
* Keystone 2 Kepler/Hawking soc specific device tree
*
- * Copyright (C) 2013-2017 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2013-2017 Texas Instruments Incorporated - https://www.ti.com/
*/
#include <dt-bindings/reset/ti-syscon.h>
diff --git a/arch/arm/boot/dts/ti/keystone/keystone-k2l-clocks.dtsi b/arch/arm/boot/dts/ti/keystone/keystone-k2l-clocks.dtsi
index 635528064dea..fcfc2fb6cc2d 100644
--- a/arch/arm/boot/dts/ti/keystone/keystone-k2l-clocks.dtsi
+++ b/arch/arm/boot/dts/ti/keystone/keystone-k2l-clocks.dtsi
@@ -2,7 +2,7 @@
/*
* Keystone 2 lamarr SoC clock nodes
*
- * Copyright (C) 2013-2017 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2013-2017 Texas Instruments Incorporated - https://www.ti.com/
*/
clocks {
diff --git a/arch/arm/boot/dts/ti/keystone/keystone-k2l-evm.dts b/arch/arm/boot/dts/ti/keystone/keystone-k2l-evm.dts
index be619e39a16f..ccda63ab12fe 100644
--- a/arch/arm/boot/dts/ti/keystone/keystone-k2l-evm.dts
+++ b/arch/arm/boot/dts/ti/keystone/keystone-k2l-evm.dts
@@ -2,7 +2,7 @@
/*
* Keystone 2 Lamarr EVM device tree
*
- * Copyright (C) 2014-2017 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2014-2017 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/ti/keystone/keystone-k2l-netcp.dtsi b/arch/arm/boot/dts/ti/keystone/keystone-k2l-netcp.dtsi
index 1afebd7458c1..b8f880faaa31 100644
--- a/arch/arm/boot/dts/ti/keystone/keystone-k2l-netcp.dtsi
+++ b/arch/arm/boot/dts/ti/keystone/keystone-k2l-netcp.dtsi
@@ -2,7 +2,7 @@
/*
* Device Tree Source for Keystone 2 Lamarr Netcp driver
*
- * Copyright (C) 2015-2017 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2015-2017 Texas Instruments Incorporated - https://www.ti.com/
*/
qmss: qmss@2a40000 {
diff --git a/arch/arm/boot/dts/ti/keystone/keystone-k2l.dtsi b/arch/arm/boot/dts/ti/keystone/keystone-k2l.dtsi
index 2062fe561642..330b437b667f 100644
--- a/arch/arm/boot/dts/ti/keystone/keystone-k2l.dtsi
+++ b/arch/arm/boot/dts/ti/keystone/keystone-k2l.dtsi
@@ -2,7 +2,7 @@
/*
* Keystone 2 Lamarr SoC specific device tree
*
- * Copyright (C) 2014-2017 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2014-2017 Texas Instruments Incorporated - https://www.ti.com/
*/
#include <dt-bindings/reset/ti-syscon.h>
diff --git a/arch/arm/boot/dts/ti/keystone/keystone.dtsi b/arch/arm/boot/dts/ti/keystone/keystone.dtsi
index 1fd04bb37a15..ff16428860a9 100644
--- a/arch/arm/boot/dts/ti/keystone/keystone.dtsi
+++ b/arch/arm/boot/dts/ti/keystone/keystone.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * Copyright (C) 2013-2017 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2013-2017 Texas Instruments Incorporated - https://www.ti.com/
*/
#include <dt-bindings/interrupt-controller/arm-gic.h>
diff --git a/arch/arm/boot/dts/ti/omap/am335x-baltos-ir2110.dts b/arch/arm/boot/dts/ti/omap/am335x-baltos-ir2110.dts
index ea5882ed7010..f82d2231dfaa 100644
--- a/arch/arm/boot/dts/ti/omap/am335x-baltos-ir2110.dts
+++ b/arch/arm/boot/dts/ti/omap/am335x-baltos-ir2110.dts
@@ -5,7 +5,7 @@
/*
* VScom OnRISC
- * http://www.vscom.de
+ * https://www.vscom.de
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/ti/omap/am335x-baltos-ir3220.dts b/arch/arm/boot/dts/ti/omap/am335x-baltos-ir3220.dts
index ea4f8dde6424..74a2191af146 100644
--- a/arch/arm/boot/dts/ti/omap/am335x-baltos-ir3220.dts
+++ b/arch/arm/boot/dts/ti/omap/am335x-baltos-ir3220.dts
@@ -5,7 +5,7 @@
/*
* VScom OnRISC
- * http://www.vscom.de
+ * https://www.vscom.de
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/ti/omap/am335x-baltos-ir5221.dts b/arch/arm/boot/dts/ti/omap/am335x-baltos-ir5221.dts
index ec914f27d11d..723ff88f76ac 100644
--- a/arch/arm/boot/dts/ti/omap/am335x-baltos-ir5221.dts
+++ b/arch/arm/boot/dts/ti/omap/am335x-baltos-ir5221.dts
@@ -5,7 +5,7 @@
/*
* VScom OnRISC
- * http://www.vscom.de
+ * https://www.vscom.de
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/ti/omap/am335x-baltos-leds.dtsi b/arch/arm/boot/dts/ti/omap/am335x-baltos-leds.dtsi
index 6a52e42b9e81..049fd8e1b40f 100644
--- a/arch/arm/boot/dts/ti/omap/am335x-baltos-leds.dtsi
+++ b/arch/arm/boot/dts/ti/omap/am335x-baltos-leds.dtsi
@@ -5,7 +5,7 @@
/*
* VScom OnRISC
- * http://www.vscom.de
+ * https://www.vscom.de
*/
/*#include "am33xx.dtsi"*/
diff --git a/arch/arm/boot/dts/ti/omap/am335x-baltos.dtsi b/arch/arm/boot/dts/ti/omap/am335x-baltos.dtsi
index c14d5b70c72f..a4beb718559c 100644
--- a/arch/arm/boot/dts/ti/omap/am335x-baltos.dtsi
+++ b/arch/arm/boot/dts/ti/omap/am335x-baltos.dtsi
@@ -5,7 +5,7 @@
/*
* VScom OnRISC
- * http://www.vscom.de
+ * https://www.vscom.de
*/
#include "am33xx.dtsi"
diff --git a/arch/arm/boot/dts/ti/omap/am335x-base0033.dts b/arch/arm/boot/dts/ti/omap/am335x-base0033.dts
index eba843e22ea1..46078af4b7a3 100644
--- a/arch/arm/boot/dts/ti/omap/am335x-base0033.dts
+++ b/arch/arm/boot/dts/ti/omap/am335x-base0033.dts
@@ -2,7 +2,7 @@
/*
* am335x-base0033.dts - Device Tree file for IGEP AQUILA EXPANSION
*
- * Copyright (C) 2013 ISEE 2007 SL - http://www.isee.biz
+ * Copyright (C) 2013 ISEE 2007 SL - https://www.isee.biz
*/
#include "am335x-igep0033.dtsi"
diff --git a/arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi b/arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi
index 96451c8a815c..2d0216840ff5 100644
--- a/arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi
+++ b/arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi
@@ -289,8 +289,8 @@
* For details, see linux-omap mailing list May 2015 thread
* [PATCH] ARM: dts: am335x-bone* enable pmic-shutdown-controller
* In particular, messages:
- * http://www.spinics.net/lists/linux-omap/msg118585.html
- * http://www.spinics.net/lists/linux-omap/msg118615.html
+ * https://www.spinics.net/lists/linux-omap/msg118585.html
+ * https://www.spinics.net/lists/linux-omap/msg118615.html
*
* You can override this later with
* &tps { /delete-property/ ti,pmic-shutdown-controller; }
diff --git a/arch/arm/boot/dts/ti/omap/am335x-cm-t335.dts b/arch/arm/boot/dts/ti/omap/am335x-cm-t335.dts
index 72990e7ffe10..06767ea164b5 100644
--- a/arch/arm/boot/dts/ti/omap/am335x-cm-t335.dts
+++ b/arch/arm/boot/dts/ti/omap/am335x-cm-t335.dts
@@ -2,7 +2,7 @@
/*
* am335x-cm-t335.dts - Device Tree file for Compulab CM-T335
*
- * Copyright (C) 2014 - 2015 CompuLab Ltd. - http://www.compulab.co.il/
+ * Copyright (C) 2014 - 2015 CompuLab Ltd. - https://www.compulab.co.il/
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/ti/omap/am335x-evmsk.dts b/arch/arm/boot/dts/ti/omap/am335x-evmsk.dts
index 57f78846c42d..eba888dcd60e 100644
--- a/arch/arm/boot/dts/ti/omap/am335x-evmsk.dts
+++ b/arch/arm/boot/dts/ti/omap/am335x-evmsk.dts
@@ -5,7 +5,7 @@
/*
* AM335x Starter Kit
- * http://www.ti.com/tool/tmdssk3358
+ * https://www.ti.com/tool/tmdssk3358
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/ti/omap/am335x-guardian.dts b/arch/arm/boot/dts/ti/omap/am335x-guardian.dts
index 205fe0ed7352..56e5d954a490 100644
--- a/arch/arm/boot/dts/ti/omap/am335x-guardian.dts
+++ b/arch/arm/boot/dts/ti/omap/am335x-guardian.dts
@@ -303,8 +303,8 @@
* For details, see linux-omap mailing list May 2015 thread
* [PATCH] ARM: dts: am335x-bone* enable pmic-shutdown-controller
* In particular, messages:
- * http://www.spinics.net/lists/linux-omap/msg118585.html
- * http://www.spinics.net/lists/linux-omap/msg118615.html
+ * https://www.spinics.net/lists/linux-omap/msg118585.html
+ * https://www.spinics.net/lists/linux-omap/msg118615.html
*
* You can override this later with
* &tps { /delete-property/ ti,pmic-shutdown-controller; }
diff --git a/arch/arm/boot/dts/ti/omap/am335x-icev2.dts b/arch/arm/boot/dts/ti/omap/am335x-icev2.dts
index 3c4228927f56..6f0f4fba043b 100644
--- a/arch/arm/boot/dts/ti/omap/am335x-icev2.dts
+++ b/arch/arm/boot/dts/ti/omap/am335x-icev2.dts
@@ -5,7 +5,7 @@
/*
* AM335x ICE V2 board
- * http://www.ti.com/tool/tmdsice3359
+ * https://www.ti.com/tool/tmdsice3359
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/ti/omap/am335x-igep0033.dtsi b/arch/arm/boot/dts/ti/omap/am335x-igep0033.dtsi
index e85c33fd42f0..c7a4a5476489 100644
--- a/arch/arm/boot/dts/ti/omap/am335x-igep0033.dtsi
+++ b/arch/arm/boot/dts/ti/omap/am335x-igep0033.dtsi
@@ -2,7 +2,7 @@
/*
* am335x-igep0033.dtsi - Device Tree file for IGEP COM AQUILA AM335x
*
- * Copyright (C) 2013 ISEE 2007 SL - http://www.isee.biz
+ * Copyright (C) 2013 ISEE 2007 SL - https://www.isee.biz
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/ti/omap/am335x-myirtech-myc.dtsi b/arch/arm/boot/dts/ti/omap/am335x-myirtech-myc.dtsi
index 584599269217..9c9359844a20 100644
--- a/arch/arm/boot/dts/ti/omap/am335x-myirtech-myc.dtsi
+++ b/arch/arm/boot/dts/ti/omap/am335x-myirtech-myc.dtsi
@@ -2,7 +2,7 @@
/* SPDX-FileCopyrightText: Alexander Shiyan, <shc_work@mail.ru> */
/* Based on code by myc_c335x.dts, MYiRtech.com */
-/* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ */
+/* Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/ */
/dts-v1/;
diff --git a/arch/arm/boot/dts/ti/omap/am335x-myirtech-myd.dts b/arch/arm/boot/dts/ti/omap/am335x-myirtech-myd.dts
index d3bba79b9358..fd91a3c01a63 100644
--- a/arch/arm/boot/dts/ti/omap/am335x-myirtech-myd.dts
+++ b/arch/arm/boot/dts/ti/omap/am335x-myirtech-myd.dts
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/* SPDX-FileCopyrightText: Alexander Shiyan, <shc_work@mail.ru> */
/* Based on code by myd_c335x.dts, MYiRtech.com */
-/* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ */
+/* Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/ */
/dts-v1/;
diff --git a/arch/arm/boot/dts/ti/omap/am335x-nano.dts b/arch/arm/boot/dts/ti/omap/am335x-nano.dts
index a475c0d91306..26b5510cb3d1 100644
--- a/arch/arm/boot/dts/ti/omap/am335x-nano.dts
+++ b/arch/arm/boot/dts/ti/omap/am335x-nano.dts
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (C) 2013 Newflow Ltd - http://www.newflow.co.uk/
+ * Copyright (C) 2013 Newflow Ltd - https://www.newflow.co.uk/
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/ti/omap/am335x-netcan-plus-1xx.dts b/arch/arm/boot/dts/ti/omap/am335x-netcan-plus-1xx.dts
index f7fad48e36ed..546e88f8fbad 100644
--- a/arch/arm/boot/dts/ti/omap/am335x-netcan-plus-1xx.dts
+++ b/arch/arm/boot/dts/ti/omap/am335x-netcan-plus-1xx.dts
@@ -5,7 +5,7 @@
/*
* VScom OnRISC
- * http://www.vscom.de
+ * https://www.vscom.de
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts b/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts
index 76751a324ad7..f66d57bb685e 100644
--- a/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts
+++ b/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts
@@ -5,7 +5,7 @@
/*
* VScom OnRISC
- * http://www.vscom.de
+ * https://www.vscom.de
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-8xx.dts b/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-8xx.dts
index 5a9fcec040fa..5fb2c629f35c 100644
--- a/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-8xx.dts
+++ b/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-8xx.dts
@@ -5,7 +5,7 @@
/*
* VScom OnRISC
- * http://www.vscom.de
+ * https://www.vscom.de
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/ti/omap/am335x-pdu001.dts b/arch/arm/boot/dts/ti/omap/am335x-pdu001.dts
index 3c9444e98c14..f38f5bff2b96 100644
--- a/arch/arm/boot/dts/ti/omap/am335x-pdu001.dts
+++ b/arch/arm/boot/dts/ti/omap/am335x-pdu001.dts
@@ -3,7 +3,7 @@
*
* EETS GmbH PDU001 board device tree file
*
- * Copyright (C) 2018 EETS GmbH - http://www.eets.ch/
+ * Copyright (C) 2018 EETS GmbH - https://www.eets.ch/
*
* Copyright (C) 2011, Texas Instruments, Incorporated - https://www.ti.com/
*
diff --git a/arch/arm/boot/dts/ti/omap/am335x-sancloud-bbe-extended-wifi.dts b/arch/arm/boot/dts/ti/omap/am335x-sancloud-bbe-extended-wifi.dts
index 5522759def26..7c9f65126c63 100644
--- a/arch/arm/boot/dts/ti/omap/am335x-sancloud-bbe-extended-wifi.dts
+++ b/arch/arm/boot/dts/ti/omap/am335x-sancloud-bbe-extended-wifi.dts
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2021 Sancloud Ltd
- * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/ti/omap/am335x-sancloud-bbe-lite.dts b/arch/arm/boot/dts/ti/omap/am335x-sancloud-bbe-lite.dts
index b1b400226d83..c6c96f6182a8 100644
--- a/arch/arm/boot/dts/ti/omap/am335x-sancloud-bbe-lite.dts
+++ b/arch/arm/boot/dts/ti/omap/am335x-sancloud-bbe-lite.dts
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/
* Copyright (C) 2021 SanCloud Ltd
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/ti/omap/am335x-sbc-t335.dts b/arch/arm/boot/dts/ti/omap/am335x-sbc-t335.dts
index 596774c84744..2841e95d9a09 100644
--- a/arch/arm/boot/dts/ti/omap/am335x-sbc-t335.dts
+++ b/arch/arm/boot/dts/ti/omap/am335x-sbc-t335.dts
@@ -2,7 +2,7 @@
/*
* am335x-sbc-t335.dts - Device Tree file for Compulab SBC-T335
*
- * Copyright (C) 2014 - 2015 CompuLab Ltd. - http://www.compulab.co.il/
+ * Copyright (C) 2014 - 2015 CompuLab Ltd. - https://www.compulab.co.il/
*/
#include "am335x-cm-t335.dts"
diff --git a/arch/arm/boot/dts/ti/omap/am335x-sl50.dts b/arch/arm/boot/dts/ti/omap/am335x-sl50.dts
index 1115c812f6c8..757ebd96b3f0 100644
--- a/arch/arm/boot/dts/ti/omap/am335x-sl50.dts
+++ b/arch/arm/boot/dts/ti/omap/am335x-sl50.dts
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (C) 2015 Toby Churchill - http://www.toby-churchill.com/
+ * Copyright (C) 2015 Toby Churchill - https://www.toby-churchill.com/
+ * url above is defunct
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/ti/omap/am33xx-clocks.dtsi b/arch/arm/boot/dts/ti/omap/am33xx-clocks.dtsi
index d34483ae1778..99b62c6b4ce8 100644
--- a/arch/arm/boot/dts/ti/omap/am33xx-clocks.dtsi
+++ b/arch/arm/boot/dts/ti/omap/am33xx-clocks.dtsi
@@ -108,30 +108,31 @@
compatible = "ti,clksel";
reg = <0x664>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- ehrpwm0_tbclk: clock-ehrpwm0-tbclk {
+ ehrpwm0_tbclk: clock-ehrpwm0-tbclk@0 {
+ reg = <0>;
#clock-cells = <0>;
compatible = "ti,gate-clock";
clock-output-names = "ehrpwm0_tbclk";
clocks = <&l4ls_gclk>;
- ti,bit-shift = <0>;
};
- ehrpwm1_tbclk: clock-ehrpwm1-tbclk {
+ ehrpwm1_tbclk: clock-ehrpwm1-tbclk@1 {
+ reg = <1>;
#clock-cells = <0>;
compatible = "ti,gate-clock";
clock-output-names = "ehrpwm1_tbclk";
clocks = <&l4ls_gclk>;
- ti,bit-shift = <1>;
};
- ehrpwm2_tbclk: clock-ehrpwm2-tbclk {
+ ehrpwm2_tbclk: clock-ehrpwm2-tbclk@2 {
+ reg = <2>;
#clock-cells = <0>;
compatible = "ti,gate-clock";
clock-output-names = "ehrpwm2_tbclk";
clocks = <&l4ls_gclk>;
- ti,bit-shift = <2>;
};
};
};
@@ -566,17 +567,19 @@
compatible = "ti,clksel";
reg = <0x52c>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- gfx_fclk_clksel_ck: clock-gfx-fclk-clksel {
+ gfx_fclk_clksel_ck: clock-gfx-fclk-clksel@1 {
+ reg = <1>;
#clock-cells = <0>;
compatible = "ti,mux-clock";
clock-output-names = "gfx_fclk_clksel_ck";
clocks = <&dpll_core_m4_ck>, <&dpll_per_m2_ck>;
- ti,bit-shift = <1>;
};
- gfx_fck_div_ck: clock-gfx-fck-div {
+ gfx_fck_div_ck: clock-gfx-fck-div@0 {
+ reg = <0>;
#clock-cells = <0>;
compatible = "ti,divider-clock";
clock-output-names = "gfx_fck_div_ck";
@@ -589,30 +592,32 @@
compatible = "ti,clksel";
reg = <0x700>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- sysclkout_pre_ck: clock-sysclkout-pre {
+ sysclkout_pre_ck: clock-sysclkout-pre@0 {
+ reg = <0>;
#clock-cells = <0>;
compatible = "ti,mux-clock";
clock-output-names = "sysclkout_pre_ck";
clocks = <&clk_32768_ck>, <&l3_gclk>, <&dpll_ddr_m2_ck>, <&dpll_per_m2_ck>, <&lcd_gclk>;
};
- clkout2_div_ck: clock-clkout2-div {
+ clkout2_div_ck: clock-clkout2-div@3 {
+ reg = <3>;
#clock-cells = <0>;
compatible = "ti,divider-clock";
clock-output-names = "clkout2_div_ck";
clocks = <&sysclkout_pre_ck>;
- ti,bit-shift = <3>;
ti,max-div = <8>;
};
- clkout2_ck: clock-clkout2 {
+ clkout2_ck: clock-clkout2@7 {
+ reg = <7>;
#clock-cells = <0>;
compatible = "ti,gate-clock";
clock-output-names = "clkout2_ck";
clocks = <&clkout2_div_ck>;
- ti,bit-shift = <7>;
};
};
};
diff --git a/arch/arm/boot/dts/ti/omap/am33xx.dtsi b/arch/arm/boot/dts/ti/omap/am33xx.dtsi
index 5b9e01a8aa5d..989d5a6edeed 100644
--- a/arch/arm/boot/dts/ti/omap/am33xx.dtsi
+++ b/arch/arm/boot/dts/ti/omap/am33xx.dtsi
@@ -640,10 +640,11 @@
#size-cells = <1>;
ranges = <0 0x56000000 0x1000000>;
- /*
- * Closed source PowerVR driver, no child device
- * binding or driver in mainline
- */
+ gpu@0 {
+ compatible = "ti,omap3630-gpu", "img,powervr-sgx530";
+ reg = <0x0 0x10000>; /* 64kB */
+ interrupts = <37>;
+ };
};
};
};
diff --git a/arch/arm/boot/dts/ti/omap/am3517.dtsi b/arch/arm/boot/dts/ti/omap/am3517.dtsi
index 77e58e686fb1..19aad715dff7 100644
--- a/arch/arm/boot/dts/ti/omap/am3517.dtsi
+++ b/arch/arm/boot/dts/ti/omap/am3517.dtsi
@@ -162,12 +162,13 @@
clock-names = "fck", "ick";
#address-cells = <1>;
#size-cells = <1>;
- ranges = <0 0x50000000 0x4000>;
+ ranges = <0 0x50000000 0x10000>;
- /*
- * Closed source PowerVR driver, no child device
- * binding or driver in mainline
- */
+ gpu@0 {
+ compatible = "ti,omap3430-gpu", "img,powervr-sgx530";
+ reg = <0x0 0x10000>; /* 64kB */
+ interrupts = <21>;
+ };
};
};
};
diff --git a/arch/arm/boot/dts/ti/omap/am35xx-clocks.dtsi b/arch/arm/boot/dts/ti/omap/am35xx-clocks.dtsi
index 0ee7afaa0e8e..b521139e6f51 100644
--- a/arch/arm/boot/dts/ti/omap/am35xx-clocks.dtsi
+++ b/arch/arm/boot/dts/ti/omap/am35xx-clocks.dtsi
@@ -66,22 +66,23 @@
compatible = "ti,clksel";
reg = <0xa10>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- ipss_ick: clock-ipss-ick {
+ ipss_ick: clock-ipss-ick@4 {
+ reg = <4>;
#clock-cells = <0>;
compatible = "ti,am35xx-interface-clock";
clock-output-names = "ipss_ick";
clocks = <&core_l3_ick>;
- ti,bit-shift = <4>;
};
- uart4_ick_am35xx: clock-uart4-ick-am35xx {
+ uart4_ick_am35xx: clock-uart4-ick-am35xx@23 {
+ reg = <23>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "uart4_ick_am35xx";
clocks = <&core_l4_ick>;
- ti,bit-shift = <23>;
};
};
@@ -101,14 +102,15 @@
compatible = "ti,clksel";
reg = <0xa00>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- uart4_fck_am35xx: clock-uart4-fck-am35xx {
+ uart4_fck_am35xx: clock-uart4-fck-am35xx@23 {
+ reg = <23>;
#clock-cells = <0>;
compatible = "ti,wait-gate-clock";
clock-output-names = "uart4_fck_am35xx";
clocks = <&core_48m_fck>;
- ti,bit-shift = <23>;
};
};
};
diff --git a/arch/arm/boot/dts/ti/omap/am4372.dtsi b/arch/arm/boot/dts/ti/omap/am4372.dtsi
index 9d2c064534f7..5fd1b380ece6 100644
--- a/arch/arm/boot/dts/ti/omap/am4372.dtsi
+++ b/arch/arm/boot/dts/ti/omap/am4372.dtsi
@@ -719,6 +719,12 @@
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x56000000 0x1000000>;
+
+ gpu@0 {
+ compatible = "ti,omap3630-gpu", "img,powervr-sgx530";
+ reg = <0x0 0x10000>; /* 64kB */
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ };
};
};
};
diff --git a/arch/arm/boot/dts/ti/omap/am437x-cm-t43.dts b/arch/arm/boot/dts/ti/omap/am437x-cm-t43.dts
index 9ec75d03eaff..172516a7667e 100644
--- a/arch/arm/boot/dts/ti/omap/am437x-cm-t43.dts
+++ b/arch/arm/boot/dts/ti/omap/am437x-cm-t43.dts
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (C) 2015 CompuLab, Ltd. - http://www.compulab.co.il/
+ * Copyright (C) 2015 CompuLab, Ltd. - https://www.compulab.co.il/
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/ti/omap/am437x-sbc-t43.dts b/arch/arm/boot/dts/ti/omap/am437x-sbc-t43.dts
index 34a5407bee15..5ec57dcb0659 100644
--- a/arch/arm/boot/dts/ti/omap/am437x-sbc-t43.dts
+++ b/arch/arm/boot/dts/ti/omap/am437x-sbc-t43.dts
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (C) 2015 CompuLab, Ltd. - http://www.compulab.co.il/
+ * Copyright (C) 2015 CompuLab, Ltd. - https://www.compulab.co.il/
*/
#include "am437x-cm-t43.dts"
diff --git a/arch/arm/boot/dts/ti/omap/am5729-beagleboneai.dts b/arch/arm/boot/dts/ti/omap/am5729-beagleboneai.dts
index 3e834fc7e370..eb1ec85aba28 100644
--- a/arch/arm/boot/dts/ti/omap/am5729-beagleboneai.dts
+++ b/arch/arm/boot/dts/ti/omap/am5729-beagleboneai.dts
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * Copyright (C) 2014-2019 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2014-2019 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/ti/omap/am57xx-cl-som-am57x.dts b/arch/arm/boot/dts/ti/omap/am57xx-cl-som-am57x.dts
index 4fd831ff206f..d6e3152b02f7 100644
--- a/arch/arm/boot/dts/ti/omap/am57xx-cl-som-am57x.dts
+++ b/arch/arm/boot/dts/ti/omap/am57xx-cl-som-am57x.dts
@@ -2,7 +2,7 @@
/*
* Support for CompuLab CL-SOM-AM57x System-on-Module
*
- * Copyright (C) 2015 CompuLab Ltd. - http://www.compulab.co.il/
+ * Copyright (C) 2015 CompuLab Ltd. - https://www.compulab.co.il/
* Author: Dmitry Lifshitz <lifshitz@compulab.co.il>
*/
diff --git a/arch/arm/boot/dts/ti/omap/am57xx-sbc-am57x.dts b/arch/arm/boot/dts/ti/omap/am57xx-sbc-am57x.dts
index 363115afb0a4..64675f4edb60 100644
--- a/arch/arm/boot/dts/ti/omap/am57xx-sbc-am57x.dts
+++ b/arch/arm/boot/dts/ti/omap/am57xx-sbc-am57x.dts
@@ -2,7 +2,7 @@
/*
* Support for CompuLab SBC-AM57x single board computer
*
- * Copyright (C) 2015 CompuLab Ltd. - http://www.compulab.co.il/
+ * Copyright (C) 2015 CompuLab Ltd. - https://www.compulab.co.il/
* Author: Dmitry Lifshitz <lifshitz@compulab.co.il>
*/
diff --git a/arch/arm/boot/dts/ti/omap/compulab-sb-som.dtsi b/arch/arm/boot/dts/ti/omap/compulab-sb-som.dtsi
index f5e6216718d8..8a8fa1b2b26c 100644
--- a/arch/arm/boot/dts/ti/omap/compulab-sb-som.dtsi
+++ b/arch/arm/boot/dts/ti/omap/compulab-sb-som.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (C) 2015 CompuLab, Ltd. - http://www.compulab.co.il/
+ * Copyright (C) 2015 CompuLab, Ltd. - https://www.compulab.co.il/
*/
/ {
diff --git a/arch/arm/boot/dts/ti/omap/dra7-l4.dtsi b/arch/arm/boot/dts/ti/omap/dra7-l4.dtsi
index 5733e3a4ea8e..6e67d99832ac 100644
--- a/arch/arm/boot/dts/ti/omap/dra7-l4.dtsi
+++ b/arch/arm/boot/dts/ti/omap/dra7-l4.dtsi
@@ -80,7 +80,7 @@
};
};
- phy_gmii_sel: phy-gmii-sel {
+ phy_gmii_sel: phy-gmii-sel@554 {
compatible = "ti,dra7xx-phy-gmii-sel";
reg = <0x554 0x4>;
#phy-cells = <1>;
diff --git a/arch/arm/boot/dts/ti/omap/dra7.dtsi b/arch/arm/boot/dts/ti/omap/dra7.dtsi
index 6509c742fb58..164fa88c459e 100644
--- a/arch/arm/boot/dts/ti/omap/dra7.dtsi
+++ b/arch/arm/boot/dts/ti/omap/dra7.dtsi
@@ -638,7 +638,7 @@
};
};
- abb_mpu: regulator-abb-mpu {
+ abb_mpu: regulator-abb-mpu@4ae07ddc {
compatible = "ti,abb-v3";
regulator-name = "abb_mpu";
#address-cells = <0>;
@@ -671,7 +671,7 @@
>;
};
- abb_ivahd: regulator-abb-ivahd {
+ abb_ivahd: regulator-abb-ivahd@4ae07e34 {
compatible = "ti,abb-v3";
regulator-name = "abb_ivahd";
#address-cells = <0>;
@@ -704,7 +704,7 @@
>;
};
- abb_dspeve: regulator-abb-dspeve {
+ abb_dspeve: regulator-abb-dspeve@4ae07e30 {
compatible = "ti,abb-v3";
regulator-name = "abb_dspeve";
#address-cells = <0>;
@@ -737,7 +737,7 @@
>;
};
- abb_gpu: regulator-abb-gpu {
+ abb_gpu: regulator-abb-gpu@4ae07de4 {
compatible = "ti,abb-v3";
regulator-name = "abb_gpu";
#address-cells = <0>;
@@ -850,12 +850,19 @@
<SYSC_IDLE_SMART>;
ti,sysc-sidle = <SYSC_IDLE_FORCE>,
<SYSC_IDLE_NO>,
- <SYSC_IDLE_SMART>;
+ <SYSC_IDLE_SMART>,
+ <SYSC_IDLE_SMART_WKUP>;
clocks = <&gpu_clkctrl DRA7_GPU_CLKCTRL 0>;
clock-names = "fck";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x56000000 0x2000000>;
+
+ gpu@0 {
+ compatible = "ti,am5728-gpu", "img,powervr-sgx544";
+ reg = <0x0 0x10000>; /* 64kB */
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ };
};
crossbar_mpu: crossbar@4a002a48 {
diff --git a/arch/arm/boot/dts/ti/omap/dra74x-p.dtsi b/arch/arm/boot/dts/ti/omap/dra74x-p.dtsi
index 006189dad7a7..bb5239ae164d 100644
--- a/arch/arm/boot/dts/ti/omap/dra74x-p.dtsi
+++ b/arch/arm/boot/dts/ti/omap/dra74x-p.dtsi
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2017 Texas Instruments Incorporated - https://www.ti.com/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/arch/arm/boot/dts/ti/omap/dra7xx-clocks.dtsi b/arch/arm/boot/dts/ti/omap/dra7xx-clocks.dtsi
index 04a7a6d1d529..06466d36caa9 100644
--- a/arch/arm/boot/dts/ti/omap/dra7xx-clocks.dtsi
+++ b/arch/arm/boot/dts/ti/omap/dra7xx-clocks.dtsi
@@ -1685,7 +1685,7 @@
reg = <0x0558>;
};
- sys_32k_ck: clock-sys-32k {
+ sys_32k_ck: clock-sys-32k@6c4 {
#clock-cells = <0>;
compatible = "ti,mux-clock";
clock-output-names = "sys_32k_ck";
diff --git a/arch/arm/boot/dts/ti/omap/omap3430es1-clocks.dtsi b/arch/arm/boot/dts/ti/omap/omap3430es1-clocks.dtsi
index 24adfac26be0..6e754d265f18 100644
--- a/arch/arm/boot/dts/ti/omap/omap3430es1-clocks.dtsi
+++ b/arch/arm/boot/dts/ti/omap/omap3430es1-clocks.dtsi
@@ -50,30 +50,31 @@
compatible = "ti,clksel";
reg = <0xa00>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- d2d_26m_fck: clock-d2d-26m-fck {
+ d2d_26m_fck: clock-d2d-26m-fck@3 {
+ reg = <3>;
#clock-cells = <0>;
compatible = "ti,wait-gate-clock";
clock-output-names = "d2d_26m_fck";
clocks = <&sys_ck>;
- ti,bit-shift = <3>;
};
- fshostusb_fck: clock-fshostusb-fck {
+ fshostusb_fck: clock-fshostusb-fck@5 {
+ reg = <5>;
#clock-cells = <0>;
compatible = "ti,wait-gate-clock";
clock-output-names = "fshostusb_fck";
clocks = <&core_48m_fck>;
- ti,bit-shift = <5>;
};
- ssi_ssr_gate_fck_3430es1: clock-ssi-ssr-gate-fck-3430es1 {
+ ssi_ssr_gate_fck_3430es1: clock-ssi-ssr-gate-fck-3430es1@0 {
+ reg = <0>;
#clock-cells = <0>;
compatible = "ti,composite-no-wait-gate-clock";
clock-output-names = "ssi_ssr_gate_fck_3430es1";
clocks = <&corex2_fck>;
- ti,bit-shift = <0>;
};
};
@@ -81,23 +82,24 @@
compatible = "ti,clksel";
reg = <0xa40>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- ssi_ssr_div_fck_3430es1: clock-ssi-ssr-div-fck-3430es1 {
+ ssi_ssr_div_fck_3430es1: clock-ssi-ssr-div-fck-3430es1@8 {
+ reg = <8>;
#clock-cells = <0>;
compatible = "ti,composite-divider-clock";
clock-output-names = "ssi_ssr_div_fck_3430es1";
clocks = <&corex2_fck>;
- ti,bit-shift = <8>;
ti,dividers = <0>, <1>, <2>, <3>, <4>, <0>, <6>, <0>, <8>;
};
- usb_l4_div_ick: clock-usb-l4-div-ick {
+ usb_l4_div_ick: clock-usb-l4-div-ick@4 {
+ reg = <4>;
#clock-cells = <0>;
compatible = "ti,composite-divider-clock";
clock-output-names = "usb_l4_div_ick";
clocks = <&l4_ick>;
- ti,bit-shift = <4>;
ti,max-div = <1>;
ti,index-starts-at-one;
};
@@ -121,38 +123,39 @@
compatible = "ti,clksel";
reg = <0xa10>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- hsotgusb_ick_3430es1: clock-hsotgusb-ick-3430es1 {
+ hsotgusb_ick_3430es1: clock-hsotgusb-ick-3430es1@4 {
+ reg = <4>;
#clock-cells = <0>;
compatible = "ti,omap3-no-wait-interface-clock";
clock-output-names = "hsotgusb_ick_3430es1";
clocks = <&core_l3_ick>;
- ti,bit-shift = <4>;
};
- fac_ick: clock-fac-ick {
+ fac_ick: clock-fac-ick@8 {
+ reg = <8>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "fac_ick";
clocks = <&core_l4_ick>;
- ti,bit-shift = <8>;
};
- ssi_ick: clock-ssi-ick-3430es1 {
+ ssi_ick: clock-ssi-ick-3430es1@0 {
+ reg = <0>;
#clock-cells = <0>;
compatible = "ti,omap3-no-wait-interface-clock";
clock-output-names = "ssi_ick_3430es1";
clocks = <&ssi_l4_ick>;
- ti,bit-shift = <0>;
};
- usb_l4_gate_ick: clock-usb-l4-gate-ick {
+ usb_l4_gate_ick: clock-usb-l4-gate-ick@5 {
+ reg = <5>;
#clock-cells = <0>;
compatible = "ti,composite-interface-clock";
clock-output-names = "usb_l4_gate_ick";
clocks = <&l4_ick>;
- ti,bit-shift = <5>;
};
};
@@ -174,14 +177,15 @@
compatible = "ti,clksel";
reg = <0xe00>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- dss1_alwon_fck: clock-dss1-alwon-fck-3430es1 {
+ dss1_alwon_fck: clock-dss1-alwon-fck-3430es1@0 {
+ reg = <0>;
#clock-cells = <0>;
compatible = "ti,gate-clock";
clock-output-names = "dss1_alwon_fck_3430es1";
clocks = <&dpll4_m4x2_ck>;
- ti,bit-shift = <0>;
ti,set-rate-parent;
};
};
diff --git a/arch/arm/boot/dts/ti/omap/omap34xx-omap36xx-clocks.dtsi b/arch/arm/boot/dts/ti/omap/omap34xx-omap36xx-clocks.dtsi
index 8374532f20e2..ca6372711baf 100644
--- a/arch/arm/boot/dts/ti/omap/omap34xx-omap36xx-clocks.dtsi
+++ b/arch/arm/boot/dts/ti/omap/omap34xx-omap36xx-clocks.dtsi
@@ -17,46 +17,47 @@
compatible = "ti,clksel";
reg = <0xa14>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- aes1_ick: clock-aes1-ick {
+ aes1_ick: clock-aes1-ick@3 {
+ reg = <3>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "aes1_ick";
clocks = <&security_l4_ick2>;
- ti,bit-shift = <3>;
};
- rng_ick: clock-rng-ick {
+ rng_ick: clock-rng-ick@2 {
+ reg = <2>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "rng_ick";
clocks = <&security_l4_ick2>;
- ti,bit-shift = <2>;
};
- sha11_ick: clock-sha11-ick {
+ sha11_ick: clock-sha11-ick@1 {
+ reg = <1>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "sha11_ick";
clocks = <&security_l4_ick2>;
- ti,bit-shift = <1>;
};
- des1_ick: clock-des1-ick {
+ des1_ick: clock-des1-ick@0 {
+ reg = <0>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "des1_ick";
clocks = <&security_l4_ick2>;
- ti,bit-shift = <0>;
};
- pka_ick: clock-pka-ick {
+ pka_ick: clock-pka-ick@4 {
+ reg = <4>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "pka_ick";
clocks = <&security_l3_ick>;
- ti,bit-shift = <4>;
};
};
@@ -65,23 +66,24 @@
compatible = "ti,clksel";
reg = <0xf00>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- cam_mclk: clock-cam-mclk {
+ cam_mclk: clock-cam-mclk@0 {
+ reg = <0>;
#clock-cells = <0>;
compatible = "ti,gate-clock";
clock-output-names = "cam_mclk";
clocks = <&dpll4_m5x2_ck>;
- ti,bit-shift = <0>;
ti,set-rate-parent;
};
- csi2_96m_fck: clock-csi2-96m-fck {
+ csi2_96m_fck: clock-csi2-96m-fck@1 {
+ reg = <1>;
#clock-cells = <0>;
compatible = "ti,gate-clock";
clock-output-names = "csi2_96m_fck";
clocks = <&core_96m_fck>;
- ti,bit-shift = <1>;
};
};
@@ -105,46 +107,47 @@
compatible = "ti,clksel";
reg = <0xa10>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- icr_ick: clock-icr-ick {
+ icr_ick: clock-icr-ick@29 {
+ reg = <29>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "icr_ick";
clocks = <&core_l4_ick>;
- ti,bit-shift = <29>;
};
- des2_ick: clock-des2-ick {
+ des2_ick: clock-des2-ick@26 {
+ reg = <26>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "des2_ick";
clocks = <&core_l4_ick>;
- ti,bit-shift = <26>;
};
- mspro_ick: clock-mspro-ick {
+ mspro_ick: clock-mspro-ick@23 {
+ reg = <23>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "mspro_ick";
clocks = <&core_l4_ick>;
- ti,bit-shift = <23>;
};
- mailboxes_ick: clock-mailboxes-ick {
+ mailboxes_ick: clock-mailboxes-ick@7 {
+ reg = <7>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "mailboxes_ick";
clocks = <&core_l4_ick>;
- ti,bit-shift = <7>;
};
- sad2d_ick: clock-sad2d-ick {
+ sad2d_ick: clock-sad2d-ick@3 {
+ reg = <3>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "sad2d_ick";
clocks = <&l3_ick>;
- ti,bit-shift = <3>;
};
};
@@ -160,22 +163,23 @@
compatible = "ti,clksel";
reg = <0xc00>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- sr1_fck: clock-sr1-fck {
+ sr1_fck: clock-sr1-fck@6 {
+ reg = <6>;
#clock-cells = <0>;
compatible = "ti,wait-gate-clock";
clock-output-names = "sr1_fck";
clocks = <&sys_ck>;
- ti,bit-shift = <6>;
};
- sr2_fck: clock-sr2-fck {
+ sr2_fck: clock-sr2-fck@7 {
+ reg = <7>;
#clock-cells = <0>;
compatible = "ti,wait-gate-clock";
clock-output-names = "sr2_fck";
clocks = <&sys_ck>;
- ti,bit-shift = <7>;
};
};
@@ -228,22 +232,23 @@
compatible = "ti,clksel";
reg = <0xa00>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- modem_fck: clock-modem-fck {
+ modem_fck: clock-modem-fck@31 {
+ reg = <31>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "modem_fck";
clocks = <&sys_ck>;
- ti,bit-shift = <31>;
};
- mspro_fck: clock-mspro-fck {
+ mspro_fck: clock-mspro-fck@23 {
+ reg = <23>;
#clock-cells = <0>;
compatible = "ti,wait-gate-clock";
clock-output-names = "mspro_fck";
clocks = <&core_96m_fck>;
- ti,bit-shift = <23>;
};
};
@@ -252,14 +257,15 @@
compatible = "ti,clksel";
reg = <0xa18>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #ssize-cells = <0>;
- mad2d_ick: clock-mad2d-ick {
+ mad2d_ick: clock-mad2d-ick@3 {
+ reg = <3>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "mad2d_ick";
clocks = <&l3_ick>;
- ti,bit-shift = <3>;
};
};
diff --git a/arch/arm/boot/dts/ti/omap/omap34xx.dtsi b/arch/arm/boot/dts/ti/omap/omap34xx.dtsi
index fc7233ac183a..acdd0ee34421 100644
--- a/arch/arm/boot/dts/ti/omap/omap34xx.dtsi
+++ b/arch/arm/boot/dts/ti/omap/omap34xx.dtsi
@@ -164,12 +164,13 @@
clock-names = "fck", "ick";
#address-cells = <1>;
#size-cells = <1>;
- ranges = <0 0x50000000 0x4000>;
+ ranges = <0 0x50000000 0x10000>;
- /*
- * Closed source PowerVR driver, no child device
- * binding or driver in mainline
- */
+ gpu@0 {
+ compatible = "ti,omap3430-gpu", "img,powervr-sgx530";
+ reg = <0x0 0x10000>; /* 64kB */
+ interrupts = <21>;
+ };
};
};
diff --git a/arch/arm/boot/dts/ti/omap/omap36xx-am35xx-omap3430es2plus-clocks.dtsi b/arch/arm/boot/dts/ti/omap/omap36xx-am35xx-omap3430es2plus-clocks.dtsi
index dcc5cfcd1fe6..656cf80f878a 100644
--- a/arch/arm/boot/dts/ti/omap/omap36xx-am35xx-omap3430es2plus-clocks.dtsi
+++ b/arch/arm/boot/dts/ti/omap/omap36xx-am35xx-omap3430es2plus-clocks.dtsi
@@ -138,14 +138,15 @@
compatible = "ti,clksel";
reg = <0xa18>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- usbtll_ick: clock-usbtll-ick {
+ usbtll_ick: clock-usbtll-ick@2 {
+ reg = <2>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "usbtll_ick";
clocks = <&core_l4_ick>;
- ti,bit-shift = <2>;
};
};
@@ -153,14 +154,15 @@
compatible = "ti,clksel";
reg = <0xa10>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- mmchs3_ick: clock-mmchs3-ick {
+ mmchs3_ick: clock-mmchs3-ick@30 {
+ reg = <30>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "mmchs3_ick";
clocks = <&core_l4_ick>;
- ti,bit-shift = <30>;
};
};
@@ -168,14 +170,15 @@
compatible = "ti,clksel";
reg = <0xa00>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- mmchs3_fck: clock-mmchs3-fck {
+ mmchs3_fck: clock-mmchs3-fck@30 {
+ reg = <30>;
#clock-cells = <0>;
compatible = "ti,wait-gate-clock";
clock-output-names = "mmchs3_fck";
clocks = <&core_96m_fck>;
- ti,bit-shift = <30>;
};
};
@@ -183,14 +186,15 @@
compatible = "ti,clksel";
reg = <0xe00>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- dss1_alwon_fck: clock-dss1-alwon-fck-3430es2 {
+ dss1_alwon_fck: clock-dss1-alwon-fck-3430es2@0 {
+ reg = <0>;
#clock-cells = <0>;
compatible = "ti,dss-gate-clock";
clock-output-names = "dss1_alwon_fck_3430es2";
clocks = <&dpll4_m4x2_ck>;
- ti,bit-shift = <0>;
ti,set-rate-parent;
};
};
diff --git a/arch/arm/boot/dts/ti/omap/omap36xx-clocks.dtsi b/arch/arm/boot/dts/ti/omap/omap36xx-clocks.dtsi
index c5fdb2bd765d..1e90f2b1ef8b 100644
--- a/arch/arm/boot/dts/ti/omap/omap36xx-clocks.dtsi
+++ b/arch/arm/boot/dts/ti/omap/omap36xx-clocks.dtsi
@@ -62,14 +62,15 @@
compatible = "ti,clksel";
reg = <0x1000>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- uart4_fck: clock-uart4-fck {
+ uart4_fck: clock-uart4-fck@18 {
+ reg = <18>;
#clock-cells = <0>;
compatible = "ti,wait-gate-clock";
clock-output-names = "uart4_fck";
clocks = <&per_48m_fck>;
- ti,bit-shift = <18>;
};
};
};
diff --git a/arch/arm/boot/dts/ti/omap/omap36xx-omap3430es2plus-clocks.dtsi b/arch/arm/boot/dts/ti/omap/omap36xx-omap3430es2plus-clocks.dtsi
index c94eb86d3da7..798acb839db4 100644
--- a/arch/arm/boot/dts/ti/omap/omap36xx-omap3430es2plus-clocks.dtsi
+++ b/arch/arm/boot/dts/ti/omap/omap36xx-omap3430es2plus-clocks.dtsi
@@ -9,14 +9,15 @@
compatible = "ti,clksel";
reg = <0xa00>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- ssi_ssr_gate_fck_3430es2: clock-ssi-ssr-gate-fck-3430es2 {
+ ssi_ssr_gate_fck_3430es2: clock-ssi-ssr-gate-fck-3430es2@0 {
+ reg = <0>;
#clock-cells = <0>;
compatible = "ti,composite-no-wait-gate-clock";
clock-output-names = "ssi_ssr_gate_fck_3430es2";
clocks = <&corex2_fck>;
- ti,bit-shift = <0>;
};
};
@@ -24,14 +25,15 @@
compatible = "ti,clksel";
reg = <0xa40>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- ssi_ssr_div_fck_3430es2: clock-ssi-ssr-div-fck-3430es2 {
+ ssi_ssr_div_fck_3430es2: clock-ssi-ssr-div-fck-3430es2@8 {
+ reg = <8>;
#clock-cells = <0>;
compatible = "ti,composite-divider-clock";
clock-output-names = "ssi_ssr_div_fck_3430es2";
clocks = <&corex2_fck>;
- ti,bit-shift = <8>;
ti,dividers = <0>, <1>, <2>, <3>, <4>, <0>, <6>, <0>, <8>;
};
};
@@ -54,22 +56,23 @@
compatible = "ti,clksel";
reg = <0xa10>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- hsotgusb_ick_3430es2: clock-hsotgusb-ick-3430es2 {
+ hsotgusb_ick_3430es2: clock-hsotgusb-ick-3430es2@4 {
+ reg = <4>;
#clock-cells = <0>;
compatible = "ti,omap3-hsotgusb-interface-clock";
clock-output-names = "hsotgusb_ick_3430es2";
clocks = <&core_l3_ick>;
- ti,bit-shift = <4>;
};
- ssi_ick: clock-ssi-ick-3430es2 {
+ ssi_ick: clock-ssi-ick-3430es2@0 {
+ reg = <0>;
#clock-cells = <0>;
compatible = "ti,omap3-ssi-interface-clock";
clock-output-names = "ssi_ick_3430es2";
clocks = <&ssi_l4_ick>;
- ti,bit-shift = <0>;
};
};
@@ -85,14 +88,15 @@
compatible = "ti,clksel";
reg = <0xc00>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- usim_gate_fck: clock-usim-gate-fck {
+ usim_gate_fck: clock-usim-gate-fck@9 {
+ reg = <9>;
#clock-cells = <0>;
compatible = "ti,composite-gate-clock";
clock-output-names = "usim_gate_fck";
clocks = <&omap_96m_fck>;
- ti,bit-shift = <9>;
};
};
@@ -172,14 +176,15 @@
compatible = "ti,clksel";
reg = <0xc40>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- usim_mux_fck: clock-usim-mux-fck {
+ usim_mux_fck: clock-usim-mux-fck@3 {
+ reg = <3>;
#clock-cells = <0>;
compatible = "ti,composite-mux-clock";
clock-output-names = "usim_mux_fck";
clocks = <&sys_ck>, <&sys_d2_ck>, <&omap_96m_d2_fck>, <&omap_96m_d4_fck>, <&omap_96m_d8_fck>, <&omap_96m_d10_fck>, <&dpll5_m2_d4_ck>, <&dpll5_m2_d8_ck>, <&dpll5_m2_d16_ck>, <&dpll5_m2_d20_ck>;
- ti,bit-shift = <3>;
ti,index-starts-at-one;
};
};
@@ -194,14 +199,15 @@
compatible = "ti,clksel";
reg = <0xc10>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- usim_ick: clock-usim-ick {
+ usim_ick: clock-usim-ick@9 {
+ reg = <9>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "usim_ick";
clocks = <&wkup_l4_ick>;
- ti,bit-shift = <9>;
};
};
};
diff --git a/arch/arm/boot/dts/ti/omap/omap36xx.dtsi b/arch/arm/boot/dts/ti/omap/omap36xx.dtsi
index e6d8070c1bf8..c3d79ecd56e3 100644
--- a/arch/arm/boot/dts/ti/omap/omap36xx.dtsi
+++ b/arch/arm/boot/dts/ti/omap/omap36xx.dtsi
@@ -211,10 +211,11 @@
#size-cells = <1>;
ranges = <0 0x50000000 0x2000000>;
- /*
- * Closed source PowerVR driver, no child device
- * binding or driver in mainline
- */
+ gpu@0 {
+ compatible = "ti,omap3630-gpu", "img,powervr-sgx530";
+ reg = <0x0 0x2000000>; /* 32MB */
+ interrupts = <21>;
+ };
};
};
diff --git a/arch/arm/boot/dts/ti/omap/omap3xxx-clocks.dtsi b/arch/arm/boot/dts/ti/omap/omap3xxx-clocks.dtsi
index 2e13ca11ceea..901ee79a66f1 100644
--- a/arch/arm/boot/dts/ti/omap/omap3xxx-clocks.dtsi
+++ b/arch/arm/boot/dts/ti/omap/omap3xxx-clocks.dtsi
@@ -83,29 +83,31 @@
compatible = "ti,clksel";
reg = <0x68>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- mcbsp5_mux_fck: clock-mcbsp5-mux-fck {
+ mcbsp5_mux_fck: clock-mcbsp5-mux-fck@4 {
+ reg = <4>;
#clock-cells = <0>;
compatible = "ti,composite-mux-clock";
clock-output-names = "mcbsp5_mux_fck";
clocks = <&core_96m_fck>, <&mcbsp_clks>;
- ti,bit-shift = <4>;
};
- mcbsp3_mux_fck: clock-mcbsp3-mux-fck {
+ mcbsp3_mux_fck: clock-mcbsp3-mux-fck@0 {
+ reg = <0>;
#clock-cells = <0>;
compatible = "ti,composite-mux-clock";
clock-output-names = "mcbsp3_mux_fck";
clocks = <&per_96m_fck>, <&mcbsp_clks>;
};
- mcbsp4_mux_fck: clock-mcbsp4-mux-fck {
+ mcbsp4_mux_fck: clock-mcbsp4-mux-fck@2 {
+ reg = <2>;
#clock-cells = <0>;
compatible = "ti,composite-mux-clock";
clock-output-names = "mcbsp4_mux_fck";
clocks = <&per_96m_fck>, <&mcbsp_clks>;
- ti,bit-shift = <2>;
};
};
@@ -120,22 +122,23 @@
compatible = "ti,clksel";
reg = <0x4>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- mcbsp1_mux_fck: clock-mcbsp1-mux-fck {
+ mcbsp1_mux_fck: clock-mcbsp1-mux-fck@2 {
+ reg = <2>;
#clock-cells = <0>;
compatible = "ti,composite-mux-clock";
clock-output-names = "mcbsp1_mux_fck";
clocks = <&core_96m_fck>, <&mcbsp_clks>;
- ti,bit-shift = <2>;
};
- mcbsp2_mux_fck: clock-mcbsp2-mux-fck {
+ mcbsp2_mux_fck: clock-mcbsp2-mux-fck@6 {
+ reg = <6>;
#clock-cells = <0>;
compatible = "ti,composite-mux-clock";
clock-output-names = "mcbsp2_mux_fck";
clocks = <&per_96m_fck>, <&mcbsp_clks>;
- ti,bit-shift = <6>;
};
};
@@ -259,79 +262,81 @@
compatible = "ti,clksel";
reg = <0x1140>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- dpll3_m3_ck: clock-dpll3-m3 {
+ dpll3_m3_ck: clock-dpll3-m3@16 {
+ reg = <16>;
#clock-cells = <0>;
compatible = "ti,divider-clock";
clock-output-names = "dpll3_m3_ck";
clocks = <&dpll3_ck>;
- ti,bit-shift = <16>;
ti,max-div = <31>;
ti,index-starts-at-one;
};
- dpll4_m6_ck: clock-dpll4-m6 {
+ dpll4_m6_ck: clock-dpll4-m6@24 {
+ reg = <24>;
#clock-cells = <0>;
compatible = "ti,divider-clock";
clock-output-names = "dpll4_m6_ck";
clocks = <&dpll4_ck>;
- ti,bit-shift = <24>;
ti,max-div = <63>;
ti,index-starts-at-one;
};
- emu_src_mux_ck: clock-emu-src-mux {
+ emu_src_mux_ck: clock-emu-src-mux@0 {
+ reg = <0>;
#clock-cells = <0>;
compatible = "ti,mux-clock";
clock-output-names = "emu_src_mux_ck";
clocks = <&sys_ck>, <&emu_core_alwon_ck>, <&emu_per_alwon_ck>, <&emu_mpu_alwon_ck>;
};
- pclk_fck: clock-pclk-fck {
+ pclk_fck: clock-pclk-fck@8 {
+ reg = <8>;
#clock-cells = <0>;
compatible = "ti,divider-clock";
clock-output-names = "pclk_fck";
clocks = <&emu_src_ck>;
- ti,bit-shift = <8>;
ti,max-div = <7>;
ti,index-starts-at-one;
};
- pclkx2_fck: clock-pclkx2-fck {
+ pclkx2_fck: clock-pclkx2-fck@6 {
+ reg = <6>;
#clock-cells = <0>;
compatible = "ti,divider-clock";
clock-output-names = "pclkx2_fck";
clocks = <&emu_src_ck>;
- ti,bit-shift = <6>;
ti,max-div = <3>;
ti,index-starts-at-one;
};
- atclk_fck: clock-atclk-fck {
+ atclk_fck: clock-atclk-fck@4 {
+ reg = <4>;
#clock-cells = <0>;
compatible = "ti,divider-clock";
clock-output-names = "atclk_fck";
clocks = <&emu_src_ck>;
- ti,bit-shift = <4>;
ti,max-div = <3>;
ti,index-starts-at-one;
};
- traceclk_src_fck: clock-traceclk-src-fck {
+ traceclk_src_fck: clock-traceclk-src-fck@2 {
+ reg = <2>;
#clock-cells = <0>;
compatible = "ti,mux-clock";
clock-output-names = "traceclk_src_fck";
clocks = <&sys_ck>, <&emu_core_alwon_ck>, <&emu_per_alwon_ck>, <&emu_mpu_alwon_ck>;
- ti,bit-shift = <2>;
};
- traceclk_fck: clock-traceclk-fck {
+ traceclk_fck: clock-traceclk-fck@11 {
+ reg = <11>;
#clock-cells = <0>;
compatible = "ti,divider-clock";
clock-output-names = "traceclk_fck";
clocks = <&traceclk_src_fck>;
- ti,bit-shift = <11>;
ti,max-div = <7>;
ti,index-starts-at-one;
};
@@ -429,40 +434,41 @@
compatible = "ti,clksel";
reg = <0xd40>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- dpll3_m2_ck: clock-dpll3-m2 {
+ dpll3_m2_ck: clock-dpll3-m2@27 {
+ reg = <27>;
#clock-cells = <0>;
compatible = "ti,divider-clock";
clock-output-names = "dpll3_m2_ck";
clocks = <&dpll3_ck>;
- ti,bit-shift = <27>;
ti,max-div = <31>;
ti,index-starts-at-one;
};
- omap_96m_fck: clock-omap-96m-fck {
+ omap_96m_fck: clock-omap-96m-fck@6 {
+ reg = <6>;
#clock-cells = <0>;
compatible = "ti,mux-clock";
clock-output-names = "omap_96m_fck";
clocks = <&cm_96m_fck>, <&sys_ck>;
- ti,bit-shift = <6>;
};
- omap_54m_fck: clock-omap-54m-fck {
+ omap_54m_fck: clock-omap-54m-fck@5 {
+ reg = <5>;
#clock-cells = <0>;
compatible = "ti,mux-clock";
clock-output-names = "omap_54m_fck";
clocks = <&dpll4_m3x2_ck>, <&sys_altclk>;
- ti,bit-shift = <5>;
};
- omap_48m_fck: clock-omap-48m-fck {
+ omap_48m_fck: clock-omap-48m-fck@3 {
+ reg = <3>;
#clock-cells = <0>;
compatible = "ti,mux-clock";
clock-output-names = "omap_48m_fck";
clocks = <&cm_96m_d2_fck>, <&sys_altclk>;
- ti,bit-shift = <3>;
};
};
@@ -471,19 +477,21 @@
compatible = "ti,clksel";
reg = <0xe40>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- dpll4_m3_ck: clock-dpll4-m3 {
+ dpll4_m3_ck: clock-dpll4-m3@8 {
+ reg = <8>;
#clock-cells = <0>;
compatible = "ti,divider-clock";
clock-output-names = "dpll4_m3_ck";
clocks = <&dpll4_ck>;
- ti,bit-shift = <8>;
ti,max-div = <32>;
ti,index-starts-at-one;
};
- dpll4_m4_ck: clock-dpll4-m4 {
+ dpll4_m4_ck: clock-dpll4-m4@0 {
+ reg = <0>;
#clock-cells = <0>;
compatible = "ti,divider-clock";
clock-output-names = "dpll4_m4_ck";
@@ -603,29 +611,31 @@
compatible = "ti,clksel";
reg = <0xd70>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- clkout2_src_gate_ck: clock-clkout2-src-gate {
+ clkout2_src_gate_ck: clock-clkout2-src-gate@7 {
+ reg = <7>;
#clock-cells = <0>;
compatible = "ti,composite-no-wait-gate-clock";
clock-output-names = "clkout2_src_gate_ck";
clocks = <&core_ck>;
- ti,bit-shift = <7>;
};
- clkout2_src_mux_ck: clock-clkout2-src-mux {
+ clkout2_src_mux_ck: clock-clkout2-src-mux@0 {
+ reg = <0>;
#clock-cells = <0>;
compatible = "ti,composite-mux-clock";
clock-output-names = "clkout2_src_mux_ck";
clocks = <&core_ck>, <&sys_ck>, <&cm_96m_fck>, <&omap_54m_fck>;
};
- sys_clkout2: clock-sys-clkout2 {
+ sys_clkout2: clock-sys-clkout2@3 {
+ reg = <3>;
#clock-cells = <0>;
compatible = "ti,divider-clock";
clock-output-names = "sys_clkout2";
clocks = <&clkout2_src_ck>;
- ti,bit-shift = <3>;
ti,max-div = <64>;
ti,index-power-of-two;
};
@@ -666,9 +676,11 @@
compatible = "ti,clksel";
reg = <0xa40>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- l3_ick: clock-l3-ick {
+ l3_ick: clock-l3-ick@0 {
+ reg = <0>;
#clock-cells = <0>;
compatible = "ti,divider-clock";
clock-output-names = "l3_ick";
@@ -677,30 +689,30 @@
ti,index-starts-at-one;
};
- l4_ick: clock-l4-ick {
+ l4_ick: clock-l4-ick@2 {
+ reg = <2>;
#clock-cells = <0>;
compatible = "ti,divider-clock";
clock-output-names = "l4_ick";
clocks = <&l3_ick>;
- ti,bit-shift = <2>;
ti,max-div = <3>;
ti,index-starts-at-one;
};
- gpt10_mux_fck: clock-gpt10-mux-fck {
+ gpt10_mux_fck: clock-gpt10-mux-fck@6 {
+ reg = <6>;
#clock-cells = <0>;
compatible = "ti,composite-mux-clock";
clock-output-names = "gpt10_mux_fck";
clocks = <&omap_32k_fck>, <&sys_ck>;
- ti,bit-shift = <6>;
};
- gpt11_mux_fck: clock-gpt11-mux-fck {
+ gpt11_mux_fck: clock-gpt11-mux-fck@7 {
+ reg = <7>;
#clock-cells = <0>;
compatible = "ti,composite-mux-clock";
clock-output-names = "gpt11_mux_fck";
clocks = <&omap_32k_fck>, <&sys_ck>;
- ti,bit-shift = <7>;
};
};
@@ -709,19 +721,21 @@
compatible = "ti,clksel";
reg = <0xc40>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- rm_ick: clock-rm-ick {
+ rm_ick: clock-rm-ick@1 {
+ reg = <1>;
#clock-cells = <0>;
compatible = "ti,divider-clock";
clock-output-names = "rm_ick";
clocks = <&l4_ick>;
- ti,bit-shift = <1>;
ti,max-div = <3>;
ti,index-starts-at-one;
};
- gpt1_mux_fck: clock-gpt1-mux-fck {
+ gpt1_mux_fck: clock-gpt1-mux-fck@0 {
+ reg = <0>;
#clock-cells = <0>;
compatible = "ti,composite-mux-clock";
clock-output-names = "gpt1_mux_fck";
@@ -734,134 +748,135 @@
compatible = "ti,clksel";
reg = <0xa00>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- gpt10_gate_fck: clock-gpt10-gate-fck {
+ gpt10_gate_fck: clock-gpt10-gate-fck@11 {
+ reg = <11>;
#clock-cells = <0>;
compatible = "ti,composite-gate-clock";
clock-output-names = "gpt10_gate_fck";
clocks = <&sys_ck>;
- ti,bit-shift = <11>;
};
- gpt11_gate_fck: clock-gpt11-gate-fck {
+ gpt11_gate_fck: clock-gpt11-gate-fck@12 {
+ reg = <12>;
#clock-cells = <0>;
compatible = "ti,composite-gate-clock";
clock-output-names = "gpt11_gate_fck";
clocks = <&sys_ck>;
- ti,bit-shift = <12>;
};
- mmchs2_fck: clock-mmchs2-fck {
+ mmchs2_fck: clock-mmchs2-fck@25 {
+ reg = <25>;
#clock-cells = <0>;
compatible = "ti,wait-gate-clock";
clock-output-names = "mmchs2_fck";
clocks = <&core_96m_fck>;
- ti,bit-shift = <25>;
};
- mmchs1_fck: clock-mmchs1-fck {
+ mmchs1_fck: clock-mmchs1-fck@24 {
+ reg = <24>;
#clock-cells = <0>;
compatible = "ti,wait-gate-clock";
clock-output-names = "mmchs1_fck";
clocks = <&core_96m_fck>;
- ti,bit-shift = <24>;
};
- i2c3_fck: clock-i2c3-fck {
+ i2c3_fck: clock-i2c3-fck@17 {
+ reg = <17>;
#clock-cells = <0>;
compatible = "ti,wait-gate-clock";
clock-output-names = "i2c3_fck";
clocks = <&core_96m_fck>;
- ti,bit-shift = <17>;
};
- i2c2_fck: clock-i2c2-fck {
+ i2c2_fck: clock-i2c2-fck@16 {
+ reg = <16>;
#clock-cells = <0>;
compatible = "ti,wait-gate-clock";
clock-output-names = "i2c2_fck";
clocks = <&core_96m_fck>;
- ti,bit-shift = <16>;
};
- i2c1_fck: clock-i2c1-fck {
+ i2c1_fck: clock-i2c1-fck@15 {
+ reg = <15>;
#clock-cells = <0>;
compatible = "ti,wait-gate-clock";
clock-output-names = "i2c1_fck";
clocks = <&core_96m_fck>;
- ti,bit-shift = <15>;
};
- mcbsp5_gate_fck: clock-mcbsp5-gate-fck {
+ mcbsp5_gate_fck: clock-mcbsp5-gate-fck@10 {
+ reg = <10>;
#clock-cells = <0>;
compatible = "ti,composite-gate-clock";
clock-output-names = "mcbsp5_gate_fck";
clocks = <&mcbsp_clks>;
- ti,bit-shift = <10>;
};
- mcbsp1_gate_fck: clock-mcbsp1-gate-fck {
+ mcbsp1_gate_fck: clock-mcbsp1-gate-fck@9 {
+ reg = <9>;
#clock-cells = <0>;
compatible = "ti,composite-gate-clock";
clock-output-names = "mcbsp1_gate_fck";
clocks = <&mcbsp_clks>;
- ti,bit-shift = <9>;
};
- mcspi4_fck: clock-mcspi4-fck {
+ mcspi4_fck: clock-mcspi4-fck@21 {
+ reg = <21>;
#clock-cells = <0>;
compatible = "ti,wait-gate-clock";
clock-output-names = "mcspi4_fck";
clocks = <&core_48m_fck>;
- ti,bit-shift = <21>;
};
- mcspi3_fck: clock-mcspi3-fck {
+ mcspi3_fck: clock-mcspi3-fck@20 {
+ reg = <20>;
#clock-cells = <0>;
compatible = "ti,wait-gate-clock";
clock-output-names = "mcspi3_fck";
clocks = <&core_48m_fck>;
- ti,bit-shift = <20>;
};
- mcspi2_fck: clock-mcspi2-fck {
+ mcspi2_fck: clock-mcspi2-fck@19 {
+ reg = <19>;
#clock-cells = <0>;
compatible = "ti,wait-gate-clock";
clock-output-names = "mcspi2_fck";
clocks = <&core_48m_fck>;
- ti,bit-shift = <19>;
};
- mcspi1_fck: clock-mcspi1-fck {
+ mcspi1_fck: clock-mcspi1-fck@18 {
+ reg = <18>;
#clock-cells = <0>;
compatible = "ti,wait-gate-clock";
clock-output-names = "mcspi1_fck";
clocks = <&core_48m_fck>;
- ti,bit-shift = <18>;
};
- uart2_fck: clock-uart2-fck {
+ uart2_fck: clock-uart2-fck@14 {
+ reg = <14>;
#clock-cells = <0>;
compatible = "ti,wait-gate-clock";
clock-output-names = "uart2_fck";
clocks = <&core_48m_fck>;
- ti,bit-shift = <14>;
};
- uart1_fck: clock-uart1-fck {
+ uart1_fck: clock-uart1-fck@13 {
+ reg = <13>;
#clock-cells = <0>;
compatible = "ti,wait-gate-clock";
clock-output-names = "uart1_fck";
clocks = <&core_48m_fck>;
- ti,bit-shift = <13>;
};
- hdq_fck: clock-hdq-fck {
+ hdq_fck: clock-hdq-fck@22 {
+ reg = <22>;
#clock-cells = <0>;
compatible = "ti,wait-gate-clock";
clock-output-names = "hdq_fck";
clocks = <&core_12m_fck>;
- ti,bit-shift = <22>;
};
};
@@ -914,166 +929,167 @@
compatible = "ti,clksel";
reg = <0xa10>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- sdrc_ick: clock-sdrc-ick {
+ sdrc_ick: clock-sdrc-ick@1 {
+ reg = <1>;
#clock-cells = <0>;
compatible = "ti,wait-gate-clock";
clock-output-names = "sdrc_ick";
clocks = <&core_l3_ick>;
- ti,bit-shift = <1>;
};
- mmchs2_ick: clock-mmchs2-ick {
+ mmchs2_ick: clock-mmchs2-ick@25 {
+ reg = <25>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "mmchs2_ick";
clocks = <&core_l4_ick>;
- ti,bit-shift = <25>;
};
- mmchs1_ick: clock-mmchs1-ick {
+ mmchs1_ick: clock-mmchs1-ick@24 {
+ reg = <24>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "mmchs1_ick";
clocks = <&core_l4_ick>;
- ti,bit-shift = <24>;
};
- hdq_ick: clock-hdq-ick {
+ hdq_ick: clock-hdq-ick@22 {
+ reg = <22>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "hdq_ick";
clocks = <&core_l4_ick>;
- ti,bit-shift = <22>;
};
- mcspi4_ick: clock-mcspi4-ick {
+ mcspi4_ick: clock-mcspi4-ick@21 {
+ reg = <21>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "mcspi4_ick";
clocks = <&core_l4_ick>;
- ti,bit-shift = <21>;
};
- mcspi3_ick: clock-mcspi3-ick {
+ mcspi3_ick: clock-mcspi3-ick@20 {
+ reg = <20>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "mcspi3_ick";
clocks = <&core_l4_ick>;
- ti,bit-shift = <20>;
};
- mcspi2_ick: clock-mcspi2-ick {
+ mcspi2_ick: clock-mcspi2-ick@19 {
+ reg = <19>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "mcspi2_ick";
clocks = <&core_l4_ick>;
- ti,bit-shift = <19>;
};
- mcspi1_ick: clock-mcspi1-ick {
+ mcspi1_ick: clock-mcspi1-ick@18 {
+ reg = <18>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "mcspi1_ick";
clocks = <&core_l4_ick>;
- ti,bit-shift = <18>;
};
- i2c3_ick: clock-i2c3-ick {
+ i2c3_ick: clock-i2c3-ick@17 {
+ reg = <17>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "i2c3_ick";
clocks = <&core_l4_ick>;
- ti,bit-shift = <17>;
};
- i2c2_ick: clock-i2c2-ick {
+ i2c2_ick: clock-i2c2-ick@16 {
+ reg = <16>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "i2c2_ick";
clocks = <&core_l4_ick>;
- ti,bit-shift = <16>;
};
- i2c1_ick: clock-i2c1-ick {
+ i2c1_ick: clock-i2c1-ick@15 {
+ reg = <15>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "i2c1_ick";
clocks = <&core_l4_ick>;
- ti,bit-shift = <15>;
};
- uart2_ick: clock-uart2-ick {
+ uart2_ick: clock-uart2-ick@14 {
+ reg = <14>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "uart2_ick";
clocks = <&core_l4_ick>;
- ti,bit-shift = <14>;
};
- uart1_ick: clock-uart1-ick {
+ uart1_ick: clock-uart1-ick@13 {
+ reg = <13>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "uart1_ick";
clocks = <&core_l4_ick>;
- ti,bit-shift = <13>;
};
- gpt11_ick: clock-gpt11-ick {
+ gpt11_ick: clock-gpt11-ick@12 {
+ reg = <12>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "gpt11_ick";
clocks = <&core_l4_ick>;
- ti,bit-shift = <12>;
};
- gpt10_ick: clock-gpt10-ick {
+ gpt10_ick: clock-gpt10-ick@11 {
+ reg = <11>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "gpt10_ick";
clocks = <&core_l4_ick>;
- ti,bit-shift = <11>;
};
- mcbsp5_ick: clock-mcbsp5-ick {
+ mcbsp5_ick: clock-mcbsp5-ick@10 {
+ reg = <10>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "mcbsp5_ick";
clocks = <&core_l4_ick>;
- ti,bit-shift = <10>;
};
- mcbsp1_ick: clock-mcbsp1-ick {
+ mcbsp1_ick: clock-mcbsp1-ick@9 {
+ reg = <9>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "mcbsp1_ick";
clocks = <&core_l4_ick>;
- ti,bit-shift = <9>;
};
- omapctrl_ick: clock-omapctrl-ick {
+ omapctrl_ick: clock-omapctrl-ick@6 {
+ reg = <6>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "omapctrl_ick";
clocks = <&core_l4_ick>;
- ti,bit-shift = <6>;
};
- aes2_ick: clock-aes2-ick {
+ aes2_ick: clock-aes2-ick@28 {
+ reg = <28>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "aes2_ick";
clocks = <&core_l4_ick>;
- ti,bit-shift = <28>;
};
- sha12_ick: clock-sha12-ick {
+ sha12_ick: clock-sha12-ick@27 {
+ reg = <27>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "sha12_ick";
clocks = <&core_l4_ick>;
- ti,bit-shift = <27>;
};
};
@@ -1136,30 +1152,31 @@
compatible = "ti,clksel";
reg = <0xc00>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- gpt1_gate_fck: clock-gpt1-gate-fck {
+ gpt1_gate_fck: clock-gpt1-gate-fck@0 {
+ reg = <0>;
#clock-cells = <0>;
compatible = "ti,composite-gate-clock";
clock-output-names = "gpt1_gate_fck";
clocks = <&sys_ck>;
- ti,bit-shift = <0>;
};
- gpio1_dbck: clock-gpio1-dbck {
+ gpio1_dbck: clock-gpio1-dbck@3 {
+ reg = <3>;
#clock-cells = <0>;
compatible = "ti,gate-clock";
clock-output-names = "gpio1_dbck";
clocks = <&wkup_32k_fck>;
- ti,bit-shift = <3>;
};
- wdt2_fck: clock-wdt2-fck {
+ wdt2_fck: clock-wdt2-fck@5 {
+ reg = <5>;
#clock-cells = <0>;
compatible = "ti,wait-gate-clock";
clock-output-names = "wdt2_fck";
clocks = <&wkup_32k_fck>;
- ti,bit-shift = <5>;
};
};
@@ -1182,54 +1199,55 @@
compatible = "ti,clksel";
reg = <0xc10>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- wdt2_ick: clock-wdt2-ick {
+ wdt2_ick: clock-wdt2-ick@5 {
+ reg = <5>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "wdt2_ick";
clocks = <&wkup_l4_ick>;
- ti,bit-shift = <5>;
};
- wdt1_ick: clock-wdt1-ick {
+ wdt1_ick: clock-wdt1-ick@4 {
+ reg = <4>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "wdt1_ick";
clocks = <&wkup_l4_ick>;
- ti,bit-shift = <4>;
};
- gpio1_ick: clock-gpio1-ick {
+ gpio1_ick: clock-gpio1-ick@3 {
+ reg = <3>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "gpio1_ick";
clocks = <&wkup_l4_ick>;
- ti,bit-shift = <3>;
};
- omap_32ksync_ick: clock-omap-32ksync-ick {
+ omap_32ksync_ick: clock-omap-32ksync-ick@2 {
+ reg = <2>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "omap_32ksync_ick";
clocks = <&wkup_l4_ick>;
- ti,bit-shift = <2>;
};
- gpt12_ick: clock-gpt12-ick {
+ gpt12_ick: clock-gpt12-ick@1 {
+ reg = <1>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "gpt12_ick";
clocks = <&wkup_l4_ick>;
- ti,bit-shift = <1>;
};
- gpt1_ick: clock-gpt1-ick {
+ gpt1_ick: clock-gpt1-ick@0 {
+ reg = <0>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "gpt1_ick";
clocks = <&wkup_l4_ick>;
- ti,bit-shift = <0>;
};
};
@@ -1254,150 +1272,151 @@
compatible = "ti,clksel";
reg = <0x1000>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- uart3_fck: clock-uart3-fck {
+ uart3_fck: clock-uart3-fck@11 {
+ reg = <11>;
#clock-cells = <0>;
compatible = "ti,wait-gate-clock";
clock-output-names = "uart3_fck";
clocks = <&per_48m_fck>;
- ti,bit-shift = <11>;
};
- gpt2_gate_fck: clock-gpt2-gate-fck {
+ gpt2_gate_fck: clock-gpt2-gate-fck@3 {
+ reg = <3>;
#clock-cells = <0>;
compatible = "ti,composite-gate-clock";
clock-output-names = "gpt2_gate_fck";
clocks = <&sys_ck>;
- ti,bit-shift = <3>;
};
- gpt3_gate_fck: clock-gpt3-gate-fck {
+ gpt3_gate_fck: clock-gpt3-gate-fck@4 {
+ reg = <4>;
#clock-cells = <0>;
compatible = "ti,composite-gate-clock";
clock-output-names = "gpt3_gate_fck";
clocks = <&sys_ck>;
- ti,bit-shift = <4>;
};
- gpt4_gate_fck: clock-gpt4-gate-fck {
+ gpt4_gate_fck: clock-gpt4-gate-fck@5 {
+ reg = <5>;
#clock-cells = <0>;
compatible = "ti,composite-gate-clock";
clock-output-names = "gpt4_gate_fck";
clocks = <&sys_ck>;
- ti,bit-shift = <5>;
};
- gpt5_gate_fck: clock-gpt5-gate-fck {
+ gpt5_gate_fck: clock-gpt5-gate-fck@6 {
+ reg = <6>;
#clock-cells = <0>;
compatible = "ti,composite-gate-clock";
clock-output-names = "gpt5_gate_fck";
clocks = <&sys_ck>;
- ti,bit-shift = <6>;
};
- gpt6_gate_fck: clock-gpt6-gate-fck {
+ gpt6_gate_fck: clock-gpt6-gate-fck@7 {
+ reg = <7>;
#clock-cells = <0>;
compatible = "ti,composite-gate-clock";
clock-output-names = "gpt6_gate_fck";
clocks = <&sys_ck>;
- ti,bit-shift = <7>;
};
- gpt7_gate_fck: clock-gpt7-gate-fck {
+ gpt7_gate_fck: clock-gpt7-gate-fck@8 {
+ reg = <8>;
#clock-cells = <0>;
compatible = "ti,composite-gate-clock";
clock-output-names = "gpt7_gate_fck";
clocks = <&sys_ck>;
- ti,bit-shift = <8>;
};
- gpt8_gate_fck: clock-gpt8-gate-fck {
+ gpt8_gate_fck: clock-gpt8-gate-fck@9 {
+ reg = <9>;
#clock-cells = <0>;
compatible = "ti,composite-gate-clock";
clock-output-names = "gpt8_gate_fck";
clocks = <&sys_ck>;
- ti,bit-shift = <9>;
};
- gpt9_gate_fck: clock-gpt9-gate-fck {
+ gpt9_gate_fck: clock-gpt9-gate-fck@10 {
+ reg = <10>;
#clock-cells = <0>;
compatible = "ti,composite-gate-clock";
clock-output-names = "gpt9_gate_fck";
clocks = <&sys_ck>;
- ti,bit-shift = <10>;
};
- gpio6_dbck: clock-gpio6-dbck {
+ gpio6_dbck: clock-gpio6-dbck@17 {
+ reg = <17>;
#clock-cells = <0>;
compatible = "ti,gate-clock";
clock-output-names = "gpio6_dbck";
clocks = <&per_32k_alwon_fck>;
- ti,bit-shift = <17>;
};
- gpio5_dbck: clock-gpio5-dbck {
+ gpio5_dbck: clock-gpio5-dbck@16 {
+ reg = <16>;
#clock-cells = <0>;
compatible = "ti,gate-clock";
clock-output-names = "gpio5_dbck";
clocks = <&per_32k_alwon_fck>;
- ti,bit-shift = <16>;
};
- gpio4_dbck: clock-gpio4-dbck {
+ gpio4_dbck: clock-gpio4-dbck@15 {
+ reg = <15>;
#clock-cells = <0>;
compatible = "ti,gate-clock";
clock-output-names = "gpio4_dbck";
clocks = <&per_32k_alwon_fck>;
- ti,bit-shift = <15>;
};
- gpio3_dbck: clock-gpio3-dbck {
+ gpio3_dbck: clock-gpio3-dbck@14 {
+ reg = <14>;
#clock-cells = <0>;
compatible = "ti,gate-clock";
clock-output-names = "gpio3_dbck";
clocks = <&per_32k_alwon_fck>;
- ti,bit-shift = <14>;
};
- gpio2_dbck: clock-gpio2-dbck {
+ gpio2_dbck: clock-gpio2-dbck@13 {
+ reg = <13>;
#clock-cells = <0>;
compatible = "ti,gate-clock";
clock-output-names = "gpio2_dbck";
clocks = <&per_32k_alwon_fck>;
- ti,bit-shift = <13>;
};
- wdt3_fck: clock-wdt3-fck {
+ wdt3_fck: clock-wdt3-fck@12 {
+ reg = <12>;
#clock-cells = <0>;
compatible = "ti,wait-gate-clock";
clock-output-names = "wdt3_fck";
clocks = <&per_32k_alwon_fck>;
- ti,bit-shift = <12>;
};
- mcbsp2_gate_fck: clock-mcbsp2-gate-fck {
+ mcbsp2_gate_fck: clock-mcbsp2-gate-fck@0 {
+ reg = <0>;
#clock-cells = <0>;
compatible = "ti,composite-gate-clock";
clock-output-names = "mcbsp2_gate_fck";
clocks = <&mcbsp_clks>;
- ti,bit-shift = <0>;
};
- mcbsp3_gate_fck: clock-mcbsp3-gate-fck {
+ mcbsp3_gate_fck: clock-mcbsp3-gate-fck@1 {
+ reg = <1>;
#clock-cells = <0>;
compatible = "ti,composite-gate-clock";
clock-output-names = "mcbsp3_gate_fck";
clocks = <&mcbsp_clks>;
- ti,bit-shift = <1>;
};
- mcbsp4_gate_fck: clock-mcbsp4-gate-fck {
+ mcbsp4_gate_fck: clock-mcbsp4-gate-fck@2 {
+ reg = <2>;
#clock-cells = <0>;
compatible = "ti,composite-gate-clock";
clock-output-names = "mcbsp4_gate_fck";
clocks = <&mcbsp_clks>;
- ti,bit-shift = <2>;
};
};
@@ -1406,69 +1425,71 @@
compatible = "ti,clksel";
reg = <0x1040>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- gpt2_mux_fck: clock-gpt2-mux-fck {
+ gpt2_mux_fck: clock-gpt2-mux-fck@0 {
+ reg = <0>;
#clock-cells = <0>;
compatible = "ti,composite-mux-clock";
clock-output-names = "gpt2_mux_fck";
clocks = <&omap_32k_fck>, <&sys_ck>;
};
- gpt3_mux_fck: clock-gpt3-mux-fck {
+ gpt3_mux_fck: clock-gpt3-mux-fck@1 {
+ reg = <1>;
#clock-cells = <0>;
compatible = "ti,composite-mux-clock";
clock-output-names = "gpt3_mux_fck";
clocks = <&omap_32k_fck>, <&sys_ck>;
- ti,bit-shift = <1>;
};
- gpt4_mux_fck: clock-gpt4-mux-fck {
+ gpt4_mux_fck: clock-gpt4-mux-fck@2 {
+ reg = <2>;
#clock-cells = <0>;
compatible = "ti,composite-mux-clock";
clock-output-names = "gpt4_mux_fck";
clocks = <&omap_32k_fck>, <&sys_ck>;
- ti,bit-shift = <2>;
};
- gpt5_mux_fck: clock-gpt5-mux-fck {
+ gpt5_mux_fck: clock-gpt5-mux-fck@3 {
+ reg = <3>;
#clock-cells = <0>;
compatible = "ti,composite-mux-clock";
clock-output-names = "gpt5_mux_fck";
clocks = <&omap_32k_fck>, <&sys_ck>;
- ti,bit-shift = <3>;
};
- gpt6_mux_fck: clock-gpt6-mux-fck {
+ gpt6_mux_fck: clock-gpt6-mux-fck@4 {
+ reg = <4>;
#clock-cells = <0>;
compatible = "ti,composite-mux-clock";
clock-output-names = "gpt6_mux_fck";
clocks = <&omap_32k_fck>, <&sys_ck>;
- ti,bit-shift = <4>;
};
- gpt7_mux_fck: clock-gpt7-mux-fck {
+ gpt7_mux_fck: clock-gpt7-mux-fck@5 {
+ reg = <5>;
#clock-cells = <0>;
compatible = "ti,composite-mux-clock";
clock-output-names = "gpt7_mux_fck";
clocks = <&omap_32k_fck>, <&sys_ck>;
- ti,bit-shift = <5>;
};
- gpt8_mux_fck: clock-gpt8-mux-fck {
+ gpt8_mux_fck: clock-gpt8-mux-fck@6 {
+ reg = <6>;
#clock-cells = <0>;
compatible = "ti,composite-mux-clock";
clock-output-names = "gpt8_mux_fck";
clocks = <&omap_32k_fck>, <&sys_ck>;
- ti,bit-shift = <6>;
};
- gpt9_mux_fck: clock-gpt9-mux-fck {
+ gpt9_mux_fck: clock-gpt9-mux-fck@7 {
+ reg = <7>;
#clock-cells = <0>;
compatible = "ti,composite-mux-clock";
clock-output-names = "gpt9_mux_fck";
clocks = <&omap_32k_fck>, <&sys_ck>;
- ti,bit-shift = <7>;
};
};
@@ -1541,158 +1562,159 @@
compatible = "ti,clksel";
reg = <0x1010>;
#clock-cells = <2>;
- #address-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
- gpio6_ick: clock-gpio6-ick {
+ gpio6_ick: clock-gpio6-ick@17 {
+ reg = <17>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "gpio6_ick";
clocks = <&per_l4_ick>;
- ti,bit-shift = <17>;
};
- gpio5_ick: clock-gpio5-ick {
+ gpio5_ick: clock-gpio5-ick@16 {
+ reg = <16>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "gpio5_ick";
clocks = <&per_l4_ick>;
- ti,bit-shift = <16>;
};
- gpio4_ick: clock-gpio4-ick {
+ gpio4_ick: clock-gpio4-ick@15 {
+ reg = <15>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "gpio4_ick";
clocks = <&per_l4_ick>;
- ti,bit-shift = <15>;
};
- gpio3_ick: clock-gpio3-ick {
+ gpio3_ick: clock-gpio3-ick@14 {
+ reg = <14>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "gpio3_ick";
clocks = <&per_l4_ick>;
- ti,bit-shift = <14>;
};
- gpio2_ick: clock-gpio2-ick {
+ gpio2_ick: clock-gpio2-ick@13 {
+ reg = <13>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "gpio2_ick";
clocks = <&per_l4_ick>;
- ti,bit-shift = <13>;
};
- wdt3_ick: clock-wdt3-ick {
+ wdt3_ick: clock-wdt3-ick@12 {
+ reg = <12>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "wdt3_ick";
clocks = <&per_l4_ick>;
- ti,bit-shift = <12>;
};
- uart3_ick: clock-uart3-ick {
+ uart3_ick: clock-uart3-ick@11 {
+ reg = <11>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "uart3_ick";
clocks = <&per_l4_ick>;
- ti,bit-shift = <11>;
};
- uart4_ick: clock-uart4-ick {
+ uart4_ick: clock-uart4-ick@18 {
+ reg = <18>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "uart4_ick";
clocks = <&per_l4_ick>;
- ti,bit-shift = <18>;
};
- gpt9_ick: clock-gpt9-ick {
+ gpt9_ick: clock-gpt9-ick@10 {
+ reg = <10>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "gpt9_ick";
clocks = <&per_l4_ick>;
- ti,bit-shift = <10>;
};
- gpt8_ick: clock-gpt8-ick {
+ gpt8_ick: clock-gpt8-ick@9 {
+ reg = <9>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "gpt8_ick";
clocks = <&per_l4_ick>;
- ti,bit-shift = <9>;
};
- gpt7_ick: clock-gpt7-ick {
+ gpt7_ick: clock-gpt7-ick@8 {
+ reg = <8>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "gpt7_ick";
clocks = <&per_l4_ick>;
- ti,bit-shift = <8>;
};
- gpt6_ick: clock-gpt6-ick {
+ gpt6_ick: clock-gpt6-ick@7 {
+ reg = <7>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "gpt6_ick";
clocks = <&per_l4_ick>;
- ti,bit-shift = <7>;
};
- gpt5_ick: clock-gpt5-ick {
+ gpt5_ick: clock-gpt5-ick@6 {
+ reg = <6>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "gpt5_ick";
clocks = <&per_l4_ick>;
- ti,bit-shift = <6>;
};
- gpt4_ick: clock-gpt4-ick {
+ gpt4_ick: clock-gpt4-ick@5 {
+ reg = <5>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "gpt4_ick";
clocks = <&per_l4_ick>;
- ti,bit-shift = <5>;
};
- gpt3_ick: clock-gpt3-ick {
+ gpt3_ick: clock-gpt3-ick@4 {
+ reg = <4>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "gpt3_ick";
clocks = <&per_l4_ick>;
- ti,bit-shift = <4>;
};
- gpt2_ick: clock-gpt2-ick {
+ gpt2_ick: clock-gpt2-ick@3 {
+ reg = <3>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "gpt2_ick";
clocks = <&per_l4_ick>;
- ti,bit-shift = <3>;
};
- mcbsp2_ick: clock-mcbsp2-ick {
+ mcbsp2_ick: clock-mcbsp2-ick@0 {
+ reg = <0>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "mcbsp2_ick";
clocks = <&per_l4_ick>;
- ti,bit-shift = <0>;
};
- mcbsp3_ick: clock-mcbsp3-ick {
+ mcbsp3_ick: clock-mcbsp3-ick@1 {
+ reg = <1>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "mcbsp3_ick";
clocks = <&per_l4_ick>;
- ti,bit-shift = <1>;
};
- mcbsp4_ick: clock-mcbsp4-ick {
+ mcbsp4_ick: clock-mcbsp4-ick@2 {
+ reg = <2>;
#clock-cells = <0>;
compatible = "ti,omap3-interface-clock";
clock-output-names = "mcbsp4_ick";
clocks = <&per_l4_ick>;
- ti,bit-shift = <2>;
};
};
diff --git a/arch/arm/boot/dts/ti/omap/omap4-epson-embt2ws.dts b/arch/arm/boot/dts/ti/omap/omap4-epson-embt2ws.dts
index 24f7d0285f79..339e52ba3614 100644
--- a/arch/arm/boot/dts/ti/omap/omap4-epson-embt2ws.dts
+++ b/arch/arm/boot/dts/ti/omap/omap4-epson-embt2ws.dts
@@ -85,6 +85,7 @@
interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_1N cascaded to gic */
interrupt-controller;
#interrupt-cells = <1>;
+ system-power-controller;
rtc {
compatible = "ti,twl4030-rtc";
diff --git a/arch/arm/boot/dts/ti/omap/omap4-panda-common.dtsi b/arch/arm/boot/dts/ti/omap/omap4-panda-common.dtsi
index f528511c2537..97706d6296a6 100644
--- a/arch/arm/boot/dts/ti/omap/omap4-panda-common.dtsi
+++ b/arch/arm/boot/dts/ti/omap/omap4-panda-common.dtsi
@@ -408,6 +408,7 @@
reg = <0x48>;
/* IRQ# = 7 */
interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; /* IRQ_SYS_1N cascaded to gic */
+ system-power-controller;
};
twl6040: twl@4b {
diff --git a/arch/arm/boot/dts/ti/omap/omap4-sdp.dts b/arch/arm/boot/dts/ti/omap/omap4-sdp.dts
index b2cb93edbc3a..b535d24c6140 100644
--- a/arch/arm/boot/dts/ti/omap/omap4-sdp.dts
+++ b/arch/arm/boot/dts/ti/omap/omap4-sdp.dts
@@ -439,7 +439,7 @@
/*
* Ambient Light Sensor
- * http://www.rohm.com/products/databook/sensor/pdf/bh1780gli-e.pdf
+ * https://www.rohm.com/products/databook/sensor/pdf/bh1780gli-e.pdf (defunct)
*/
bh1780@29 {
compatible = "rohm,bh1780";
diff --git a/arch/arm/boot/dts/ti/omap/omap4.dtsi b/arch/arm/boot/dts/ti/omap/omap4.dtsi
index 2bbff9032be3..559b2bfe4ca7 100644
--- a/arch/arm/boot/dts/ti/omap/omap4.dtsi
+++ b/arch/arm/boot/dts/ti/omap/omap4.dtsi
@@ -501,10 +501,11 @@
#size-cells = <1>;
ranges = <0 0x56000000 0x2000000>;
- /*
- * Closed source PowerVR driver, no child device
- * binding or driver in mainline
- */
+ gpu@0 {
+ compatible = "ti,omap4430-gpu", "img,powervr-sgx540";
+ reg = <0x0 0x2000000>; /* 32MB */
+ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+ };
};
/*
diff --git a/arch/arm/boot/dts/ti/omap/omap5-igep0050.dts b/arch/arm/boot/dts/ti/omap/omap5-igep0050.dts
index d4ca2e3a14dd..0368e32f67e7 100644
--- a/arch/arm/boot/dts/ti/omap/omap5-igep0050.dts
+++ b/arch/arm/boot/dts/ti/omap/omap5-igep0050.dts
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (C) 2013 ISEE 2007 SL - http://www.isee.biz/
+ * Copyright (C) 2013 ISEE 2007 SL - https://www.isee.biz/
*/
/dts-v1/;
diff --git a/arch/arm/boot/dts/ti/omap/omap5.dtsi b/arch/arm/boot/dts/ti/omap/omap5.dtsi
index bac6fa838793..6a66214ad0e2 100644
--- a/arch/arm/boot/dts/ti/omap/omap5.dtsi
+++ b/arch/arm/boot/dts/ti/omap/omap5.dtsi
@@ -453,10 +453,11 @@
#size-cells = <1>;
ranges = <0 0x56000000 0x2000000>;
- /*
- * Closed source PowerVR driver, no child device
- * binding or driver in mainline
- */
+ gpu@0 {
+ compatible = "ti,omap5432-gpu", "img,powervr-sgx544";
+ reg = <0x0 0x2000000>; /* 32MB */
+ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+ };
};
target-module@58000000 {
diff --git a/arch/arm/boot/dts/ti/omap/twl4030.dtsi b/arch/arm/boot/dts/ti/omap/twl4030.dtsi
index 93e07c18781b..a5d9c5738317 100644
--- a/arch/arm/boot/dts/ti/omap/twl4030.dtsi
+++ b/arch/arm/boot/dts/ti/omap/twl4030.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2011 Texas Instruments Incorporated - https://www.ti.com/
*/
/*
diff --git a/arch/arm/boot/dts/ti/omap/twl6030.dtsi b/arch/arm/boot/dts/ti/omap/twl6030.dtsi
index 9d588cfaa5cb..8da969035c41 100644
--- a/arch/arm/boot/dts/ti/omap/twl6030.dtsi
+++ b/arch/arm/boot/dts/ti/omap/twl6030.dtsi
@@ -1,11 +1,11 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2011 Texas Instruments Incorporated - https://www.ti.com/
*/
/*
* Integrated Power Management Chip
- * http://www.ti.com/lit/ds/symlink/twl6030.pdf
+ * https://www.ti.com/lit/ds/symlink/twl6030.pdf
*/
&twl {
compatible = "ti,twl6030";
diff --git a/arch/arm/configs/aspeed_g4_defconfig b/arch/arm/configs/aspeed_g4_defconfig
index b3dc0465796f..28b724d59e7e 100644
--- a/arch/arm/configs/aspeed_g4_defconfig
+++ b/arch/arm/configs/aspeed_g4_defconfig
@@ -252,7 +252,7 @@ CONFIG_DEBUG_INFO_REDUCED=y
CONFIG_GDB_SCRIPTS=y
CONFIG_STRIP_ASM_SYMS=y
CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_WX=y
+CONFIG_ARM_DEBUG_WX=y
CONFIG_SCHED_STACK_END_CHECK=y
CONFIG_PANIC_ON_OOPS=y
CONFIG_PANIC_TIMEOUT=-1
diff --git a/arch/arm/configs/aspeed_g5_defconfig b/arch/arm/configs/aspeed_g5_defconfig
index 3fdf4dbfdea5..61cee1e7ebea 100644
--- a/arch/arm/configs/aspeed_g5_defconfig
+++ b/arch/arm/configs/aspeed_g5_defconfig
@@ -302,7 +302,7 @@ CONFIG_DEBUG_INFO_REDUCED=y
CONFIG_GDB_SCRIPTS=y
CONFIG_STRIP_ASM_SYMS=y
CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_WX=y
+CONFIG_ARM_DEBUG_WX=y
CONFIG_SCHED_STACK_END_CHECK=y
CONFIG_PANIC_ON_OOPS=y
CONFIG_PANIC_TIMEOUT=-1
diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig
index c98d5ff8a1ed..7ad48fdda1da 100644
--- a/arch/arm/configs/exynos_defconfig
+++ b/arch/arm/configs/exynos_defconfig
@@ -318,8 +318,11 @@ CONFIG_EXTCON_MAX77693=y
CONFIG_EXTCON_MAX8997=y
CONFIG_EXYNOS5422_DMC=y
CONFIG_IIO=y
+CONFIG_IIO_ST_ACCEL_3AXIS=m
+# CONFIG_IIO_ST_ACCEL_SPI_3AXIS is not set
CONFIG_EXYNOS_ADC=y
CONFIG_STMPE_ADC=y
+CONFIG_IIO_ST_GYRO_3AXIS=m
CONFIG_CM36651=y
CONFIG_AK8975=y
CONFIG_SENSORS_ISL29018=y
diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 8f9dbe8d9029..7327fce87808 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -208,6 +208,7 @@ CONFIG_PINCTRL_IMX8MQ=y
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_MXC=y
CONFIG_GPIO_SIOX=m
+CONFIG_GPIO_VF610=y
CONFIG_GPIO_MAX732X=y
CONFIG_GPIO_PCA953X=y
CONFIG_GPIO_PCF857X=y
@@ -228,7 +229,6 @@ CONFIG_SENSORS_IIO_HWMON=y
CONFIG_SENSORS_PWM_FAN=y
CONFIG_SENSORS_SY7636A=y
CONFIG_THERMAL_STATISTICS=y
-CONFIG_THERMAL_WRITABLE_TRIPS=y
CONFIG_CPU_THERMAL=y
CONFIG_IMX_THERMAL=y
CONFIG_WATCHDOG=y
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index ecb3e286107a..b2955dcb5a53 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -183,6 +183,7 @@ CONFIG_PCIE_RCAR_HOST=y
CONFIG_PCI_RCAR_GEN2=y
CONFIG_PCI_LAYERSCAPE=y
CONFIG_PCI_DRA7XX_EP=y
+CONFIG_PCI_KEYSTONE_HOST=y
CONFIG_PCI_ENDPOINT=y
CONFIG_PCI_ENDPOINT_CONFIGFS=y
CONFIG_PCI_EPF_TEST=m
@@ -191,6 +192,7 @@ CONFIG_DEVTMPFS_MOUNT=y
CONFIG_OMAP_OCP2SCP=y
CONFIG_ARM_SCMI_PROTOCOL=y
CONFIG_RASPBERRYPI_FIRMWARE=y
+CONFIG_TI_SCI_PROTOCOL=y
CONFIG_TRUSTED_FOUNDATIONS=y
CONFIG_BCM47XX_NVRAM=y
CONFIG_BCM47XX_SPROM=y
@@ -280,6 +282,8 @@ CONFIG_DWMAC_DWC_QOS_ETH=y
CONFIG_TI_CPSW=y
CONFIG_TI_CPSW_SWITCHDEV=y
CONFIG_TI_CPTS=y
+CONFIG_TI_KEYSTONE_NETCP=y
+CONFIG_TI_KEYSTONE_NETCP_ETHSS=y
CONFIG_XILINX_EMACLITE=y
CONFIG_SFP=m
CONFIG_BROADCOM_PHY=y
@@ -292,6 +296,8 @@ CONFIG_CAN_AT91=m
CONFIG_CAN_FLEXCAN=m
CONFIG_CAN_SUN4I=y
CONFIG_CAN_XILINXCAN=y
+CONFIG_CAN_C_CAN=m
+CONFIG_CAN_C_CAN_PLATFORM=m
CONFIG_CAN_RCAR=m
CONFIG_CAN_MCP251X=y
CONFIG_MDIO_MSCC_MIIM=m
@@ -335,6 +341,7 @@ CONFIG_INPUT_MISC=y
CONFIG_INPUT_PM8941_PWRKEY=y
CONFIG_INPUT_MAX77693_HAPTIC=m
CONFIG_INPUT_MAX8997_HAPTIC=m
+CONFIG_INPUT_GPIO_DECODER=m
CONFIG_INPUT_CPCAP_PWRBUTTON=m
CONFIG_INPUT_AXP20X_PEK=m
CONFIG_INPUT_DA9063_ONKEY=m
@@ -436,6 +443,7 @@ CONFIG_SPI_ATMEL_QUADSPI=m
CONFIG_SPI_BCM2835=y
CONFIG_SPI_BCM2835AUX=y
CONFIG_SPI_CADENCE=y
+CONFIG_SPI_CADENCE_QUADSPI=y
CONFIG_SPI_DAVINCI=y
CONFIG_SPI_FSL_QUADSPI=m
CONFIG_SPI_GXP=m
@@ -769,6 +777,7 @@ CONFIG_FB_EFI=y
CONFIG_FB_WM8505=y
CONFIG_FB_SH_MOBILE_LCDC=y
CONFIG_FB_SIMPLE=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
CONFIG_BACKLIGHT_PWM=y
CONFIG_BACKLIGHT_AS3711=y
CONFIG_BACKLIGHT_GPIO=y
@@ -1047,7 +1056,6 @@ CONFIG_KEYBOARD_NVEC=y
CONFIG_SERIO_NVEC_PS2=y
CONFIG_NVEC_POWER=y
CONFIG_NVEC_PAZ00=y
-CONFIG_STAGING_BOARD=y
CONFIG_CHROME_PLATFORMS=y
CONFIG_CROS_EC=m
CONFIG_CROS_EC_I2C=m
@@ -1073,6 +1081,7 @@ CONFIG_HWSPINLOCK_OMAP=y
CONFIG_HWSPINLOCK_QCOM=y
CONFIG_OMAP2PLUS_MBOX=y
CONFIG_BCM2835_MBOX=y
+CONFIG_TI_MESSAGE_MANAGER=y
CONFIG_QCOM_APCS_IPC=y
CONFIG_STM32_IPCC=m
CONFIG_QCOM_IPCC=y
@@ -1133,11 +1142,15 @@ CONFIG_ARCH_TEGRA_2x_SOC=y
CONFIG_ARCH_TEGRA_3x_SOC=y
CONFIG_ARCH_TEGRA_114_SOC=y
CONFIG_ARCH_TEGRA_124_SOC=y
+CONFIG_SOC_TI=y
+CONFIG_KEYSTONE_NAVIGATOR_QMSS=y
+CONFIG_KEYSTONE_NAVIGATOR_DMA=y
CONFIG_RASPBERRYPI_POWER=y
CONFIG_QCOM_CPR=y
CONFIG_QCOM_RPMHPD=y
CONFIG_QCOM_RPMPD=y
CONFIG_ROCKCHIP_PM_DOMAINS=y
+CONFIG_TI_SCI_PM_DOMAINS=y
CONFIG_ARM_EXYNOS_BUS_DEVFREQ=m
CONFIG_ARM_TEGRA_DEVFREQ=m
CONFIG_DEVFREQ_EVENT_EXYNOS_NOCP=m
@@ -1150,6 +1163,8 @@ CONFIG_STM32_FMC2_EBI=y
CONFIG_EXYNOS5422_DMC=m
CONFIG_IIO=y
CONFIG_IIO_SW_TRIGGER=y
+CONFIG_IIO_ST_ACCEL_3AXIS=m
+# CONFIG_IIO_ST_ACCEL_SPI_3AXIS is not set
CONFIG_ASPEED_ADC=m
CONFIG_AT91_ADC=m
CONFIG_AT91_SAMA5D2_ADC=m
@@ -1169,6 +1184,7 @@ CONFIG_IIO_CROS_EC_SENSORS_CORE=m
CONFIG_IIO_CROS_EC_SENSORS=m
CONFIG_STM32_DAC=m
CONFIG_MPU3050_I2C=y
+CONFIG_IIO_ST_GYRO_3AXIS=m
CONFIG_CM36651=m
CONFIG_IIO_CROS_EC_LIGHT_PROX=m
CONFIG_SENSORS_ISL29018=y
@@ -1193,10 +1209,13 @@ CONFIG_PWM_STM32=m
CONFIG_PWM_STM32_LP=m
CONFIG_PWM_SUN4I=y
CONFIG_PWM_TEGRA=y
+CONFIG_PWM_TIECAP=m
CONFIG_PWM_VT8500=y
CONFIG_KEYSTONE_IRQ=y
CONFIG_RESET_MCHP_SPARX5=y
CONFIG_RESET_SCMI=y
+CONFIG_RESET_TI_SCI=m
+CONFIG_RESET_TI_SYSCON=m
CONFIG_PHY_SUN4I_USB=y
CONFIG_PHY_SUN9I_USB=y
CONFIG_PHY_BRCM_USB=m
diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig
index c47a638172a8..091e1840933c 100644
--- a/arch/arm/configs/shmobile_defconfig
+++ b/arch/arm/configs/shmobile_defconfig
@@ -191,8 +191,6 @@ CONFIG_DW_DMAC=y
CONFIG_RZN1_DMAMUX=y
CONFIG_RCAR_DMAC=y
CONFIG_RENESAS_USB_DMAC=y
-CONFIG_STAGING=y
-CONFIG_STAGING_BOARD=y
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_ARCH_EMEV2=y
CONFIG_ARCH_R8A7794=y
diff --git a/arch/arm/crypto/sha256_glue.c b/arch/arm/crypto/sha256_glue.c
index 433ee4ddce6c..f85933fdec75 100644
--- a/arch/arm/crypto/sha256_glue.c
+++ b/arch/arm/crypto/sha256_glue.c
@@ -24,8 +24,8 @@
#include "sha256_glue.h"
-asmlinkage void sha256_block_data_order(u32 *digest, const void *data,
- unsigned int num_blks);
+asmlinkage void sha256_block_data_order(struct sha256_state *state,
+ const u8 *data, int num_blks);
int crypto_sha256_arm_update(struct shash_desc *desc, const u8 *data,
unsigned int len)
@@ -33,23 +33,20 @@ int crypto_sha256_arm_update(struct shash_desc *desc, const u8 *data,
/* make sure casting to sha256_block_fn() is safe */
BUILD_BUG_ON(offsetof(struct sha256_state, state) != 0);
- return sha256_base_do_update(desc, data, len,
- (sha256_block_fn *)sha256_block_data_order);
+ return sha256_base_do_update(desc, data, len, sha256_block_data_order);
}
EXPORT_SYMBOL(crypto_sha256_arm_update);
static int crypto_sha256_arm_final(struct shash_desc *desc, u8 *out)
{
- sha256_base_do_finalize(desc,
- (sha256_block_fn *)sha256_block_data_order);
+ sha256_base_do_finalize(desc, sha256_block_data_order);
return sha256_base_finish(desc, out);
}
int crypto_sha256_arm_finup(struct shash_desc *desc, const u8 *data,
unsigned int len, u8 *out)
{
- sha256_base_do_update(desc, data, len,
- (sha256_block_fn *)sha256_block_data_order);
+ sha256_base_do_update(desc, data, len, sha256_block_data_order);
return crypto_sha256_arm_final(desc, out);
}
EXPORT_SYMBOL(crypto_sha256_arm_finup);
diff --git a/arch/arm/crypto/sha512-glue.c b/arch/arm/crypto/sha512-glue.c
index 0635a65aa488..1be5bd498af3 100644
--- a/arch/arm/crypto/sha512-glue.c
+++ b/arch/arm/crypto/sha512-glue.c
@@ -25,27 +25,25 @@ MODULE_ALIAS_CRYPTO("sha512");
MODULE_ALIAS_CRYPTO("sha384-arm");
MODULE_ALIAS_CRYPTO("sha512-arm");
-asmlinkage void sha512_block_data_order(u64 *state, u8 const *src, int blocks);
+asmlinkage void sha512_block_data_order(struct sha512_state *state,
+ u8 const *src, int blocks);
int sha512_arm_update(struct shash_desc *desc, const u8 *data,
unsigned int len)
{
- return sha512_base_do_update(desc, data, len,
- (sha512_block_fn *)sha512_block_data_order);
+ return sha512_base_do_update(desc, data, len, sha512_block_data_order);
}
static int sha512_arm_final(struct shash_desc *desc, u8 *out)
{
- sha512_base_do_finalize(desc,
- (sha512_block_fn *)sha512_block_data_order);
+ sha512_base_do_finalize(desc, sha512_block_data_order);
return sha512_base_finish(desc, out);
}
int sha512_arm_finup(struct shash_desc *desc, const u8 *data,
unsigned int len, u8 *out)
{
- sha512_base_do_update(desc, data, len,
- (sha512_block_fn *)sha512_block_data_order);
+ sha512_base_do_update(desc, data, len, sha512_block_data_order);
return sha512_arm_final(desc, out);
}
diff --git a/arch/arm/include/asm/cachetype.h b/arch/arm/include/asm/cachetype.h
index e8c30430be33..b9dbe1d4c8fe 100644
--- a/arch/arm/include/asm/cachetype.h
+++ b/arch/arm/include/asm/cachetype.h
@@ -20,6 +20,8 @@ extern unsigned int cacheid;
#define icache_is_vipt_aliasing() cacheid_is(CACHEID_VIPT_I_ALIASING)
#define icache_is_pipt() cacheid_is(CACHEID_PIPT)
+#define cpu_dcache_is_aliasing() (cache_is_vivt() || cache_is_vipt_aliasing())
+
/*
* __LINUX_ARM_ARCH__ is the minimum supported CPU architecture
* Mask out support which will never be present on newer CPUs.
diff --git a/arch/arm/include/asm/current.h b/arch/arm/include/asm/current.h
index 1e1178bf176d..5225cb1c803b 100644
--- a/arch/arm/include/asm/current.h
+++ b/arch/arm/include/asm/current.h
@@ -18,18 +18,12 @@ static __always_inline __attribute_const__ struct task_struct *get_current(void)
{
struct task_struct *cur;
-#if __has_builtin(__builtin_thread_pointer) && \
- defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO) && \
- !(defined(CONFIG_THUMB2_KERNEL) && \
- defined(CONFIG_CC_IS_CLANG) && CONFIG_CLANG_VERSION < 130001)
+#if __has_builtin(__builtin_thread_pointer) && defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO)
/*
* Use the __builtin helper when available - this results in better
* code, especially when using GCC in combination with the per-task
* stack protector, as the compiler will recognize that it needs to
* load the TLS register only once in every function.
- *
- * Clang < 13.0.1 gets this wrong for Thumb2 builds:
- * https://github.com/ClangBuiltLinux/linux/issues/1485
*/
cur = __builtin_thread_pointer();
#elif defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO) || defined(CONFIG_SMP)
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index d68101655b74..9f21e170320f 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -4,7 +4,6 @@
#include <asm/auxvec.h>
#include <asm/hwcap.h>
-#include <asm/vdso_datapage.h>
/*
* ELF register definitions..
diff --git a/arch/arm/include/asm/mman.h b/arch/arm/include/asm/mman.h
new file mode 100644
index 000000000000..2189e507c8e0
--- /dev/null
+++ b/arch/arm/include/asm/mman.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_MMAN_H__
+#define __ASM_MMAN_H__
+
+#include <asm/system_info.h>
+#include <uapi/asm/mman.h>
+
+static inline bool arch_memory_deny_write_exec_supported(void)
+{
+ return cpu_architecture() >= CPU_ARCH_ARMv6;
+}
+#define arch_memory_deny_write_exec_supported arch_memory_deny_write_exec_supported
+
+#endif /* __ASM_MMAN_H__ */
diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
index 119aa85d1feb..62af9f7f9e96 100644
--- a/arch/arm/include/asm/page.h
+++ b/arch/arm/include/asm/page.h
@@ -8,7 +8,7 @@
#define _ASMARM_PAGE_H
/* PAGE_SHIFT determines the page size */
-#define PAGE_SHIFT 12
+#define PAGE_SHIFT CONFIG_PAGE_SHIFT
#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1))
diff --git a/arch/arm/include/asm/pgtable-2level.h b/arch/arm/include/asm/pgtable-2level.h
index ce543cd9380c..b0a262566eb9 100644
--- a/arch/arm/include/asm/pgtable-2level.h
+++ b/arch/arm/include/asm/pgtable-2level.h
@@ -213,7 +213,6 @@ 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_large(pmd) (pmd_val(pmd) & 2)
#define pmd_leaf(pmd) (pmd_val(pmd) & 2)
#define pmd_bad(pmd) (pmd_val(pmd) & 2)
#define pmd_present(pmd) (pmd_val(pmd))
diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h
index 71c3add6417f..4b1d9eb3908a 100644
--- a/arch/arm/include/asm/pgtable-3level.h
+++ b/arch/arm/include/asm/pgtable-3level.h
@@ -118,7 +118,6 @@
PMD_TYPE_TABLE)
#define pmd_sect(pmd) ((pmd_val(pmd) & PMD_TYPE_MASK) == \
PMD_TYPE_SECT)
-#define pmd_large(pmd) pmd_sect(pmd)
#define pmd_leaf(pmd) pmd_sect(pmd)
#define pud_clear(pudp) \
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index d657b84b6bf7..be91e376df79 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -209,6 +209,8 @@ static inline void __sync_icache_dcache(pte_t pteval)
extern void __sync_icache_dcache(pte_t pteval);
#endif
+#define PFN_PTE_SHIFT PAGE_SHIFT
+
void set_ptes(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pteval, unsigned int nr);
#define set_ptes set_ptes
diff --git a/arch/arm/include/asm/ptdump.h b/arch/arm/include/asm/ptdump.h
index aad1d034136c..46a4575146ee 100644
--- a/arch/arm/include/asm/ptdump.h
+++ b/arch/arm/include/asm/ptdump.h
@@ -32,10 +32,10 @@ void ptdump_check_wx(void);
#endif /* CONFIG_ARM_PTDUMP_CORE */
-#ifdef CONFIG_DEBUG_WX
-#define debug_checkwx() ptdump_check_wx()
+#ifdef CONFIG_ARM_DEBUG_WX
+#define arm_debug_checkwx() ptdump_check_wx()
#else
-#define debug_checkwx() do { } while (0)
+#define arm_debug_checkwx() do { } while (0)
#endif
#endif /* __ASM_PTDUMP_H */
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h
index 7f44e88d1f25..14a38cc67e0b 100644
--- a/arch/arm/include/asm/ptrace.h
+++ b/arch/arm/include/asm/ptrace.h
@@ -10,6 +10,7 @@
#include <uapi/asm/ptrace.h>
#ifndef __ASSEMBLY__
+#include <linux/bitfield.h>
#include <linux/types.h>
struct pt_regs {
@@ -35,8 +36,8 @@ struct svc_pt_regs {
#ifndef CONFIG_CPU_V7M
#define isa_mode(regs) \
- ((((regs)->ARM_cpsr & PSR_J_BIT) >> (__ffs(PSR_J_BIT) - 1)) | \
- (((regs)->ARM_cpsr & PSR_T_BIT) >> (__ffs(PSR_T_BIT))))
+ (FIELD_GET(PSR_J_BIT, (regs)->ARM_cpsr) << 1 | \
+ FIELD_GET(PSR_T_BIT, (regs)->ARM_cpsr))
#else
#define isa_mode(regs) 1 /* Thumb */
#endif
diff --git a/arch/arm/include/asm/vdso_datapage.h b/arch/arm/include/asm/vdso_datapage.h
deleted file mode 100644
index bef68f59928d..000000000000
--- a/arch/arm/include/asm/vdso_datapage.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Adapted from arm64 version.
- *
- * Copyright (C) 2012 ARM Limited
- */
-#ifndef __ASM_VDSO_DATAPAGE_H
-#define __ASM_VDSO_DATAPAGE_H
-
-#ifdef __KERNEL__
-
-#ifndef __ASSEMBLY__
-
-#include <vdso/datapage.h>
-#include <asm/page.h>
-
-union vdso_data_store {
- struct vdso_data data[CS_BASES];
- u8 page[PAGE_SIZE];
-};
-
-#endif /* !__ASSEMBLY__ */
-
-#endif /* __KERNEL__ */
-
-#endif /* __ASM_VDSO_DATAPAGE_H */
diff --git a/arch/arm/include/asm/word-at-a-time.h b/arch/arm/include/asm/word-at-a-time.h
index 352ab213520d..f9a3897b06e7 100644
--- a/arch/arm/include/asm/word-at-a-time.h
+++ b/arch/arm/include/asm/word-at-a-time.h
@@ -8,7 +8,8 @@
* Little-endian word-at-a-time zero byte handling.
* Heavily based on the x86 algorithm.
*/
-#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/wordpart.h>
struct word_at_a_time {
const unsigned long one_bits, high_bits;
diff --git a/arch/arm/include/debug/brcmstb.S b/arch/arm/include/debug/brcmstb.S
index f6175e6e28cd..3f7d68740ed4 100644
--- a/arch/arm/include/debug/brcmstb.S
+++ b/arch/arm/include/debug/brcmstb.S
@@ -27,6 +27,7 @@
#define UARTA_72165 UARTA_7278
#define UARTA_7364 REG_PHYS_ADDR(0x40b000)
#define UARTA_7366 UARTA_7364
+#define UARTA_74165 UARTA_7278
#define UARTA_74371 REG_PHYS_ADDR(0x406b00)
#define UARTA_7439 REG_PHYS_ADDR(0x40a900)
#define UARTA_7445 REG_PHYS_ADDR(0x40ab00)
@@ -88,9 +89,10 @@ ARM_BE8( rev \rv, \rv )
30: checkuart(\rp, \rv, 0x72780000, 7278)
31: checkuart(\rp, \rv, 0x73640000, 7364)
32: checkuart(\rp, \rv, 0x73660000, 7366)
-33: checkuart(\rp, \rv, 0x07437100, 74371)
-34: checkuart(\rp, \rv, 0x74390000, 7439)
-35: checkuart(\rp, \rv, 0x74450000, 7445)
+33: checkuart(\rp, \rv, 0x07416500, 74165)
+34: checkuart(\rp, \rv, 0x07437100, 74371)
+35: checkuart(\rp, \rv, 0x74390000, 7439)
+36: checkuart(\rp, \rv, 0x74450000, 7445)
/* No valid UART found */
90: mov \rp, #0
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 771264d4726a..89a77e3f51d2 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -60,6 +60,7 @@ obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o insn.o patch.o
obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o patch.o
obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o
obj-$(CONFIG_KEXEC_CORE) += machine_kexec.o relocate_kernel.o
+obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o
# Main staffs in KPROBES are in arch/arm/probes/ .
obj-$(CONFIG_KPROBES) += patch.o insn.o
obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o
@@ -75,8 +76,6 @@ obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
obj-$(CONFIG_CPU_XSCALE) += xscale-cp0.o
obj-$(CONFIG_CPU_XSC3) += xscale-cp0.o
obj-$(CONFIG_CPU_MOHAWK) += xscale-cp0.o
-obj-$(CONFIG_CPU_PJ4) += pj4-cp0.o
-obj-$(CONFIG_CPU_PJ4B) += pj4-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 \
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 219cbc7e5d13..4915662842ff 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -21,10 +21,12 @@
#include <asm/mpu.h>
#include <asm/procinfo.h>
#include <asm/suspend.h>
-#include <asm/vdso_datapage.h>
#include <asm/hardware/cache-l2x0.h>
#include <linux/kbuild.h>
#include <linux/arm-smccc.h>
+
+#include <vdso/datapage.h>
+
#include "signal.h"
/*
diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S
index a0218c4867b9..4a335d3c5969 100644
--- a/arch/arm/kernel/iwmmxt.S
+++ b/arch/arm/kernel/iwmmxt.S
@@ -18,18 +18,6 @@
#include <asm/assembler.h>
#include "iwmmxt.h"
-#if defined(CONFIG_CPU_PJ4) || defined(CONFIG_CPU_PJ4B)
-#define PJ4(code...) code
-#define XSC(code...)
-#elif defined(CONFIG_CPU_MOHAWK) || \
- defined(CONFIG_CPU_XSC3) || \
- defined(CONFIG_CPU_XSCALE)
-#define PJ4(code...)
-#define XSC(code...) code
-#else
-#error "Unsupported iWMMXt architecture"
-#endif
-
#define MMX_WR0 (0x00)
#define MMX_WR1 (0x08)
#define MMX_WR2 (0x10)
@@ -81,17 +69,13 @@ ENDPROC(iwmmxt_undef_handler)
ENTRY(iwmmxt_task_enable)
inc_preempt_count r10, r3
- XSC(mrc p15, 0, r2, c15, c1, 0)
- PJ4(mrc p15, 0, r2, c1, c0, 2)
+ mrc p15, 0, r2, c15, c1, 0
@ CP0 and CP1 accessible?
- XSC(tst r2, #0x3)
- PJ4(tst r2, #0xf)
+ tst r2, #0x3
bne 4f @ if so no business here
@ enable access to CP0 and CP1
- XSC(orr r2, r2, #0x3)
- XSC(mcr p15, 0, r2, c15, c1, 0)
- PJ4(orr r2, r2, #0xf)
- PJ4(mcr p15, 0, r2, c1, c0, 2)
+ orr r2, r2, #0x3
+ mcr p15, 0, r2, c15, c1, 0
ldr r3, =concan_owner
ldr r2, [r0, #S_PC] @ current task pc value
@@ -218,12 +202,9 @@ ENTRY(iwmmxt_task_disable)
bne 1f @ no: quit
@ enable access to CP0 and CP1
- XSC(mrc p15, 0, r4, c15, c1, 0)
- XSC(orr r4, r4, #0x3)
- XSC(mcr p15, 0, r4, c15, c1, 0)
- PJ4(mrc p15, 0, r4, c1, c0, 2)
- PJ4(orr r4, r4, #0xf)
- PJ4(mcr p15, 0, r4, c1, c0, 2)
+ mrc p15, 0, r4, c15, c1, 0
+ orr r4, r4, #0x3
+ mcr p15, 0, r4, c15, c1, 0
mov r0, #0 @ nothing to load
str r0, [r3] @ no more current owner
@@ -232,10 +213,8 @@ ENTRY(iwmmxt_task_disable)
bl concan_save
@ disable access to CP0 and CP1
- XSC(bic r4, r4, #0x3)
- XSC(mcr p15, 0, r4, c15, c1, 0)
- PJ4(bic r4, r4, #0xf)
- PJ4(mcr p15, 0, r4, c1, c0, 2)
+ bic r4, r4, #0x3
+ mcr p15, 0, r4, c15, c1, 0
mrc p15, 0, r2, c2, c0, 0
mov r2, r2 @ cpwait
@@ -330,11 +309,9 @@ ENDPROC(iwmmxt_task_restore)
*/
ENTRY(iwmmxt_task_switch)
- XSC(mrc p15, 0, r1, c15, c1, 0)
- PJ4(mrc p15, 0, r1, c1, c0, 2)
+ mrc p15, 0, r1, c15, c1, 0
@ CP0 and CP1 accessible?
- XSC(tst r1, #0x3)
- PJ4(tst r1, #0xf)
+ tst r1, #0x3
bne 1f @ yes: block them for next task
ldr r2, =concan_owner
@@ -344,10 +321,8 @@ ENTRY(iwmmxt_task_switch)
retne lr @ no: leave Concan disabled
1: @ flip Concan access
- XSC(eor r1, r1, #0x3)
- XSC(mcr p15, 0, r1, c15, c1, 0)
- PJ4(eor r1, r1, #0xf)
- PJ4(mcr p15, 0, r1, c1, c0, 2)
+ eor r1, r1, #0x3
+ mcr p15, 0, r1, c15, c1, 0
mrc p15, 0, r1, c2, c0, 0
sub pc, lr, r1, lsr #32 @ cpwait and return
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 5d07cf9e0044..80ceb5bd2680 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -198,10 +198,3 @@ void machine_kexec(struct kimage *image)
soft_restart(reboot_entry_phys);
}
-
-void arch_crash_save_vmcoreinfo(void)
-{
-#ifdef CONFIG_ARM_LPAE
- VMCOREINFO_CONFIG(ARM_LPAE);
-#endif
-}
diff --git a/arch/arm/kernel/pj4-cp0.c b/arch/arm/kernel/pj4-cp0.c
deleted file mode 100644
index 4bca8098c4ff..000000000000
--- a/arch/arm/kernel/pj4-cp0.c
+++ /dev/null
@@ -1,135 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * linux/arch/arm/kernel/pj4-cp0.c
- *
- * PJ4 iWMMXt coprocessor context switching and handling
- *
- * Copyright (c) 2010 Marvell International Inc.
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <asm/thread_notify.h>
-#include <asm/cputype.h>
-
-static int iwmmxt_do(struct notifier_block *self, unsigned long cmd, void *t)
-{
- struct thread_info *thread = t;
-
- switch (cmd) {
- case THREAD_NOTIFY_FLUSH:
- /*
- * flush_thread() zeroes thread->fpstate, so no need
- * to do anything here.
- *
- * FALLTHROUGH: Ensure we don't try to overwrite our newly
- * initialised state information on the first fault.
- */
-
- case THREAD_NOTIFY_EXIT:
- iwmmxt_task_release(thread);
- break;
-
- case THREAD_NOTIFY_SWITCH:
- iwmmxt_task_switch(thread);
- break;
- }
-
- return NOTIFY_DONE;
-}
-
-static struct notifier_block __maybe_unused iwmmxt_notifier_block = {
- .notifier_call = iwmmxt_do,
-};
-
-
-static u32 __init pj4_cp_access_read(void)
-{
- u32 value;
-
- __asm__ __volatile__ (
- "mrc p15, 0, %0, c1, c0, 2\n\t"
- : "=r" (value));
- return value;
-}
-
-static void __init pj4_cp_access_write(u32 value)
-{
- u32 temp;
-
- __asm__ __volatile__ (
- "mcr p15, 0, %1, c1, c0, 2\n\t"
-#ifdef CONFIG_THUMB2_KERNEL
- "isb\n\t"
-#else
- "mrc p15, 0, %0, c1, c0, 2\n\t"
- "mov %0, %0\n\t"
- "sub pc, pc, #4\n\t"
-#endif
- : "=r" (temp) : "r" (value));
-}
-
-static int __init pj4_get_iwmmxt_version(void)
-{
- u32 cp_access, wcid;
-
- cp_access = pj4_cp_access_read();
- pj4_cp_access_write(cp_access | 0xf);
-
- /* check if coprocessor 0 and 1 are available */
- if ((pj4_cp_access_read() & 0xf) != 0xf) {
- pj4_cp_access_write(cp_access);
- return -ENODEV;
- }
-
- /* read iWMMXt coprocessor id register p1, c0 */
- __asm__ __volatile__ ("mrc p1, 0, %0, c0, c0, 0\n" : "=r" (wcid));
-
- pj4_cp_access_write(cp_access);
-
- /* iWMMXt v1 */
- if ((wcid & 0xffffff00) == 0x56051000)
- return 1;
- /* iWMMXt v2 */
- if ((wcid & 0xffffff00) == 0x56052000)
- return 2;
-
- return -EINVAL;
-}
-
-/*
- * Disable CP0/CP1 on boot, and let call_fpe() and the iWMMXt lazy
- * switch code handle iWMMXt context switching.
- */
-static int __init pj4_cp0_init(void)
-{
- u32 __maybe_unused cp_access;
- int vers;
-
- if (!cpu_is_pj4())
- return 0;
-
- vers = pj4_get_iwmmxt_version();
- if (vers < 0)
- return 0;
-
-#ifndef CONFIG_IWMMXT
- pr_info("PJ4 iWMMXt coprocessor detected, but kernel support is missing.\n");
-#else
- cp_access = pj4_cp_access_read() & ~0xf;
- pj4_cp_access_write(cp_access);
-
- pr_info("PJ4 iWMMXt v%d coprocessor enabled.\n", vers);
- elf_hwcap |= HWCAP_IWMMXT;
- thread_register_notifier(&iwmmxt_notifier_block);
- register_iwmmxt_undef_handler();
-#endif
-
- return 0;
-}
-
-late_initcall(pj4_cp0_init);
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index ff2299ce1ad7..7b33b157fca0 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -979,7 +979,7 @@ static int __init init_machine_late(void)
}
late_initcall(init_machine_late);
-#ifdef CONFIG_KEXEC
+#ifdef CONFIG_CRASH_RESERVE
/*
* The crash region must be aligned to 128MB to avoid
* zImage relocating below the reserved region.
@@ -1066,7 +1066,7 @@ static void __init reserve_crashkernel(void)
}
#else
static inline void reserve_crashkernel(void) {}
-#endif /* CONFIG_KEXEC */
+#endif /* CONFIG_CRASH_RESERVE*/
void __init hyp_mode_check(void)
{
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 3bad79db5d6e..72c82a4d63ac 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -220,7 +220,7 @@ void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
unsigned int fp, mode;
int ok = 1;
- printk("%sBacktrace: ", loglvl);
+ printk("%sCall trace: ", loglvl);
if (!tsk)
tsk = current;
diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
index 9d2192156087..f60547dadc93 100644
--- a/arch/arm/kernel/unwind.c
+++ b/arch/arm/kernel/unwind.c
@@ -524,6 +524,8 @@ void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk,
{
struct stackframe frame;
+ printk("%sCall trace: ", loglvl);
+
pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk);
if (!tsk)
diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c
index f297d66a8a76..d499ad461b00 100644
--- a/arch/arm/kernel/vdso.c
+++ b/arch/arm/kernel/vdso.c
@@ -21,7 +21,6 @@
#include <asm/cacheflush.h>
#include <asm/page.h>
#include <asm/vdso.h>
-#include <asm/vdso_datapage.h>
#include <clocksource/arm_arch_timer.h>
#include <vdso/helpers.h>
#include <vdso/vsyscall.h>
@@ -35,9 +34,6 @@ extern char vdso_start[], vdso_end[];
/* Total number of pages needed for the data and text portions of the VDSO. */
unsigned int vdso_total_pages __ro_after_init;
-/*
- * The VDSO data page.
- */
static union vdso_data_store vdso_data_store __page_aligned_data;
struct vdso_data *vdso_data = vdso_data_store.data;
diff --git a/arch/arm/kernel/vmcore_info.c b/arch/arm/kernel/vmcore_info.c
new file mode 100644
index 000000000000..1437aba47787
--- /dev/null
+++ b/arch/arm/kernel/vmcore_info.c
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/vmcore_info.h>
+
+void arch_crash_save_vmcoreinfo(void)
+{
+#ifdef CONFIG_ARM_LPAE
+ VMCOREINFO_CONFIG(ARM_LPAE);
+#endif
+}
diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig
index 8789d93a7c04..7318d8789e24 100644
--- a/arch/arm/mach-bcm/Kconfig
+++ b/arch/arm/mach-bcm/Kconfig
@@ -93,7 +93,6 @@ config ARCH_BCM_MOBILE
select ARM_ERRATA_775420
select ARM_GIC
select GPIO_BCM_KONA
- select TICK_ONESHOT
select HAVE_ARM_ARCH_TIMER
select PINCTRL
select ARCH_BCM_MOBILE_SMP if SMP
diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c
index 444a7eaa320c..25893d109190 100644
--- a/arch/arm/mach-imx/mmdc.c
+++ b/arch/arm/mach-imx/mmdc.c
@@ -452,7 +452,7 @@ static int mmdc_pmu_init(struct mmdc_pmu *pmu_mmdc,
.active_events = 0,
};
- pmu_mmdc->id = ida_simple_get(&mmdc_ida, 0, 0, GFP_KERNEL);
+ pmu_mmdc->id = ida_alloc(&mmdc_ida, GFP_KERNEL);
return pmu_mmdc->id;
}
@@ -461,7 +461,7 @@ static void imx_mmdc_remove(struct platform_device *pdev)
{
struct mmdc_pmu *pmu_mmdc = platform_get_drvdata(pdev);
- ida_simple_remove(&mmdc_ida, pmu_mmdc->id);
+ ida_free(&mmdc_ida, pmu_mmdc->id);
cpuhp_state_remove_instance_nocalls(cpuhp_mmdc_state, &pmu_mmdc->node);
perf_pmu_unregister(&pmu_mmdc->pmu);
iounmap(pmu_mmdc->mmdc_base);
@@ -529,7 +529,7 @@ pmu_register_err:
cpuhp_state_remove_instance_nocalls(cpuhp_mmdc_state, &pmu_mmdc->node);
hrtimer_cancel(&pmu_mmdc->hrtimer);
pmu_release_id:
- ida_simple_remove(&mmdc_ida, pmu_mmdc->id);
+ ida_free(&mmdc_ida, pmu_mmdc->id);
pmu_free:
kfree(pmu_mmdc);
return ret;
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
index cbf703f0d850..a643b71e30a3 100644
--- a/arch/arm/mach-omap1/Kconfig
+++ b/arch/arm/mach-omap1/Kconfig
@@ -4,7 +4,6 @@ menuconfig ARCH_OMAP1
depends on ARCH_MULTI_V4T || ARCH_MULTI_V5
depends on CPU_LITTLE_ENDIAN
depends on ATAGS
- select ARCH_OMAP
select ARCH_HAS_HOLES_MEMORYMODEL
select ARCH_OMAP
select CLKSRC_MMIO
diff --git a/arch/arm/mach-omap2/am33xx-restart.c b/arch/arm/mach-omap2/am33xx-restart.c
index ef2f18a56b65..fcf3d557aa78 100644
--- a/arch/arm/mach-omap2/am33xx-restart.c
+++ b/arch/arm/mach-omap2/am33xx-restart.c
@@ -9,7 +9,7 @@
#include "prm.h"
/**
- * am3xx_restart - trigger a software restart of the SoC
+ * am33xx_restart - trigger a software restart of the SoC
* @mode: the "reboot mode", see arch/arm/kernel/{setup,process}.c
* @cmd: passed from the userspace program rebooting the system (if provided)
*
@@ -18,7 +18,8 @@
*/
void am33xx_restart(enum reboot_mode mode, const char *cmd)
{
- /* TODO: Handle mode and cmd if necessary */
+ /* TODO: Handle cmd if necessary */
+ prm_reboot_mode = mode;
omap_prm_reset_system();
}
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index fde6ccb3df6e..68e0baad2bbf 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -246,6 +246,12 @@ DT_MACHINE_START(AM33XX_DT, "Generic AM33XX (Flattened Device Tree)")
.init_time = omap_init_time_of,
.dt_compat = am33xx_boards_compat,
.restart = am33xx_restart,
+ /*
+ * Historically am33xx supported only REBOOT_WARM even though default
+ * reboot_mode was REBOOT_COLD. Reflect legacy de-facto behaviour in
+ * SYSFS.
+ */
+ .reboot_mode = REBOOT_WARM,
MACHINE_END
#endif
diff --git a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
index be4557d1fdac..011076a5952f 100644
--- a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
+++ b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
@@ -162,7 +162,7 @@ static int omap2_select_table_rate(struct clk_hw *hw, unsigned long rate,
}
/**
- * omap2xxx_clkt_vps_check_bootloader_rate - determine which of the rate
+ * omap2xxx_clkt_vps_check_bootloader_rates - determine which of the rate
* table sets matches the current CORE DPLL hardware rate
*
* Check the MPU rate set by bootloader. Sets the 'curr_prcm_set'
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index d145e7ac709b..69dc5b839335 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -990,7 +990,7 @@ void clkdm_allow_idle(struct clockdomain *clkdm)
}
/**
- * clkdm_deny_idle - disable hwsup idle transitions for clkdm
+ * clkdm_deny_idle_nolock - disable hwsup idle transitions for clkdm
* @clkdm: struct clockdomain *
*
* Prevent the hardware from automatically switching the clockdomain
@@ -1110,7 +1110,7 @@ void clkdm_del_autodeps(struct clockdomain *clkdm)
/**
* clkdm_clk_enable - add an enabled downstream clock to this clkdm
* @clkdm: struct clockdomain *
- * @clk: struct clk * of the enabled downstream clock
+ * @unused: struct clk * of the enabled downstream clock
*
* Increment the usecount of the clockdomain @clkdm and ensure that it
* is awake before @clk is enabled. Intended to be called by
diff --git a/arch/arm/mach-omap2/cm33xx.c b/arch/arm/mach-omap2/cm33xx.c
index c824d4e3db63..acdf72a541c0 100644
--- a/arch/arm/mach-omap2/cm33xx.c
+++ b/arch/arm/mach-omap2/cm33xx.c
@@ -357,7 +357,7 @@ static int am33xx_clkdm_save_context(struct clockdomain *clkdm)
}
/**
- * am33xx_restore_save_context - Restore the clockdomain transition context
+ * am33xx_clkdm_restore_context - Restore the clockdomain transition context
* @clkdm: The clockdomain pointer whose context needs to be restored
*
* Restore the clockdomain transition context.
diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c
index 46670521b278..49483a888046 100644
--- a/arch/arm/mach-omap2/cminst44xx.c
+++ b/arch/arm/mach-omap2/cminst44xx.c
@@ -237,7 +237,7 @@ static void omap4_cminst_clkdm_disable_hwsup(u8 part, u16 inst, u16 cdoffs)
}
/**
- * omap4_cminst_clkdm_force_sleep - try to take a clockdomain out of idle
+ * omap4_cminst_clkdm_force_wakeup - try to take a clockdomain out of idle
* @part: PRCM partition ID that the clockdomain registers exist in
* @inst: CM instance register offset (*_INST macro)
* @cdoffs: Clockdomain register offset (*_CDOFFS macro)
diff --git a/arch/arm/mach-omap2/omap-secure.c b/arch/arm/mach-omap2/omap-secure.c
index 29c7350b06ab..c2e1aecd07cc 100644
--- a/arch/arm/mach-omap2/omap-secure.c
+++ b/arch/arm/mach-omap2/omap-secure.c
@@ -47,7 +47,7 @@ static void __init omap_optee_init_check(void)
}
/**
- * omap_sec_dispatcher: Routine to dispatch low power secure
+ * omap_secure_dispatcher - Routine to dispatch low power secure
* service routines
* @idx: The HAL API index
* @flag: The flag indicating criticality of operation
@@ -183,7 +183,7 @@ static u32 rx51_secure_dispatcher(u32 idx, u32 process, u32 flag, u32 nargs,
/**
* rx51_secure_update_aux_cr: Routine to modify the contents of Auxiliary Control Register
* @set_bits: bits to set in ACR
- * @clr_bits: bits to clear in ACR
+ * @clear_bits: bits to clear in ACR
*
* Return the non-zero error value on failure.
*/
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index ba71928c0fcb..111677878d9c 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -900,7 +900,7 @@ static int _init_interface_clks(struct omap_hwmod *oh)
}
/**
- * _init_opt_clk - get a struct clk * for the hwmod's optional clocks
+ * _init_opt_clks - get a struct clk * for the hwmod's optional clocks
* @oh: struct omap_hwmod *
*
* Called from _init_clocks(). Populates the @oh omap_hwmod_opt_clk
@@ -2297,7 +2297,7 @@ static void __init parse_module_flags(struct omap_hwmod *oh,
/**
* _init - initialize internal data for the hwmod @oh
* @oh: struct omap_hwmod *
- * @n: (unused)
+ * @data: (unused)
*
* Look up the clocks and the address space used by the MPU to access
* registers belonging to the hwmod @oh. @oh must already be
@@ -2493,7 +2493,7 @@ static void _setup_postsetup(struct omap_hwmod *oh)
/**
* _setup - prepare IP block hardware for use
* @oh: struct omap_hwmod *
- * @n: (unused, pass NULL)
+ * @data: (unused, pass NULL)
*
* Configure the IP block represented by @oh. This may include
* enabling the IP block, resetting it, and placing it into a
@@ -3367,8 +3367,9 @@ static int omap_hwmod_check_module(struct device *dev,
* omap_hwmod_allocate_module - allocate new module
* @dev: struct device
* @oh: module
+ * @data: module data
* @sysc_fields: sysc register bits
- * @clockdomain: clockdomain
+ * @clkdm: clockdomain
* @rev_offs: revision register offset
* @sysc_offs: sysconfig register offset
* @syss_offs: sysstatus register offset
diff --git a/arch/arm/mach-omap2/omap_hwmod_common_data.c b/arch/arm/mach-omap2/omap_hwmod_common_data.c
index 246f1e5da99f..439232233c39 100644
--- a/arch/arm/mach-omap2/omap_hwmod_common_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_common_data.c
@@ -20,7 +20,7 @@
#include "omap_hwmod_common_data.h"
-/**
+/*
* struct omap_hwmod_sysc_type1 - TYPE1 sysconfig scheme.
*
* To be used by hwmod structure to specify the sysconfig offsets
@@ -36,7 +36,7 @@ struct sysc_regbits omap_hwmod_sysc_type1 = {
.autoidle_shift = SYSC_TYPE1_AUTOIDLE_SHIFT,
};
-/**
+/*
* struct omap_hwmod_sysc_type2 - TYPE2 sysconfig scheme.
*
* To be used by hwmod structure to specify the sysconfig offsets if the
@@ -50,7 +50,7 @@ struct sysc_regbits omap_hwmod_sysc_type2 = {
.dmadisable_shift = SYSC_TYPE2_DMADISABLE_SHIFT,
};
-/**
+/*
* struct omap_hwmod_sysc_type3 - TYPE3 sysconfig scheme.
* Used by some IPs on AM33xx
*/
diff --git a/arch/arm/mach-omap2/pmic-cpcap.c b/arch/arm/mach-omap2/pmic-cpcap.c
index 668dc84fd31e..4f31e61c0c90 100644
--- a/arch/arm/mach-omap2/pmic-cpcap.c
+++ b/arch/arm/mach-omap2/pmic-cpcap.c
@@ -18,10 +18,10 @@
#include "vc.h"
/**
- * omap_cpcap_vsel_to_vdc - convert CPCAP VSEL value to microvolts DC
+ * omap_cpcap_vsel_to_uv - convert CPCAP VSEL value to microvolts DC
* @vsel: CPCAP VSEL value to convert
*
- * Returns the microvolts DC that the CPCAP PMIC should generate when
+ * Returns: the microvolts DC that the CPCAP PMIC should generate when
* programmed with @vsel.
*/
static unsigned long omap_cpcap_vsel_to_uv(unsigned char vsel)
@@ -35,7 +35,7 @@ static unsigned long omap_cpcap_vsel_to_uv(unsigned char vsel)
* omap_cpcap_uv_to_vsel - convert microvolts DC to CPCAP VSEL value
* @uv: microvolts DC to convert
*
- * Returns the VSEL value necessary for the CPCAP PMIC to
+ * Returns: the VSEL value necessary for the CPCAP PMIC to
* generate an output voltage equal to or greater than @uv microvolts DC.
*/
static unsigned char omap_cpcap_uv_to_vsel(unsigned long uv)
@@ -82,10 +82,10 @@ static struct omap_voltdm_pmic omap_cpcap_iva = {
};
/**
- * omap_max8952_vsel_to_vdc - convert MAX8952 VSEL value to microvolts DC
+ * omap_max8952_vsel_to_uv - convert MAX8952 VSEL value to microvolts DC
* @vsel: MAX8952 VSEL value to convert
*
- * Returns the microvolts DC that the MAX8952 Regulator should generate when
+ * Returns: the microvolts DC that the MAX8952 Regulator should generate when
* programmed with @vsel.
*/
static unsigned long omap_max8952_vsel_to_uv(unsigned char vsel)
@@ -99,7 +99,7 @@ static unsigned long omap_max8952_vsel_to_uv(unsigned char vsel)
* omap_max8952_uv_to_vsel - convert microvolts DC to MAX8952 VSEL value
* @uv: microvolts DC to convert
*
- * Returns the VSEL value necessary for the MAX8952 Regulator to
+ * Returns: the VSEL value necessary for the MAX8952 Regulator to
* generate an output voltage equal to or greater than @uv microvolts DC.
*/
static unsigned char omap_max8952_uv_to_vsel(unsigned long uv)
@@ -129,10 +129,10 @@ static struct omap_voltdm_pmic omap443x_max8952_mpu = {
};
/**
- * omap_fan5355_vsel_to_vdc - convert FAN535503 VSEL value to microvolts DC
+ * omap_fan535503_vsel_to_uv - convert FAN535503 VSEL value to microvolts DC
* @vsel: FAN535503 VSEL value to convert
*
- * Returns the microvolts DC that the FAN535503 Regulator should generate when
+ * Returns: the microvolts DC that the FAN535503 Regulator should generate when
* programmed with @vsel.
*/
static unsigned long omap_fan535503_vsel_to_uv(unsigned char vsel)
@@ -144,10 +144,10 @@ static unsigned long omap_fan535503_vsel_to_uv(unsigned char vsel)
}
/**
- * omap_fan535508_vsel_to_vdc - convert FAN535508 VSEL value to microvolts DC
+ * omap_fan535508_vsel_to_uv - convert FAN535508 VSEL value to microvolts DC
* @vsel: FAN535508 VSEL value to convert
*
- * Returns the microvolts DC that the FAN535508 Regulator should generate when
+ * Returns: the microvolts DC that the FAN535508 Regulator should generate when
* programmed with @vsel.
*/
static unsigned long omap_fan535508_vsel_to_uv(unsigned char vsel)
@@ -165,7 +165,7 @@ static unsigned long omap_fan535508_vsel_to_uv(unsigned char vsel)
* omap_fan535503_uv_to_vsel - convert microvolts DC to FAN535503 VSEL value
* @uv: microvolts DC to convert
*
- * Returns the VSEL value necessary for the MAX8952 Regulator to
+ * Returns: the VSEL value necessary for the MAX8952 Regulator to
* generate an output voltage equal to or greater than @uv microvolts DC.
*/
static unsigned char omap_fan535503_uv_to_vsel(unsigned long uv)
@@ -184,7 +184,7 @@ static unsigned char omap_fan535503_uv_to_vsel(unsigned long uv)
* omap_fan535508_uv_to_vsel - convert microvolts DC to FAN535508 VSEL value
* @uv: microvolts DC to convert
*
- * Returns the VSEL value necessary for the MAX8952 Regulator to
+ * Returns: the VSEL value necessary for the MAX8952 Regulator to
* generate an output voltage equal to or greater than @uv microvolts DC.
*/
static unsigned char omap_fan535508_uv_to_vsel(unsigned long uv)
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 5e05dd1324e7..2441d96b7144 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -1162,7 +1162,7 @@ static int pwrdm_save_context(struct powerdomain *pwrdm, void *unused)
}
/**
- * pwrdm_save_context - restore powerdomain registers
+ * pwrdm_restore_context - restore powerdomain registers
*
* Restore powerdomain control registers after a suspend or resume
* event.
diff --git a/arch/arm/mach-omap2/prm-regbits-33xx.h b/arch/arm/mach-omap2/prm-regbits-33xx.h
index 3748c5266ae1..9b97f8c76cd1 100644
--- a/arch/arm/mach-omap2/prm-regbits-33xx.h
+++ b/arch/arm/mach-omap2/prm-regbits-33xx.h
@@ -15,6 +15,7 @@
#define AM33XX_GFX_MEM_STATEST_MASK (0x3 << 4)
#define AM33XX_GLOBAL_WARM_SW_RST_MASK (1 << 1)
#define AM33XX_RST_GLOBAL_WARM_SW_MASK (1 << 0)
+#define AM33XX_RST_GLOBAL_COLD_SW_MASK (1 << 1)
#define AM33XX_PRUSS_MEM_ONSTATE_MASK (0x3 << 5)
#define AM33XX_PRUSS_MEM_RETSTATE_MASK (1 << 7)
#define AM33XX_PRUSS_MEM_STATEST_MASK (0x3 << 23)
diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h
index fc45a7ed09bb..fc53a27eed01 100644
--- a/arch/arm/mach-omap2/prm.h
+++ b/arch/arm/mach-omap2/prm.h
@@ -15,6 +15,7 @@
# ifndef __ASSEMBLER__
extern struct omap_domain_base prm_base;
extern u16 prm_features;
+extern enum reboot_mode prm_reboot_mode;
int omap_prcm_init(void);
int omap2_prcm_base_init(void);
# endif
diff --git a/arch/arm/mach-omap2/prm33xx.c b/arch/arm/mach-omap2/prm33xx.c
index 4b65a0f9cf7d..505d685d6792 100644
--- a/arch/arm/mach-omap2/prm33xx.c
+++ b/arch/arm/mach-omap2/prm33xx.c
@@ -10,15 +10,12 @@
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/io.h>
+#include <linux/reboot.h>
#include "powerdomain.h"
#include "prm33xx.h"
#include "prm-regbits-33xx.h"
-#define AM33XX_PRM_RSTCTRL_OFFSET 0x0000
-
-#define AM33XX_RST_GLOBAL_WARM_SW_MASK (1 << 0)
-
/* Read a register in a PRM instance */
static u32 am33xx_prm_read_reg(s16 inst, u16 idx)
{
@@ -322,10 +319,19 @@ static int am33xx_check_vcvp(void)
*
* Immediately reboots the device through warm reset.
*/
-static void am33xx_prm_global_warm_sw_reset(void)
+static void am33xx_prm_global_sw_reset(void)
{
- am33xx_prm_rmw_reg_bits(AM33XX_RST_GLOBAL_WARM_SW_MASK,
- AM33XX_RST_GLOBAL_WARM_SW_MASK,
+ /*
+ * Historically AM33xx performed warm reset for all requested reboot_mode.
+ * Keep this behaviour unchanged for all except newly added REBOOT_COLD.
+ */
+ u32 mask = AM33XX_RST_GLOBAL_WARM_SW_MASK;
+
+ if (prm_reboot_mode == REBOOT_COLD)
+ mask = AM33XX_RST_GLOBAL_COLD_SW_MASK;
+
+ am33xx_prm_rmw_reg_bits(mask,
+ mask,
AM33XX_PRM_DEVICE_MOD,
AM33XX_PRM_RSTCTRL_OFFSET);
@@ -386,7 +392,7 @@ static struct prm_ll_data am33xx_prm_ll_data = {
.assert_hardreset = am33xx_prm_assert_hardreset,
.deassert_hardreset = am33xx_prm_deassert_hardreset,
.is_hardreset_asserted = am33xx_prm_is_hardreset_asserted,
- .reset_system = am33xx_prm_global_warm_sw_reset,
+ .reset_system = am33xx_prm_global_sw_reset,
};
int __init am33xx_prm_init(const struct omap_prcm_init_data *data)
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index 25093c1e5b9a..6c555438dd48 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -407,7 +407,7 @@ static bool omap44xx_prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx)
}
/**
- * omap44xx_prm_clear_context_lost_flags_old - clear context loss flags
+ * omap44xx_prm_clear_context_loss_flags_old - clear context loss flags
* @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
* @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
* @idx: CONTEXT register offset
diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c
index fd896f2295a1..ee4588acda50 100644
--- a/arch/arm/mach-omap2/prm_common.c
+++ b/arch/arm/mach-omap2/prm_common.c
@@ -67,6 +67,12 @@ struct omap_domain_base prm_base;
u16 prm_features;
/*
+ * Platforms that implement different reboot modes can store the requested
+ * mode here.
+ */
+enum reboot_mode prm_reboot_mode;
+
+/*
* prm_ll_data: function pointers to SoC-specific implementations of
* common PRM functions
*/
@@ -370,7 +376,7 @@ bool prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx)
}
/**
- * prm_clear_context_lost_flags_old - clear context loss flags (old API)
+ * prm_clear_context_loss_flags_old - clear context loss flags (old API)
* @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
* @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
* @idx: CONTEXT register offset
@@ -497,6 +503,7 @@ int omap_prm_clear_mod_irqs(s16 module, u8 regs, u32 wkst_mask)
/**
* omap_prm_vp_check_txdone - check voltage processor TX done status
+ * @vp_id: unique VP instance ID
*
* Checks if voltage processor transmission has been completed.
* Returns non-zero if a transmission has completed, 0 otherwise.
@@ -514,6 +521,7 @@ u32 omap_prm_vp_check_txdone(u8 vp_id)
/**
* omap_prm_vp_clear_txdone - clears voltage processor TX done status
+ * @vp_id: unique VP instance ID
*
* Clears the status bit for completed voltage processor transmission
* returned by prm_vp_check_txdone.
diff --git a/arch/arm/mach-omap2/wd_timer.c b/arch/arm/mach-omap2/wd_timer.c
index d4ea56a5f75a..898e7e332981 100644
--- a/arch/arm/mach-omap2/wd_timer.c
+++ b/arch/arm/mach-omap2/wd_timer.c
@@ -57,7 +57,7 @@ int omap2_wd_timer_disable(struct omap_hwmod *oh)
}
/**
- * omap2_wdtimer_reset - reset and disable the WDTIMER IP block
+ * omap2_wd_timer_reset - reset and disable the WDTIMER IP block
* @oh: struct omap_hwmod *
*
* After the WDTIMER IP blocks are reset on OMAP2/3, we must also take
@@ -71,6 +71,8 @@ int omap2_wd_timer_disable(struct omap_hwmod *oh)
* during a normal merge window. omap_hwmod_softreset() should be
* renamed to omap_hwmod_set_ocp_softreset(), and omap_hwmod_softreset()
* should call the hwmod _ocp_softreset() code.
+ *
+ * Returns: %0 on success or -errno value on error.
*/
int omap2_wd_timer_reset(struct omap_hwmod *oh)
{
diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig
index 12a812e61c16..f4765be1b2a0 100644
--- a/arch/arm/mach-qcom/Kconfig
+++ b/arch/arm/mach-qcom/Kconfig
@@ -4,46 +4,21 @@ menuconfig ARCH_QCOM
depends on ARCH_MULTI_V7
select ARM_GIC
select ARM_AMBA
+ select CLKSRC_QCOM
+ select HAVE_ARM_ARCH_TIMER
select PINCTRL
select QCOM_SCM if SMP
help
Support for Qualcomm's devicetree based systems.
+ This includes support for a few devices with ARM64 SoC, that have
+ ARM32 signed firmware that does not allow booting ARM64 kernels.
if ARCH_QCOM
-config ARCH_IPQ40XX
- bool "Enable support for IPQ40XX"
- select CLKSRC_QCOM
- select HAVE_ARM_ARCH_TIMER
-
-config ARCH_MSM8X60
- bool "Enable support for MSM8X60"
- select CLKSRC_QCOM
-
-config ARCH_MSM8909
- bool "Enable support for MSM8909"
- select HAVE_ARM_ARCH_TIMER
-
-config ARCH_MSM8916
- bool "Enable support for MSM8916"
- select HAVE_ARM_ARCH_TIMER
+config ARCH_QCOM_RESERVE_SMEM
+ bool "Reserve SMEM at the beginning of RAM"
help
- Enable support for the Qualcomm Snapdragon 410 (MSM8916/APQ8016).
-
- Note that ARM64 is the main supported architecture for MSM8916.
- The ARM32 option is intended for a few devices with signed firmware
- that does not allow booting ARM64 kernels.
-
-config ARCH_MSM8960
- bool "Enable support for MSM8960"
- select CLKSRC_QCOM
-
-config ARCH_MSM8974
- bool "Enable support for MSM8974"
- select HAVE_ARM_ARCH_TIMER
-
-config ARCH_MDM9615
- bool "Enable support for MDM9615"
- select CLKSRC_QCOM
+ Reserve 2MB at the beginning of the System RAM for shared mem.
+ This is required on IPQ40xx, MSM8x60 and MSM8960 platforms.
endif
diff --git a/arch/arm/mach-s3c/cpu.h b/arch/arm/mach-s3c/cpu.h
index d0adc9b40e25..a0187606b999 100644
--- a/arch/arm/mach-s3c/cpu.h
+++ b/arch/arm/mach-s3c/cpu.h
@@ -76,6 +76,6 @@ extern void s3c24xx_init_uartdevs(char *name,
struct s3c24xx_uart_resources *res,
struct s3c2410_uartcfg *cfg, int no);
-extern struct bus_type s3c6410_subsys;
+extern const struct bus_type s3c6410_subsys;
#endif
diff --git a/arch/arm/mach-s3c/s3c6410.c b/arch/arm/mach-s3c/s3c6410.c
index e79f18d0ca81..a29276a4fde5 100644
--- a/arch/arm/mach-s3c/s3c6410.c
+++ b/arch/arm/mach-s3c/s3c6410.c
@@ -57,7 +57,7 @@ void __init s3c6410_init_irq(void)
s3c64xx_init_irq(~0 & ~(1 << 7), ~0);
}
-struct bus_type s3c6410_subsys = {
+const struct bus_type s3c6410_subsys = {
.name = "s3c6410-core",
.dev_name = "s3c6410-core",
};
diff --git a/arch/arm/mach-s3c/s3c64xx.c b/arch/arm/mach-s3c/s3c64xx.c
index 9f9717874d67..6c70ea7f2931 100644
--- a/arch/arm/mach-s3c/s3c64xx.c
+++ b/arch/arm/mach-s3c/s3c64xx.c
@@ -149,7 +149,7 @@ static struct map_desc s3c_iodesc[] __initdata = {
},
};
-static struct bus_type s3c64xx_subsys = {
+static const struct bus_type s3c64xx_subsys = {
.name = "s3c64xx-core",
.dev_name = "s3c64xx-core",
};
diff --git a/arch/arm/mach-s5pv210/pm.c b/arch/arm/mach-s5pv210/pm.c
index d59c094cdea8..6fa70f787df4 100644
--- a/arch/arm/mach-s5pv210/pm.c
+++ b/arch/arm/mach-s5pv210/pm.c
@@ -47,7 +47,7 @@ static void s3c_pm_do_save(struct sleep_save *ptr, int count)
}
/**
- * s3c_pm_do_restore() - restore register values from the save list.
+ * s3c_pm_do_restore_core() - restore register values from the save list.
* @ptr: Pointer to an array of registers.
* @count: Size of the ptr array.
*
diff --git a/arch/arm/mach-zynq/slcr.c b/arch/arm/mach-zynq/slcr.c
index 9765b3f4c2fc..6aae14b0736c 100644
--- a/arch/arm/mach-zynq/slcr.c
+++ b/arch/arm/mach-zynq/slcr.c
@@ -10,7 +10,6 @@
#include <linux/mfd/syscon.h>
#include <linux/of_address.h>
#include <linux/regmap.h>
-#include <linux/clk/zynq.h>
#include "common.h"
/* register offsets */
@@ -146,7 +145,7 @@ void zynq_slcr_cpu_stop(int cpu)
}
/**
- * zynq_slcr_cpu_state - Read/write cpu state
+ * zynq_slcr_cpu_state_read - Read cpu state
* @cpu: cpu number
*
* SLCR_REBOOT_STATUS save upper 2 bits (31/30 cpu states for cpu0 and cpu1)
@@ -165,7 +164,7 @@ bool zynq_slcr_cpu_state_read(int cpu)
}
/**
- * zynq_slcr_cpu_state - Read/write cpu state
+ * zynq_slcr_cpu_state_write - Write cpu state
* @cpu: cpu number
* @die: cpu state - true if cpu is going to die
*
diff --git a/arch/arm/mm/dump.c b/arch/arm/mm/dump.c
index a9381095ab36..cd032522d902 100644
--- a/arch/arm/mm/dump.c
+++ b/arch/arm/mm/dump.c
@@ -349,12 +349,12 @@ static void walk_pmd(struct pg_state *st, pud_t *pud, unsigned long start)
for (i = 0; i < PTRS_PER_PMD; i++, pmd++) {
addr = start + i * PMD_SIZE;
domain = get_domain_name(pmd);
- if (pmd_none(*pmd) || pmd_large(*pmd) || !pmd_present(*pmd))
+ if (pmd_none(*pmd) || pmd_leaf(*pmd) || !pmd_present(*pmd))
note_page(st, addr, 4, pmd_val(*pmd), domain);
else
walk_pte(st, pmd, addr, domain);
- if (SECTION_SIZE < PMD_SIZE && pmd_large(pmd[1])) {
+ if (SECTION_SIZE < PMD_SIZE && pmd_leaf(pmd[1])) {
addr += SECTION_SIZE;
pmd++;
domain = get_domain_name(pmd);
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 07565b593ed6..439dc6a26bb9 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -25,6 +25,13 @@
#include "fault.h"
+bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
+{
+ unsigned long addr = (unsigned long)unsafe_src;
+
+ return addr >= TASK_SIZE && ULONG_MAX - addr >= size;
+}
+
#ifdef CONFIG_MMU
/*
@@ -588,6 +595,7 @@ do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs)
if (!inf->fn(addr, ifsr | FSR_LNX_PF, regs))
return;
+ pr_alert("8<--- cut here ---\n");
pr_alert("Unhandled prefetch abort: %s (0x%03x) at 0x%08lx\n",
inf->name, ifsr, addr);
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index d19d140a10c7..0749cf8a6637 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -296,6 +296,9 @@ void __sync_icache_dcache(pte_t pteval)
return;
folio = page_folio(pfn_to_page(pfn));
+ if (folio_test_reserved(folio))
+ return;
+
if (cache_is_vipt_aliasing())
mapping = folio_flush_mapping(folio);
else
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index a42e4cd11db2..e8c6f4be0ce1 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -418,7 +418,7 @@ static void set_section_perms(struct section_perm *perms, int n, bool set,
}
-/**
+/*
* update_sections_early intended to be called only through stop_machine
* framework and executed by only one CPU while all other CPUs will spin and
* wait, so no locking is required in this function.
@@ -458,7 +458,7 @@ static int __mark_rodata_ro(void *unused)
void mark_rodata_ro(void)
{
stop_machine(__mark_rodata_ro, NULL, NULL);
- debug_checkwx();
+ arm_debug_checkwx();
}
#else
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 2129070065c3..794cfea9f9d4 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -110,8 +110,8 @@ void __init add_static_vm_early(struct static_vm *svm)
int ioremap_page(unsigned long virt, unsigned long phys,
const struct mem_type *mtype)
{
- return ioremap_page_range(virt, virt + PAGE_SIZE, phys,
- __pgprot(mtype->prot_pte));
+ return vmap_page_range(virt, virt + PAGE_SIZE, phys,
+ __pgprot(mtype->prot_pte));
}
EXPORT_SYMBOL(ioremap_page);
@@ -466,8 +466,8 @@ int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr)
if (res->end > IO_SPACE_LIMIT)
return -EINVAL;
- return ioremap_page_range(vaddr, vaddr + resource_size(res), phys_addr,
- __pgprot(get_mem_type(pci_ioremap_mem_type)->prot_pte));
+ return vmap_page_range(vaddr, vaddr + resource_size(res), phys_addr,
+ __pgprot(get_mem_type(pci_ioremap_mem_type)->prot_pte));
}
EXPORT_SYMBOL(pci_remap_iospace);
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 674ed71573a8..c24e29c0b9a4 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -1814,6 +1814,6 @@ void set_ptes(struct mm_struct *mm, unsigned long addr,
if (--nr == 0)
break;
ptep++;
- pte_val(pteval) += PAGE_SIZE;
+ pteval = pte_next_pfn(pteval);
}
}
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index aa7c1d435139..7b11c98b3e84 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -107,7 +107,7 @@ config ARM64
select ARCH_WANT_LD_ORPHAN_WARN
select ARCH_WANTS_NO_INSTR
select ARCH_WANTS_THP_SWAP if ARM64_4K_PAGES
- select ARCH_HAS_UBSAN_SANITIZE_ALL
+ select ARCH_HAS_UBSAN
select ARM_AMBA
select ARM_ARCH_TIMER
select ARM_GIC
@@ -120,6 +120,7 @@ config ARM64
select CLONE_BACKWARDS
select COMMON_CLK
select CPU_PM if (SUSPEND || CPU_IDLE)
+ select CPUMASK_OFFSTACK if NR_CPUS > 256
select CRC32
select DCACHE_WORD_ACCESS
select DYNAMIC_FTRACE if FUNCTION_TRACER
@@ -164,7 +165,7 @@ config ARM64
select HAVE_ARCH_HUGE_VMAP
select HAVE_ARCH_JUMP_LABEL
select HAVE_ARCH_JUMP_LABEL_RELATIVE
- select HAVE_ARCH_KASAN if !(ARM64_16K_PAGES && ARM64_VA_BITS_48)
+ 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)
@@ -198,7 +199,7 @@ config ARM64
if DYNAMIC_FTRACE_WITH_ARGS && DYNAMIC_FTRACE_WITH_CALL_OPS
select HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS \
if (DYNAMIC_FTRACE_WITH_ARGS && !CFI_CLANG && \
- !CC_OPTIMIZE_FOR_SIZE)
+ (CC_IS_CLANG || !CC_OPTIMIZE_FOR_SIZE))
select FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY \
if DYNAMIC_FTRACE_WITH_ARGS
select HAVE_SAMPLE_FTRACE_DIRECT
@@ -216,7 +217,6 @@ config ARM64
select HAVE_HW_BREAKPOINT if PERF_EVENTS
select HAVE_IOREMAP_PROT
select HAVE_IRQ_TIME_ACCOUNTING
- select HAVE_KVM
select HAVE_MOD_ARCH_SPECIFIC
select HAVE_NMI
select HAVE_PERF_EVENTS
@@ -229,6 +229,7 @@ config ARM64
select HAVE_FUNCTION_ARG_ACCESS_API
select MMU_GATHER_RCU_TABLE_FREE
select HAVE_RSEQ
+ select HAVE_RUST if CPU_LITTLE_ENDIAN
select HAVE_STACKPROTECTOR
select HAVE_SYSCALL_TRACEPOINTS
select HAVE_KPROBES
@@ -277,27 +278,21 @@ config 64BIT
config MMU
def_bool y
-config ARM64_PAGE_SHIFT
- int
- default 16 if ARM64_64K_PAGES
- default 14 if ARM64_16K_PAGES
- default 12
-
config ARM64_CONT_PTE_SHIFT
int
- default 5 if ARM64_64K_PAGES
- default 7 if ARM64_16K_PAGES
+ default 5 if PAGE_SIZE_64KB
+ default 7 if PAGE_SIZE_16KB
default 4
config ARM64_CONT_PMD_SHIFT
int
- default 5 if ARM64_64K_PAGES
- default 5 if ARM64_16K_PAGES
+ default 5 if PAGE_SIZE_64KB
+ default 5 if PAGE_SIZE_16KB
default 4
config ARCH_MMAP_RND_BITS_MIN
- default 14 if ARM64_64K_PAGES
- default 16 if ARM64_16K_PAGES
+ default 14 if PAGE_SIZE_64KB
+ default 16 if PAGE_SIZE_16KB
default 18
# max bits determined by the following formula:
@@ -368,7 +363,9 @@ config PGTABLE_LEVELS
default 3 if ARM64_64K_PAGES && (ARM64_VA_BITS_48 || ARM64_VA_BITS_52)
default 3 if ARM64_4K_PAGES && ARM64_VA_BITS_39
default 3 if ARM64_16K_PAGES && ARM64_VA_BITS_47
+ default 4 if ARM64_16K_PAGES && (ARM64_VA_BITS_48 || ARM64_VA_BITS_52)
default 4 if !ARM64_64K_PAGES && ARM64_VA_BITS_48
+ default 5 if ARM64_4K_PAGES && ARM64_VA_BITS_52
config ARCH_SUPPORTS_UPROBES
def_bool y
@@ -382,8 +379,8 @@ config BROKEN_GAS_INST
config BUILTIN_RETURN_ADDRESS_STRIPS_PAC
bool
# Clang's __builtin_return_adddress() strips the PAC since 12.0.0
- # https://reviews.llvm.org/D75044
- default y if CC_IS_CLANG && (CLANG_VERSION >= 120000)
+ # 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,
# and this was backported to 10.2.0, 9.4.0, 8.5.0, but not earlier
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94891
@@ -396,13 +393,13 @@ config BUILTIN_RETURN_ADDRESS_STRIPS_PAC
config KASAN_SHADOW_OFFSET
hex
depends on KASAN_GENERIC || KASAN_SW_TAGS
- default 0xdfff800000000000 if (ARM64_VA_BITS_48 || ARM64_VA_BITS_52) && !KASAN_SW_TAGS
- default 0xdfffc00000000000 if ARM64_VA_BITS_47 && !KASAN_SW_TAGS
+ default 0xdfff800000000000 if (ARM64_VA_BITS_48 || (ARM64_VA_BITS_52 && !ARM64_16K_PAGES)) && !KASAN_SW_TAGS
+ default 0xdfffc00000000000 if (ARM64_VA_BITS_47 || ARM64_VA_BITS_52) && ARM64_16K_PAGES && !KASAN_SW_TAGS
default 0xdffffe0000000000 if ARM64_VA_BITS_42 && !KASAN_SW_TAGS
default 0xdfffffc000000000 if ARM64_VA_BITS_39 && !KASAN_SW_TAGS
default 0xdffffff800000000 if ARM64_VA_BITS_36 && !KASAN_SW_TAGS
- default 0xefff800000000000 if (ARM64_VA_BITS_48 || ARM64_VA_BITS_52) && KASAN_SW_TAGS
- default 0xefffc00000000000 if ARM64_VA_BITS_47 && KASAN_SW_TAGS
+ default 0xefff800000000000 if (ARM64_VA_BITS_48 || (ARM64_VA_BITS_52 && !ARM64_16K_PAGES)) && KASAN_SW_TAGS
+ default 0xefffc00000000000 if (ARM64_VA_BITS_47 || ARM64_VA_BITS_52) && ARM64_16K_PAGES && KASAN_SW_TAGS
default 0xeffffe0000000000 if ARM64_VA_BITS_42 && KASAN_SW_TAGS
default 0xefffffc000000000 if ARM64_VA_BITS_39 && KASAN_SW_TAGS
default 0xeffffff800000000 if ARM64_VA_BITS_36 && KASAN_SW_TAGS
@@ -547,9 +544,8 @@ config ARM64_ERRATUM_832075
If unsure, say Y.
config ARM64_ERRATUM_834220
- bool "Cortex-A57: 834220: Stage 2 translation fault might be incorrectly reported in presence of a Stage 1 fault"
+ bool "Cortex-A57: 834220: Stage 2 translation fault might be incorrectly reported in presence of a Stage 1 fault (rare)"
depends on KVM
- default y
help
This option adds an alternative code sequence to work around ARM
erratum 834220 on Cortex-A57 parts up to r1p2.
@@ -565,7 +561,7 @@ config ARM64_ERRATUM_834220
as it depends on the alternative framework, which will only patch
the kernel if an affected CPU is detected.
- If unsure, say Y.
+ If unsure, say N.
config ARM64_ERRATUM_1742098
bool "Cortex-A57/A72: 1742098: ELR recorded incorrectly on interrupt taken between cryptographic instructions in a sequence"
@@ -692,8 +688,7 @@ config ARM64_WORKAROUND_REPEAT_TLBI
bool
config ARM64_ERRATUM_2441007
- bool "Cortex-A55: Completion of affected memory accesses might not be guaranteed by completion of a TLBI"
- default y
+ bool "Cortex-A55: Completion of affected memory accesses might not be guaranteed by completion of a TLBI (rare)"
select ARM64_WORKAROUND_REPEAT_TLBI
help
This option adds a workaround for ARM Cortex-A55 erratum #2441007.
@@ -706,11 +701,10 @@ config ARM64_ERRATUM_2441007
Work around this by adding the affected CPUs to the list that needs
TLB sequences to be done twice.
- If unsure, say Y.
+ If unsure, say N.
config ARM64_ERRATUM_1286807
- bool "Cortex-A76: Modification of the translation table for a virtual address might lead to read-after-read ordering violation"
- default y
+ bool "Cortex-A76: Modification of the translation table for a virtual address might lead to read-after-read ordering violation (rare)"
select ARM64_WORKAROUND_REPEAT_TLBI
help
This option adds a workaround for ARM Cortex-A76 erratum 1286807.
@@ -724,6 +718,8 @@ config ARM64_ERRATUM_1286807
invalidated has been observed by other observers. The
workaround repeats the TLBI+DSB operation.
+ If unsure, say N.
+
config ARM64_ERRATUM_1463225
bool "Cortex-A76: Software Step might prevent interrupt recognition"
default y
@@ -743,8 +739,7 @@ config ARM64_ERRATUM_1463225
If unsure, say Y.
config ARM64_ERRATUM_1542419
- bool "Neoverse-N1: workaround mis-ordering of instruction fetches"
- default y
+ bool "Neoverse-N1: workaround mis-ordering of instruction fetches (rare)"
help
This option adds a workaround for ARM Neoverse-N1 erratum
1542419.
@@ -756,7 +751,7 @@ config ARM64_ERRATUM_1542419
Workaround the issue by hiding the DIC feature from EL0. This
forces user-space to perform cache maintenance.
- If unsure, say Y.
+ If unsure, say N.
config ARM64_ERRATUM_1508412
bool "Cortex-A77: 1508412: workaround deadlock on sequence of NC/Device load and store exclusive or PAR read"
@@ -931,8 +926,7 @@ config ARM64_ERRATUM_2224489
If unsure, say Y.
config ARM64_ERRATUM_2441009
- bool "Cortex-A510: Completion of affected memory accesses might not be guaranteed by completion of a TLBI"
- default y
+ bool "Cortex-A510: Completion of affected memory accesses might not be guaranteed by completion of a TLBI (rare)"
select ARM64_WORKAROUND_REPEAT_TLBI
help
This option adds a workaround for ARM Cortex-A510 erratum #2441009.
@@ -945,7 +939,7 @@ config ARM64_ERRATUM_2441009
Work around this by adding the affected CPUs to the list that needs
TLB sequences to be done twice.
- If unsure, say Y.
+ If unsure, say N.
config ARM64_ERRATUM_2064142
bool "Cortex-A510: 2064142: workaround TRBE register writes while disabled"
@@ -1259,11 +1253,13 @@ choice
config ARM64_4K_PAGES
bool "4KB"
+ select HAVE_PAGE_SIZE_4KB
help
This feature enables 4KB pages support.
config ARM64_16K_PAGES
bool "16KB"
+ select HAVE_PAGE_SIZE_16KB
help
The system will use 16KB pages support. AArch32 emulation
requires applications compiled with 16K (or a multiple of 16K)
@@ -1271,6 +1267,7 @@ config ARM64_16K_PAGES
config ARM64_64K_PAGES
bool "64KB"
+ select HAVE_PAGE_SIZE_64KB
help
This feature enables 64KB pages support (4KB by default)
allowing only two levels of page tables and faster TLB
@@ -1281,9 +1278,7 @@ endchoice
choice
prompt "Virtual address space size"
- default ARM64_VA_BITS_39 if ARM64_4K_PAGES
- default ARM64_VA_BITS_47 if ARM64_16K_PAGES
- default ARM64_VA_BITS_42 if ARM64_64K_PAGES
+ default ARM64_VA_BITS_52
help
Allows choosing one of multiple possible virtual address
space sizes. The level of translation table is determined by
@@ -1291,26 +1286,26 @@ choice
config ARM64_VA_BITS_36
bool "36-bit" if EXPERT
- depends on ARM64_16K_PAGES
+ depends on PAGE_SIZE_16KB
config ARM64_VA_BITS_39
bool "39-bit"
- depends on ARM64_4K_PAGES
+ depends on PAGE_SIZE_4KB
config ARM64_VA_BITS_42
bool "42-bit"
- depends on ARM64_64K_PAGES
+ depends on PAGE_SIZE_64KB
config ARM64_VA_BITS_47
bool "47-bit"
- depends on ARM64_16K_PAGES
+ depends on PAGE_SIZE_16KB
config ARM64_VA_BITS_48
bool "48-bit"
config ARM64_VA_BITS_52
bool "52-bit"
- depends on ARM64_64K_PAGES && (ARM64_PAN || !ARM64_SW_TTBR0_PAN)
+ depends on ARM64_PAN || !ARM64_SW_TTBR0_PAN
help
Enable 52-bit virtual addressing for userspace when explicitly
requested via a hint to mmap(). The kernel will also use 52-bit
@@ -1357,10 +1352,11 @@ choice
config ARM64_PA_BITS_48
bool "48-bit"
+ depends on ARM64_64K_PAGES || !ARM64_VA_BITS_52
config ARM64_PA_BITS_52
- bool "52-bit (ARMv8.2)"
- depends on ARM64_64K_PAGES
+ bool "52-bit"
+ depends on ARM64_64K_PAGES || ARM64_VA_BITS_52
depends on ARM64_PAN || !ARM64_SW_TTBR0_PAN
help
Enable support for a 52-bit physical address space, introduced as
@@ -1377,6 +1373,10 @@ config ARM64_PA_BITS
default 48 if ARM64_PA_BITS_48
default 52 if ARM64_PA_BITS_52
+config ARM64_LPA2
+ def_bool y
+ depends on ARM64_PA_BITS_52 && !ARM64_64K_PAGES
+
choice
prompt "Endianness"
default CPU_LITTLE_ENDIAN
@@ -1387,7 +1387,6 @@ choice
config CPU_BIG_ENDIAN
bool "Build big-endian kernel"
- depends on !LD_IS_LLD || LLD_VERSION >= 130000
# https://github.com/llvm/llvm-project/commit/1379b150991f70a5782e9a143c2ba5308da1161c
depends on AS_IS_GNU || AS_VERSION >= 150000
help
@@ -1427,7 +1426,7 @@ config SCHED_SMT
config NR_CPUS
int "Maximum number of CPUs (2-4096)"
range 2 4096
- default "256"
+ default "512"
config HOTPLUG_CPU
bool "Support for hot-pluggable CPUs"
@@ -1519,7 +1518,7 @@ config ARCH_SUPPORTS_CRASH_DUMP
def_bool y
config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
- def_bool CRASH_CORE
+ def_bool CRASH_RESERVE
config TRANS_TABLE
def_bool y
@@ -2018,8 +2017,6 @@ config ARM64_BTI_KERNEL
depends on !CC_IS_GCC || GCC_VERSION >= 100100
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106671
depends on !CC_IS_GCC
- # https://github.com/llvm/llvm-project/commit/a88c722e687e6780dcd6a58718350dc76fcc4cc9
- depends on !CC_IS_CLANG || CLANG_VERSION >= 120000
depends on (!FUNCTION_GRAPH_TRACER || DYNAMIC_FTRACE_WITH_ARGS)
help
Build the kernel with Branch Target Identification annotations
@@ -2222,13 +2219,22 @@ config STACKPROTECTOR_PER_TASK
config UNWIND_PATCH_PAC_INTO_SCS
bool "Enable shadow call stack dynamically using code patching"
- # needs Clang with https://reviews.llvm.org/D111780 incorporated
+ # needs Clang with https://github.com/llvm/llvm-project/commit/de07cde67b5d205d58690be012106022aea6d2b3 incorporated
depends on CC_IS_CLANG && CLANG_VERSION >= 150000
depends on ARM64_PTR_AUTH_KERNEL && CC_HAS_BRANCH_PROT_PAC_RET
depends on SHADOW_CALL_STACK
select UNWIND_TABLES
select DYNAMIC_SCS
+config ARM64_CONTPTE
+ bool "Contiguous PTE mappings for user memory" if EXPERT
+ depends on TRANSPARENT_HUGEPAGE
+ default y
+ help
+ When enabled, user mappings are configured using the PTE contiguous
+ bit, for any mappings that meet the size and alignment requirements.
+ This reduces TLB pressure and improves performance.
+
endmenu # "Kernel Features"
menu "Boot options"
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index a88cdf910687..0e075d3c546b 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -41,6 +41,8 @@ KBUILD_CFLAGS += -mgeneral-regs-only \
KBUILD_CFLAGS += $(call cc-disable-warning, psabi)
KBUILD_AFLAGS += $(compat_vdso)
+KBUILD_RUSTFLAGS += --target=aarch64-unknown-none -Ctarget-feature="-neon"
+
KBUILD_CFLAGS += $(call cc-option,-mabi=lp64)
KBUILD_AFLAGS += $(call cc-option,-mabi=lp64)
@@ -65,7 +67,9 @@ endif
ifeq ($(CONFIG_ARM64_BTI_KERNEL),y)
KBUILD_CFLAGS += -mbranch-protection=pac-ret+bti
+ KBUILD_RUSTFLAGS += -Zbranch-protection=bti,pac-ret
else ifeq ($(CONFIG_ARM64_PTR_AUTH_KERNEL),y)
+ KBUILD_RUSTFLAGS += -Zbranch-protection=pac-ret
ifeq ($(CONFIG_CC_HAS_BRANCH_PROT_PAC_RET),y)
KBUILD_CFLAGS += -mbranch-protection=pac-ret
else
diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
index 1f1f8d865d0e..21149b346a60 100644
--- a/arch/arm64/boot/dts/allwinner/Makefile
+++ b/arch/arm64/boot/dts/allwinner/Makefile
@@ -16,6 +16,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pinetab.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pinetab-early-adopter.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-sopine-baseboard.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-teres-i.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h64-remix-mini-pc.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a100-allwinner-perf1.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-bananapi-m2-plus.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-bananapi-m2-plus-v1.2.dtb
@@ -42,6 +43,7 @@ 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
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-x96-mate.dtb
+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
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 9ec49ac2f6fd..381d58cea092 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
@@ -291,6 +291,8 @@
};
&spdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spdif_tx_pin>;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix.dtsi
index 4903d6358112..855b7d43bc50 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix.dtsi
@@ -166,6 +166,8 @@
};
&spdif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spdif_tx_pin>;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index ca1d287a0a01..d11e5041bae9 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -406,6 +406,7 @@
function = "spi1";
};
+ /omit-if-no-ref/
spdif_tx_pin: spdif-tx-pin {
pins = "PH7";
function = "spdif";
@@ -655,10 +656,8 @@
clocks = <&ccu CLK_BUS_SPDIF>, <&ccu CLK_SPDIF>;
clock-names = "apb", "spdif";
resets = <&ccu RST_BUS_SPDIF>;
- dmas = <&dma 2>;
- dma-names = "tx";
- pinctrl-names = "default";
- pinctrl-0 = <&spdif_tx_pin>;
+ dmas = <&dma 2>, <&dma 2>;
+ dma-names = "rx", "tx";
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1-manta.dts b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1-manta.dts
index dbce61b355d6..4bfb52609c94 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1-manta.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1-manta.dts
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (C) 2023 Martin Botka <martin.botka@somainline.org>.
*/
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 1fed2b46cfe8..af421ba24ce0 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (C) 2023 Martin Botka <martin.botka@somainline.org>.
*/
@@ -93,7 +93,7 @@
interrupt-controller;
#interrupt-cells = <1>;
- regulators{
+ regulators {
reg_dcdc1: dcdc1 {
regulator-name = "vdd-gpu-sys";
regulator-min-microvolt = <810000>;
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-pi.dts b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-pi.dts
index 832f08b2b260..ff84a3794470 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-pi.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-bigtreetech-pi.dts
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (C) 2023 Martin Botka <martin@biqu3d.com>.
*/
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
index d549d277d972..b2e85e52d1a1 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
@@ -9,6 +9,7 @@
#include <dt-bindings/clock/sun6i-rtc.h>
#include <dt-bindings/reset/sun50i-h616-ccu.h>
#include <dt-bindings/reset/sun50i-h6-r-ccu.h>
+#include <dt-bindings/thermal/thermal.h>
/ {
interrupt-parent = <&gic>;
@@ -133,11 +134,28 @@
#reset-cells = <1>;
};
+ dma: dma-controller@3002000 {
+ compatible = "allwinner,sun50i-h616-dma",
+ "allwinner,sun50i-a100-dma";
+ reg = <0x03002000 0x1000>;
+ interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_BUS_DMA>, <&ccu CLK_MBUS_DMA>;
+ clock-names = "bus", "mbus";
+ dma-channels = <16>;
+ dma-requests = <49>;
+ resets = <&ccu RST_BUS_DMA>;
+ #dma-cells = <1>;
+ };
+
sid: efuse@3006000 {
compatible = "allwinner,sun50i-h616-sid", "allwinner,sun50i-a64-sid";
reg = <0x03006000 0x1000>;
#address-cells = <1>;
#size-cells = <1>;
+
+ ths_calibration: thermal-sensor-calibration@14 {
+ reg = <0x14 0x8>;
+ };
};
watchdog: watchdog@30090a0 {
@@ -240,6 +258,11 @@
function = "spi1";
};
+ spdif_tx_pin: spdif-tx-pin {
+ pins = "PH4";
+ function = "spdif";
+ };
+
uart0_ph_pins: uart0-ph-pins {
pins = "PH0", "PH1";
function = "uart0";
@@ -256,6 +279,12 @@
pins = "PG8", "PG9";
function = "uart1";
};
+
+ /omit-if-no-ref/
+ x32clk_fanout_pin: x32clk-fanout-pin {
+ pins = "PG10";
+ function = "clock";
+ };
};
gic: interrupt-controller@3021000 {
@@ -339,6 +368,8 @@
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&ccu CLK_BUS_UART0>;
+ dmas = <&dma 14>, <&dma 14>;
+ dma-names = "tx", "rx";
resets = <&ccu RST_BUS_UART0>;
status = "disabled";
};
@@ -350,6 +381,8 @@
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&ccu CLK_BUS_UART1>;
+ dmas = <&dma 15>, <&dma 15>;
+ dma-names = "tx", "rx";
resets = <&ccu RST_BUS_UART1>;
status = "disabled";
};
@@ -361,6 +394,8 @@
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&ccu CLK_BUS_UART2>;
+ dmas = <&dma 16>, <&dma 16>;
+ dma-names = "tx", "rx";
resets = <&ccu RST_BUS_UART2>;
status = "disabled";
};
@@ -372,6 +407,8 @@
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&ccu CLK_BUS_UART3>;
+ dmas = <&dma 17>, <&dma 17>;
+ dma-names = "tx", "rx";
resets = <&ccu RST_BUS_UART3>;
status = "disabled";
};
@@ -383,6 +420,8 @@
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&ccu CLK_BUS_UART4>;
+ dmas = <&dma 18>, <&dma 18>;
+ dma-names = "tx", "rx";
resets = <&ccu RST_BUS_UART4>;
status = "disabled";
};
@@ -394,6 +433,8 @@
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&ccu CLK_BUS_UART5>;
+ dmas = <&dma 19>, <&dma 19>;
+ dma-names = "tx", "rx";
resets = <&ccu RST_BUS_UART5>;
status = "disabled";
};
@@ -405,6 +446,8 @@
reg = <0x05002000 0x400>;
interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ccu CLK_BUS_I2C0>;
+ dmas = <&dma 43>, <&dma 43>;
+ dma-names = "rx", "tx";
resets = <&ccu RST_BUS_I2C0>;
pinctrl-names = "default";
pinctrl-0 = <&i2c0_pins>;
@@ -420,6 +463,8 @@
reg = <0x05002400 0x400>;
interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ccu CLK_BUS_I2C1>;
+ dmas = <&dma 44>, <&dma 44>;
+ dma-names = "rx", "tx";
resets = <&ccu RST_BUS_I2C1>;
status = "disabled";
#address-cells = <1>;
@@ -433,6 +478,8 @@
reg = <0x05002800 0x400>;
interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ccu CLK_BUS_I2C2>;
+ dmas = <&dma 45>, <&dma 45>;
+ dma-names = "rx", "tx";
resets = <&ccu RST_BUS_I2C2>;
status = "disabled";
#address-cells = <1>;
@@ -446,6 +493,8 @@
reg = <0x05002c00 0x400>;
interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ccu CLK_BUS_I2C3>;
+ dmas = <&dma 46>, <&dma 46>;
+ dma-names = "rx", "tx";
resets = <&ccu RST_BUS_I2C3>;
status = "disabled";
#address-cells = <1>;
@@ -459,6 +508,8 @@
reg = <0x05003000 0x400>;
interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ccu CLK_BUS_I2C4>;
+ dmas = <&dma 47>, <&dma 47>;
+ dma-names = "rx", "tx";
resets = <&ccu RST_BUS_I2C4>;
status = "disabled";
#address-cells = <1>;
@@ -472,6 +523,8 @@
interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_SPI0>;
clock-names = "ahb", "mod";
+ dmas = <&dma 22>, <&dma 22>;
+ dma-names = "rx", "tx";
resets = <&ccu RST_BUS_SPI0>;
status = "disabled";
#address-cells = <1>;
@@ -485,6 +538,8 @@
interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ccu CLK_BUS_SPI1>, <&ccu CLK_SPI1>;
clock-names = "ahb", "mod";
+ dmas = <&dma 23>, <&dma 23>;
+ dma-names = "rx", "tx";
resets = <&ccu RST_BUS_SPI1>;
status = "disabled";
#address-cells = <1>;
@@ -511,6 +566,34 @@
};
};
+ spdif: spdif@5093000 {
+ compatible = "allwinner,sun50i-h616-spdif";
+ reg = <0x05093000 0x400>;
+ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_BUS_SPDIF>, <&ccu CLK_SPDIF>;
+ clock-names = "apb", "spdif";
+ resets = <&ccu RST_BUS_SPDIF>;
+ dmas = <&dma 2>;
+ dma-names = "tx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spdif_tx_pin>;
+ #sound-dai-cells = <0>;
+ status = "disabled";
+ };
+
+ ths: thermal-sensor@5070400 {
+ compatible = "allwinner,sun50i-h616-ths";
+ reg = <0x05070400 0x400>;
+ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_BUS_THS>;
+ clock-names = "bus";
+ resets = <&ccu RST_BUS_THS>;
+ nvmem-cells = <&ths_calibration>;
+ nvmem-cell-names = "calibration";
+ allwinner,sram = <&syscon>;
+ #thermal-sensor-cells = <1>;
+ };
+
usbotg: usb@5100000 {
compatible = "allwinner,sun50i-h616-musb",
"allwinner,sun8i-h3-musb";
@@ -734,6 +817,8 @@
reg = <0x07081400 0x400>;
interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&r_ccu CLK_R_APB2_I2C>;
+ dmas = <&dma 48>, <&dma 48>;
+ dma-names = "rx", "tx";
resets = <&r_ccu RST_R_APB2_I2C>;
status = "disabled";
#address-cells = <1>;
@@ -755,4 +840,74 @@
#size-cells = <0>;
};
};
+
+ thermal-zones {
+ cpu-thermal {
+ polling-delay-passive = <500>;
+ polling-delay = <1000>;
+ thermal-sensors = <&ths 2>;
+ sustainable-power = <1000>;
+
+ trips {
+ cpu_threshold: cpu-trip-0 {
+ temperature = <60000>;
+ type = "passive";
+ hysteresis = <0>;
+ };
+ cpu_target: cpu-trip-1 {
+ temperature = <70000>;
+ type = "passive";
+ hysteresis = <0>;
+ };
+ cpu_critical: cpu-trip-2 {
+ temperature = <110000>;
+ type = "critical";
+ hysteresis = <0>;
+ };
+ };
+ };
+
+ gpu-thermal {
+ polling-delay-passive = <500>;
+ polling-delay = <1000>;
+ thermal-sensors = <&ths 0>;
+ sustainable-power = <1100>;
+
+ trips {
+ gpu_temp_critical: gpu-trip-0 {
+ temperature = <110000>;
+ type = "critical";
+ hysteresis = <0>;
+ };
+ };
+ };
+
+ ve-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&ths 1>;
+
+ trips {
+ ve_temp_critical: ve-trip-0 {
+ temperature = <110000>;
+ type = "critical";
+ hysteresis = <0>;
+ };
+ };
+ };
+
+ ddr-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&ths 3>;
+
+ trips {
+ ddr_temp_critical: ddr-trip-0 {
+ temperature = <110000>;
+ type = "critical";
+ hysteresis = <0>;
+ };
+ };
+ };
+ };
};
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
new file mode 100644
index 000000000000..8c1263a3939e
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) Jisheng Zhang <jszhang@kernel.org>
+ */
+
+#include "sun50i-h616.dtsi"
+
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pins>;
+ vmmc-supply = <&reg_dldo1>;
+ vqmmc-supply = <&reg_aldo1>;
+ bus-width = <8>;
+ non-removable;
+ cap-mmc-hw-reset;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+ status = "okay";
+};
+
+&r_i2c {
+ status = "okay";
+
+ axp313: pmic@36 {
+ compatible = "x-powers,axp313a";
+ reg = <0x36>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+
+ regulators {
+ reg_aldo1: aldo1 {
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc-1v8-pll";
+ };
+
+ reg_dldo1: dldo1 {
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-3v3-io";
+ };
+
+ 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 = <1100000>;
+ regulator-name = "vdd-cpu";
+ };
+
+ reg_dcdc3: dcdc3 {
+ regulator-always-on;
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-name = "vdd-dram";
+ };
+ };
+ };
+};
+
+&pio {
+ vcc-pc-supply = <&reg_dldo1>;
+ vcc-pf-supply = <&reg_dldo1>;
+ vcc-pg-supply = <&reg_aldo1>;
+ vcc-ph-supply = <&reg_dldo1>;
+ vcc-pi-supply = <&reg_dldo1>;
+};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts b/arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts
new file mode 100644
index 000000000000..18b29c6b867f
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-longanpi-3h.dts
@@ -0,0 +1,144 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) Jisheng Zhang <jszhang@kernel.org>
+ */
+
+/dts-v1/;
+
+#include "sun50i-h618-longan-module-3h.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ model = "Sipeed Longan Pi 3H";
+ compatible = "sipeed,longan-pi-3h", "sipeed,longan-module-3h", "allwinner,sun50i-h618";
+
+ aliases {
+ ethernet0 = &emac0;
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ color = <LED_COLOR_ID_ORANGE>;
+ function = LED_FUNCTION_INDICATOR;
+ function-enumerator = <0>;
+ gpios = <&pio 6 2 GPIO_ACTIVE_LOW>; /* PG2 */
+ };
+
+ led-1 {
+ color = <LED_COLOR_ID_ORANGE>;
+ function = LED_FUNCTION_INDICATOR;
+ function-enumerator = <1>;
+ gpios = <&pio 6 4 GPIO_ACTIVE_LOW>; /* PG4 */
+ };
+ };
+
+ reg_vcc5v: regulator-vcc5v {
+ /* board wide 5V supply directly from the USB-C socket */
+ compatible = "regulator-fixed";
+ regulator-name = "vcc-5v";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ reg_vcc3v3: regulator-vcc3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ vin-supply = <&reg_vcc5v>;
+ };
+};
+
+&axp313 {
+ vin1-supply = <&reg_vcc5v>;
+ vin2-supply = <&reg_vcc5v>;
+ vin3-supply = <&reg_vcc5v>;
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&ohci1 {
+ status = "okay";
+};
+
+&ehci2 {
+ status = "okay";
+};
+
+&ohci2 {
+ status = "okay";
+};
+
+/* WiFi & BT combo module is connected to this Host */
+&ehci3 {
+ status = "okay";
+};
+
+&ohci3 {
+ status = "okay";
+};
+
+&emac0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ext_rgmii_pins>;
+ phy-mode = "rgmii";
+ phy-handle = <&ext_rgmii_phy>;
+ allwinner,rx-delay-ps = <3100>;
+ allwinner,tx-delay-ps = <700>;
+ phy-supply = <&reg_vcc3v3>;
+ status = "okay";
+};
+
+&mdio0 {
+ ext_rgmii_phy: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ };
+};
+
+&mmc0 {
+ bus-width = <4>;
+ cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */
+ vmmc-supply = <&reg_vcc3v3>;
+ status = "okay";
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&usbotg {
+ /*
+ * PHY0 pins are connected to a USB-C socket, but a role switch
+ * is not implemented: both CC pins are pulled to GND.
+ * The VBUS pins power the device, so a fixed peripheral mode
+ * is the best choice.
+ * The board can be powered via GPIOs, in this case port0 *can*
+ * act as a host (with a cable/adapter ignoring CC), as VBUS is
+ * then provided by the GPIOs. Any user of this setup would
+ * need to adjust the DT accordingly: dr_mode set to "host",
+ * enabling OHCI0 and EHCI0.
+ */
+ dr_mode = "peripheral";
+ status = "okay";
+};
+
+&usbphy {
+ usb1_vbus-supply = <&reg_vcc5v>;
+ usb2_vbus-supply = <&reg_vcc5v>;
+ status = "okay";
+};
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 8ea1fd41aeba..ac0a2b7ea6f3 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
@@ -15,6 +15,7 @@
compatible = "transpeed,8k618-t", "allwinner,sun50i-h618";
aliases {
+ ethernet1 = &sdio_wifi;
serial0 = &uart0;
};
@@ -39,6 +40,15 @@
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
+
+ wifi_pwrseq: wifi_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 */
+ };
};
&ehci0 {
@@ -60,6 +70,19 @@
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>;
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
new file mode 100644
index 000000000000..b6e3c169797f
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts
@@ -0,0 +1,356 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (c) 2023 ARM Ltd.
+
+/dts-v1/;
+
+#include "sun50i-a64.dtsi"
+#include "sun50i-a64-cpu-opp.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Remix Mini PC";
+ compatible = "jide,remix-mini-pc", "allwinner,sun50i-h64",
+ "allwinner,sun50i-a64";
+
+ aliases {
+ ethernet1 = &rtl8723bs;
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ hdmi-connector {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi_con_in: endpoint {
+ remote-endpoint = <&hdmi_out_con>;
+ };
+ };
+ };
+
+ reg_vcc5v: regulator-5v {
+ /* 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;
+ };
+
+ wifi_pwrseq: wifi_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
+ post-power-on-delay-ms = <200>;
+ };
+};
+
+&codec {
+ status = "okay";
+};
+
+&codec_analog {
+ cpvdd-supply = <&reg_eldo1>;
+ status = "okay";
+};
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu1 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu2 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu3 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
+&dai {
+ status = "okay";
+};
+
+&de {
+ status = "okay";
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&hdmi {
+ hvcc-supply = <&reg_dldo1>;
+ status = "okay";
+};
+
+&hdmi_out {
+ hdmi_out_con: endpoint {
+ remote-endpoint = <&hdmi_con_in>;
+ };
+};
+
+/* Connects to the AC200 chip */
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ status = "okay";
+};
+
+&i2c0_pins {
+ bias-pull-up;
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins>;
+ vmmc-supply = <&reg_dcdc1>;
+ cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
+ disable-wp;
+ bus-width = <4>;
+ status = "okay";
+};
+
+&mmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+ vmmc-supply = <&reg_aldo1>;
+ vqmmc-supply = <&reg_dldo4>;
+ mmc-pwrseq = <&wifi_pwrseq>;
+ bus-width = <4>;
+ non-removable;
+ status = "okay";
+
+ rtl8723bs: wifi@1 {
+ reg = <1>;
+ interrupt-parent = <&r_pio>;
+ interrupts = <0 3 IRQ_TYPE_LEVEL_LOW>; /* PL3 */
+ interrupt-names = "host-wake";
+ };
+};
+
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pins>, <&mmc2_ds_pin>;
+ vmmc-supply = <&reg_dcdc1>;
+ vqmmc-supply = <&reg_eldo1>;
+ bus-width = <8>;
+ non-removable;
+ mmc-hs200-1_8v;
+ mmc-hs400-1_8v;
+ cap-mmc-hw-reset;
+ status = "okay";
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&ohci1 {
+ status = "okay";
+};
+
+&pio {
+ vcc-pb-supply = <&reg_dcdc1>;
+ vcc-pc-supply = <&reg_dcdc1>;
+ vcc-pd-supply = <&reg_dcdc1>;
+ vcc-pe-supply = <&reg_dcdc1>;
+ vcc-pf-supply = <&reg_dcdc1>;
+ vcc-pg-supply = <&reg_dldo4>;
+ vcc-ph-supply = <&reg_dcdc1>;
+};
+
+&r_ir {
+ status = "okay";
+};
+
+&r_pio {
+ /*
+ * We cannot add that supply for now since it would create a circular
+ * dependency between pinctrl, the regulator and the RSB Bus.
+ *
+ * vcc-pl-supply = <&reg_aldo2>;
+ */
+};
+
+&r_rsb {
+ status = "okay";
+
+ axp803: pmic@3a3 {
+ compatible = "x-powers,axp803";
+ reg = <0x3a3>;
+ interrupt-parent = <&r_intc>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_LOW>;
+ x-powers,drive-vbus-en;
+
+ vin1-supply = <&reg_vcc5v>;
+ vin2-supply = <&reg_vcc5v>;
+ vin3-supply = <&reg_vcc5v>;
+ vin5-supply = <&reg_vcc5v>;
+ vin6-supply = <&reg_vcc5v>;
+ aldoin-supply = <&reg_vcc5v>;
+ dldoin-supply = <&reg_vcc5v>;
+ eldoin-supply = <&reg_vcc5v>;
+ fldoin-supply = <&reg_vcc5v>;
+ drivevbus-supply = <&reg_vcc5v>;
+ ips-supply = <&reg_vcc5v>;
+
+ status = "okay";
+ };
+};
+
+#include "axp803.dtsi"
+
+&ac_power_supply {
+ status = "okay";
+};
+
+&reg_dcdc1 {
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-3v3";
+};
+
+&reg_dcdc2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1040000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-name = "vdd-cpux";
+};
+
+/* DCDC3 is polyphased with DCDC2 */
+
+&reg_dcdc5 {
+ regulator-always-on;
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-name = "vcc-dram";
+};
+
+/* Deviates from the reset default of 1.1V. */
+&reg_dcdc6 {
+ regulator-always-on;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-name = "vdd-sys";
+};
+
+&reg_aldo1 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-wifi";
+};
+
+&reg_aldo2 {
+ /* Specifying R_PIO consumer would create circular dependency. */
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-pl";
+};
+
+&reg_aldo3 {
+ regulator-always-on;
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-name = "vcc-pll-avcc";
+};
+
+/* AC200 power supply */
+&reg_dldo1 {
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-ave-33";
+};
+
+&reg_dldo4 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-wifi-io";
+};
+
+&reg_drivevbus {
+ regulator-name = "usb0-vbus";
+ status = "okay";
+};
+
+&reg_eldo1 {
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc-cpvdd-dram-emmc";
+};
+
+/* Supplies the arisc management core, needed by TF-A to power off cores. */
+&reg_fldo2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-name = "vdd-cpus";
+};
+
+&reg_rtc_ldo {
+ regulator-name = "vcc-rtc";
+};
+
+&simplefb_hdmi {
+ vcc-hdmi-supply = <&reg_dcdc1>;
+};
+
+&sound {
+ simple-audio-card,aux-devs = <&codec_analog>;
+ simple-audio-card,widgets = "Microphone", "Microphone Jack",
+ "Headphone", "Headphone Jack";
+ simple-audio-card,routing =
+ "Left DAC", "DACL",
+ "Right DAC", "DACR",
+ "Headphone Jack", "HP",
+ "ADCL", "Left ADC",
+ "ADCR", "Right ADC",
+ "MIC2", "Microphone Jack";
+ status = "okay";
+};
+
+/* On the (unpopulated) UART pads. */
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pb_pins>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
+ uart-has-rtscts;
+ status = "okay";
+
+ bluetooth {
+ compatible = "realtek,rtl8723bs-bt";
+ enable-gpios = <&r_pio 0 4 GPIO_ACTIVE_HIGH>; /* PL4 */
+ max-speed = <1500000>;
+ };
+};
+
+&usb_otg {
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usbphy {
+ usb0_vbus-supply = <&reg_drivevbus>;
+ usb1_vbus-supply = <&reg_drivevbus>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index cc8b34bd583d..1ab160bf928a 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -8,6 +8,8 @@ dtb-$(CONFIG_ARCH_MESON) += meson-axg-jethome-jethub-j100.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-axg-jethome-jethub-j110-rev-2.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-axg-jethome-jethub-j110-rev-3.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-axg-s400.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-g12a-fbx8am-brcm.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-g12a-fbx8am-realtek.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-g12a-radxa-zero.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-g12a-sei510.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-g12a-u200.dtb
@@ -80,3 +82,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-hc4.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-sm1-sei610.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-sm1-x96-air-gbit.dtb
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
diff --git a/arch/arm64/boot/dts/amlogic/amlogic-c3.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-c3.dtsi
index 2ad1f8eef199..32a754fe7990 100644
--- a/arch/arm64/boot/dts/amlogic/amlogic-c3.dtsi
+++ b/arch/arm64/boot/dts/amlogic/amlogic-c3.dtsi
@@ -6,6 +6,7 @@
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/reset/amlogic,c3-reset.h>
/ {
cpus {
@@ -81,6 +82,12 @@
#size-cells = <2>;
ranges = <0x0 0x0 0x0 0xfe000000 0x0 0x480000>;
+ reset: reset-controller@2000 {
+ compatible = "amlogic,c3-reset";
+ reg = <0x0 0x2000 0x0 0x98>;
+ #reset-cells = <1>;
+ };
+
watchdog@2100 {
compatible = "amlogic,c3-wdt", "amlogic,t7-wdt";
reg = <0x0 0x2100 0x0 0x10>;
diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
index a03c7667d2b6..5248bdf824ea 100644
--- a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
+++ b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
@@ -54,7 +54,7 @@
enable-method = "psci";
};
- cpu101: cpu@101{
+ cpu101: cpu@101 {
device_type = "cpu";
compatible = "arm,cortex-a53";
reg = <0x0 0x101>;
@@ -171,6 +171,16 @@
};
};
+ gpio_intc: interrupt-controller@4080 {
+ compatible = "amlogic,t7-gpio-intc",
+ "amlogic,meson-gpio-intc";
+ reg = <0x0 0x4080 0x0 0x20>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ amlogic,channel-interrupts =
+ <10 11 12 13 14 15 16 17 18 19 20 21>;
+ };
+
uart_a: serial@78000 {
compatible = "amlogic,t7-uart", "amlogic,meson-s4-uart";
reg = <0x0 0x78000 0x0 0x18>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-a1-ad402.dts b/arch/arm64/boot/dts/amlogic/meson-a1-ad402.dts
index 1c20516fa653..4bc30af05848 100644
--- a/arch/arm64/boot/dts/amlogic/meson-a1-ad402.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-a1-ad402.dts
@@ -106,7 +106,7 @@
pinctrl-0 = <&spifc_pins>;
pinctrl-names = "default";
- spi_nand@0 {
+ flash@0 {
compatible = "spi-nand";
status = "okay";
reg = <0>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
index 648e7f49424f..c03e207ea6c5 100644
--- a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
@@ -450,6 +450,8 @@
<&clkc_periphs CLKID_USB_BUS>,
<&clkc_periphs CLKID_USB_CTRL_IN>;
clock-names = "usb_ctrl", "usb_bus", "xtal_usb_ctrl";
+ assigned-clocks = <&clkc_periphs CLKID_USB_BUS>;
+ assigned-clock-rates = <64000000>;
resets = <&reset RESET_USBCTRL>;
reset-name = "usb_ctrl";
diff --git a/arch/arm64/boot/dts/amlogic/meson-axg-jethome-jethub-j1xx.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg-jethome-jethub-j1xx.dtsi
index db605f3a22b4..9b65ae818e2f 100644
--- a/arch/arm64/boot/dts/amlogic/meson-axg-jethome-jethub-j1xx.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-axg-jethome-jethub-j1xx.dtsi
@@ -35,7 +35,7 @@
reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
};
- vcc_3v3: regulator-vcc_3v3 {
+ vcc_3v3: regulator-vcc-3v3 {
compatible = "regulator-fixed";
regulator-name = "VCC_3V3";
regulator-min-microvolt = <3300000>;
@@ -44,7 +44,7 @@
regulator-always-on;
};
- vcc_5v: regulator-vcc_5v {
+ vcc_5v: regulator-vcc-5v {
compatible = "regulator-fixed";
regulator-name = "VCC5V";
regulator-min-microvolt = <5000000>;
@@ -52,7 +52,7 @@
regulator-always-on;
};
- vddao_3v3: regulator-vddao_3v3 {
+ vddao_3v3: regulator-vddao-3v3 {
compatible = "regulator-fixed";
regulator-name = "VDDAO_3V3";
regulator-min-microvolt = <3300000>;
@@ -61,7 +61,7 @@
regulator-always-on;
};
- vddio_ao18: regulator-vddio_ao18 {
+ vddio_ao18: regulator-vddio-ao18 {
compatible = "regulator-fixed";
regulator-name = "VDDIO_AO18";
regulator-min-microvolt = <1800000>;
@@ -70,7 +70,7 @@
regulator-always-on;
};
- vddio_boot: regulator-vddio_boot {
+ vddio_boot: regulator-vddio-boot {
compatible = "regulator-fixed";
regulator-name = "VDDIO_BOOT";
regulator-min-microvolt = <3300000>;
@@ -79,7 +79,7 @@
regulator-always-on;
};
- vccq_1v8: regulator-vccq_1v8 {
+ vccq_1v8: regulator-vccq-1v8 {
compatible = "regulator-fixed";
regulator-name = "VCCQ_1V8";
regulator-min-microvolt = <1800000>;
@@ -88,7 +88,7 @@
regulator-always-on;
};
- usb_pwr: regulator-usb_pwr {
+ usb_pwr: regulator-usb-pwr {
compatible = "regulator-fixed";
regulator-name = "USB_PWR";
regulator-min-microvolt = <5000000>;
@@ -332,19 +332,3 @@
"", "", "", "", "", // 80 - 84
"", ""; // 85-86
};
-
-&cpu0 {
- #cooling-cells = <2>;
-};
-
-&cpu1 {
- #cooling-cells = <2>;
-};
-
-&cpu2 {
- #cooling-cells = <2>;
-};
-
-&cpu3 {
- #cooling-cells = <2>;
-};
diff --git a/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts b/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts
index c8905663bc75..7ed526f45175 100644
--- a/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts
@@ -12,7 +12,7 @@
compatible = "amlogic,s400", "amlogic,a113d", "amlogic,meson-axg";
model = "Amlogic Meson AXG S400 Development Board";
- adc_keys {
+ keys {
compatible = "adc-keys";
io-channels = <&saradc 0>;
io-channel-names = "buttons";
@@ -111,7 +111,7 @@
reg = <0x0 0x0 0x0 0x40000000>;
};
- main_12v: regulator-main_12v {
+ main_12v: regulator-main-12v {
compatible = "regulator-fixed";
regulator-name = "12V";
regulator-min-microvolt = <12000000>;
@@ -119,7 +119,7 @@
regulator-always-on;
};
- vcc_3v3: regulator-vcc_3v3 {
+ vcc_3v3: regulator-vcc-3v3 {
compatible = "regulator-fixed";
regulator-name = "VCC_3V3";
regulator-min-microvolt = <3300000>;
@@ -128,7 +128,7 @@
regulator-always-on;
};
- vcc_5v: regulator-vcc_5v {
+ vcc_5v: regulator-vcc-5v {
compatible = "regulator-fixed";
regulator-name = "VCC5V";
regulator-min-microvolt = <5000000>;
@@ -139,7 +139,7 @@
enable-active-high;
};
- vddao_3v3: regulator-vddao_3v3 {
+ vddao_3v3: regulator-vddao-3v3 {
compatible = "regulator-fixed";
regulator-name = "VDDAO_3V3";
regulator-min-microvolt = <3300000>;
@@ -148,7 +148,7 @@
regulator-always-on;
};
- vddio_ao18: regulator-vddio_ao18 {
+ vddio_ao18: regulator-vddio-ao18 {
compatible = "regulator-fixed";
regulator-name = "VDDIO_AO18";
regulator-min-microvolt = <1800000>;
@@ -157,7 +157,7 @@
regulator-always-on;
};
- vddio_boot: regulator-vddio_boot {
+ vddio_boot: regulator-vddio-boot {
compatible = "regulator-fixed";
regulator-name = "VDDIO_BOOT";
regulator-min-microvolt = <1800000>;
@@ -166,7 +166,7 @@
regulator-always-on;
};
- usb_pwr: regulator-usb_pwr {
+ usb_pwr: regulator-usb-pwr {
compatible = "regulator-fixed";
regulator-name = "USB_PWR";
regulator-min-microvolt = <5000000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
index 7e5ac9db93f8..6d12b760b90f 100644
--- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
@@ -74,6 +74,8 @@
enable-method = "psci";
next-level-cache = <&l2>;
clocks = <&scpi_dvfs 0>;
+ dynamic-power-coefficient = <140>;
+ #cooling-cells = <2>;
};
cpu1: cpu@1 {
@@ -83,6 +85,8 @@
enable-method = "psci";
next-level-cache = <&l2>;
clocks = <&scpi_dvfs 0>;
+ dynamic-power-coefficient = <140>;
+ #cooling-cells = <2>;
};
cpu2: cpu@2 {
@@ -92,6 +96,8 @@
enable-method = "psci";
next-level-cache = <&l2>;
clocks = <&scpi_dvfs 0>;
+ dynamic-power-coefficient = <140>;
+ #cooling-cells = <2>;
};
cpu3: cpu@3 {
@@ -101,6 +107,8 @@
enable-method = "psci";
next-level-cache = <&l2>;
clocks = <&scpi_dvfs 0>;
+ dynamic-power-coefficient = <140>;
+ #cooling-cells = <2>;
};
l2: l2-cache0 {
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
index ff68b911b729..9d5eab6595d0 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
@@ -2502,6 +2502,9 @@
clocks = <&clkc CLKID_NNA_CORE_CLK>,
<&clkc CLKID_NNA_AXI_CLK>;
clock-names = "core", "bus";
+ assigned-clocks = <&clkc CLKID_NNA_CORE_CLK>,
+ <&clkc CLKID_NNA_AXI_CLK>;
+ assigned-clock-rates = <800000000>, <800000000>;
resets = <&reset RESET_NNA>;
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-fbx8am-brcm.dtso b/arch/arm64/boot/dts/amlogic/meson-g12a-fbx8am-brcm.dtso
new file mode 100644
index 000000000000..9591fdc31ee0
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a-fbx8am-brcm.dtso
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (c) 2024 Freebox SAS
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/gpio/meson-g12a-gpio.h>
+
+&uart_A {
+ bluetooth {
+ compatible = "brcm,bcm43438-bt";
+ shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
+ max-speed = <2000000>;
+ clocks = <&wifi32k>;
+ clock-names = "lpo";
+ vbat-supply = <&vddao_3v3>;
+ vddio-supply = <&vddio_ao1v8>;
+ };
+};
+
+&sd_emmc_a {
+ /* Per mmc-controller.yaml */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ /* NB: may be either AP6398S or AP6398SR3 wifi module */
+ brcmf: wifi@1 {
+ reg = <1>;
+ compatible = "brcm,bcm4329-fmac";
+ };
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-fbx8am-realtek.dtso b/arch/arm64/boot/dts/amlogic/meson-g12a-fbx8am-realtek.dtso
new file mode 100644
index 000000000000..55fff35b09ae
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a-fbx8am-realtek.dtso
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (c) 2024 Freebox SAS
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/gpio/meson-g12a-gpio.h>
+
+&uart_A {
+ bluetooth {
+ compatible = "realtek,rtl8822cs-bt";
+ enable-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
+ host-wake-gpios = <&gpio GPIOX_19 GPIO_ACTIVE_HIGH>;
+ device-wake-gpios = <&gpio GPIOX_18 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&sd_emmc_a {
+ /* No explicit compatible for rtl8822cs sdio */
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-fbx8am.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-fbx8am.dts
new file mode 100644
index 000000000000..af211d8f3952
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a-fbx8am.dts
@@ -0,0 +1,462 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (c) 2024 Freebox SAS
+
+/*
+ * SEI codename: SEI530FB (based on SEI510)
+ * Freebox codename: fbx8am
+ * Commercial names: Freebox Pop, Player TV Free 4K
+ */
+
+/dts-v1/;
+
+#include "meson-g12a.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/meson-g12a-gpio.h>
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+ compatible = "freebox,fbx8am", "amlogic,g12a";
+ model = "Freebox Player Pop";
+ chassis-type = "embedded";
+
+ firmware {
+ optee {
+ compatible = "linaro,optee-tz";
+ method = "smc";
+ };
+ };
+
+ gpio-keys-polled {
+ compatible = "gpio-keys-polled";
+ poll-interval = <100>;
+
+ /* Physical user-accessible reset button near USB port */
+ power-button {
+ label = "Reset";
+ linux,code = <BTN_MISC>;
+ gpios = <&gpio_ao GPIOAO_3 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ spdif_dit: audio-codec-2 {
+ #sound-dai-cells = <0>;
+ compatible = "linux,spdif-dit";
+ status = "okay";
+ sound-name-prefix = "DIT";
+ };
+
+ aliases {
+ serial0 = &uart_AO;
+ ethernet0 = &ethmac;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ emmc_pwrseq: emmc-pwrseq {
+ compatible = "mmc-pwrseq-emmc";
+ reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>;
+ };
+
+ hdmi-connector {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&hdmi_tx_tmds_out>;
+ };
+ };
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x80000000>;
+ };
+
+ ao_5v: regulator-ao-5v {
+ compatible = "regulator-fixed";
+ regulator-name = "AO_5V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&dc_in>;
+ regulator-always-on;
+ };
+
+ dc_in: regulator-dc-in {
+ compatible = "regulator-fixed";
+ regulator-name = "DC_IN";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ regulator-always-on;
+ };
+
+ emmc_1v8: regulator-emmc-1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "EMMC_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vddao_3v3>;
+ regulator-always-on;
+ };
+
+ vddao_3v3: regulator-vddao-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDAO_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&ao_5v>;
+ regulator-always-on;
+ };
+
+ vddao_3v3_t: regulator-vddao-3v3-t {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDAO_3V3_T";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vddao_3v3>;
+ gpio = <&gpio GPIOH_8 GPIO_OPEN_DRAIN>;
+ enable-active-high;
+ };
+
+ vddcpu: regulator-vddcpu {
+ /*
+ * SY8120B1ABC DC/DC Regulator.
+ */
+ compatible = "pwm-regulator";
+
+ regulator-name = "VDDCPU";
+ regulator-min-microvolt = <721000>;
+ regulator-max-microvolt = <1022000>;
+
+ pwm-supply = <&ao_5v>;
+
+ pwms = <&pwm_AO_cd 1 1250 0>;
+ pwm-dutycycle-range = <100 0>;
+
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vddio_ao1v8: regulator-vddio-ao1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDIO_AO1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vddao_3v3>;
+ regulator-always-on;
+ };
+
+ sdio_pwrseq: sdio-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
+ post-power-on-delay-ms = <10>; /* required for 43752 */
+ clocks = <&wifi32k>;
+ clock-names = "ext_clock";
+ };
+
+ wifi32k: wifi32k {
+ compatible = "pwm-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
+ };
+
+ sound {
+ compatible = "amlogic,axg-sound-card";
+ model = "fbx8am";
+ 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";
+};
+
+&cecb_AO {
+ pinctrl-0 = <&cec_ao_b_h_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ hdmi-phandle = <&hdmi_tx>;
+};
+
+&clkc_audio {
+ status = "okay";
+};
+
+&cpu0 {
+ cpu-supply = <&vddcpu>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu1 {
+ cpu-supply = <&vddcpu>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu2 {
+ cpu-supply = <&vddcpu>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu3 {
+ cpu-supply = <&vddcpu>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&ethmac {
+ status = "okay";
+ phy-handle = <&internal_ephy>;
+ phy-mode = "rmii";
+};
+
+&frddr_a {
+ status = "okay";
+};
+
+&frddr_b {
+ status = "okay";
+};
+
+&frddr_c {
+ status = "okay";
+};
+
+&spdifout_a {
+ pinctrl-0 = <&spdif_out_h_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&spdifout_b {
+ status = "okay";
+};
+
+&hdmi_tx {
+ status = "okay";
+ pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>;
+ pinctrl-names = "default";
+};
+
+&hdmi_tx_tmds_port {
+ hdmi_tx_tmds_out: endpoint {
+ remote-endpoint = <&hdmi_connector_in>;
+ };
+};
+
+&i2c3 {
+ status = "okay";
+ pinctrl-0 = <&i2c3_sda_a_pins>, <&i2c3_sck_a_pins>;
+ pinctrl-names = "default";
+};
+
+&ir {
+ status = "okay";
+ pinctrl-0 = <&remote_input_ao_pins>;
+ pinctrl-names = "default";
+};
+
+&pwm_AO_cd {
+ pinctrl-0 = <&pwm_ao_d_e_pins>;
+ pinctrl-names = "default";
+ clocks = <&xtal>;
+ clock-names = "clkin1";
+ status = "okay";
+};
+
+&pwm_ef {
+ status = "okay";
+ pinctrl-0 = <&pwm_e_pins>;
+ pinctrl-names = "default";
+ clocks = <&xtal>;
+ clock-names = "clkin0";
+};
+
+&pdm {
+ pinctrl-0 = <&pdm_din0_z_pins>, <&pdm_din1_z_pins>,
+ <&pdm_din2_z_pins>, <&pdm_din3_z_pins>,
+ <&pdm_dclk_z_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&saradc {
+ status = "okay";
+ vref-supply = <&vddio_ao1v8>;
+};
+
+/* SDIO */
+&sd_emmc_a {
+ status = "okay";
+ pinctrl-0 = <&sdio_pins>;
+ pinctrl-1 = <&sdio_clk_gate_pins>;
+ pinctrl-names = "default", "clk-gate";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ bus-width = <4>;
+ cap-sd-highspeed;
+ sd-uhs-sdr50;
+ max-frequency = <100000000>;
+
+ non-removable;
+ disable-wp;
+
+ /* WiFi firmware requires power to be kept while in suspend */
+ keep-power-in-suspend;
+
+ mmc-pwrseq = <&sdio_pwrseq>;
+
+ vmmc-supply = <&vddao_3v3>;
+ vqmmc-supply = <&vddio_ao1v8>;
+};
+
+/* SD card */
+&sd_emmc_b {
+ status = "okay";
+ pinctrl-0 = <&sdcard_c_pins>;
+ pinctrl-1 = <&sdcard_clk_gate_c_pins>;
+ pinctrl-names = "default", "clk-gate";
+
+ bus-width = <4>;
+ cap-sd-highspeed;
+ max-frequency = <50000000>;
+ disable-wp;
+
+ cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>;
+ vmmc-supply = <&vddao_3v3>;
+ vqmmc-supply = <&vddao_3v3>;
+};
+
+/* eMMC */
+&sd_emmc_c {
+ status = "okay";
+ pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>;
+ pinctrl-1 = <&emmc_clk_gate_pins>;
+ pinctrl-names = "default", "clk-gate";
+
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+ max-frequency = <200000000>;
+ non-removable;
+ disable-wp;
+
+ mmc-pwrseq = <&emmc_pwrseq>;
+ vmmc-supply = <&vddao_3v3>;
+ vqmmc-supply = <&emmc_1v8>;
+};
+
+&tdmif_b {
+ status = "okay";
+};
+
+&tdmout_b {
+ status = "okay";
+};
+
+&tohdmitx {
+ status = "okay";
+};
+
+&uart_A {
+ status = "okay";
+ pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>;
+ pinctrl-names = "default";
+ uart-has-rtscts;
+};
+
+&uart_AO {
+ status = "okay";
+ pinctrl-0 = <&uart_ao_a_pins>;
+ pinctrl-names = "default";
+};
+
+&usb {
+ status = "okay";
+ dr_mode = "host";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts
index fcd7e1d8e16f..15b9bc280706 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a-radxa-zero.dts
@@ -60,7 +60,7 @@
clock-names = "ext_clock";
};
- ao_5v: regulator-ao_5v {
+ ao_5v: regulator-ao-5v {
compatible = "regulator-fixed";
regulator-name = "AO_5V";
regulator-min-microvolt = <5000000>;
@@ -68,7 +68,7 @@
regulator-always-on;
};
- vcc_1v8: regulator-vcc_1v8 {
+ vcc_1v8: regulator-vcc-1v8 {
compatible = "regulator-fixed";
regulator-name = "VCC_1V8";
regulator-min-microvolt = <1800000>;
@@ -77,7 +77,7 @@
regulator-always-on;
};
- vcc_3v3: regulator-vcc_3v3 {
+ vcc_3v3: regulator-vcc-3v3 {
compatible = "regulator-fixed";
regulator-name = "VCC_3V3";
regulator-min-microvolt = <3300000>;
@@ -86,7 +86,7 @@
regulator-always-on;
};
- hdmi_pw: regulator-hdmi_pw {
+ hdmi_pw: regulator-hdmi-pw {
compatible = "regulator-fixed";
regulator-name = "HDMI_PW";
regulator-min-microvolt = <5000000>;
@@ -95,7 +95,7 @@
regulator-always-on;
};
- vddao_1v8: regulator-vddao_1v8 {
+ vddao_1v8: regulator-vddao-1v8 {
compatible = "regulator-fixed";
regulator-name = "VDDAO_1V8";
regulator-min-microvolt = <1800000>;
@@ -104,7 +104,7 @@
regulator-always-on;
};
- vddao_3v3: regulator-vddao_3v3 {
+ vddao_3v3: regulator-vddao-3v3 {
compatible = "regulator-fixed";
regulator-name = "VDDAO_3V3";
regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
index 4c4550dd4711..61cb8135a392 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
@@ -15,7 +15,7 @@
compatible = "seirobotics,sei510", "amlogic,g12a";
model = "SEI Robotics SEI510";
- adc_keys {
+ keys {
compatible = "adc-keys";
io-channels = <&saradc 0>;
io-channel-names = "buttons";
@@ -83,7 +83,7 @@
reg = <0x0 0x0 0x0 0x40000000>;
};
- ao_5v: regulator-ao_5v {
+ ao_5v: regulator-ao-5v {
compatible = "regulator-fixed";
regulator-name = "AO_5V";
regulator-min-microvolt = <5000000>;
@@ -92,7 +92,7 @@
regulator-always-on;
};
- dc_in: regulator-dc_in {
+ dc_in: regulator-dc-in {
compatible = "regulator-fixed";
regulator-name = "DC_IN";
regulator-min-microvolt = <5000000>;
@@ -100,7 +100,7 @@
regulator-always-on;
};
- emmc_1v8: regulator-emmc_1v8 {
+ emmc_1v8: regulator-emmc-1v8 {
compatible = "regulator-fixed";
regulator-name = "EMMC_1V8";
regulator-min-microvolt = <1800000>;
@@ -109,7 +109,7 @@
regulator-always-on;
};
- vddao_3v3: regulator-vddao_3v3 {
+ vddao_3v3: regulator-vddao-3v3 {
compatible = "regulator-fixed";
regulator-name = "VDDAO_3V3";
regulator-min-microvolt = <3300000>;
@@ -118,7 +118,7 @@
regulator-always-on;
};
- vddao_3v3_t: regultor-vddao_3v3_t {
+ vddao_3v3_t: regulator-vddao-3v3-t {
compatible = "regulator-fixed";
regulator-name = "VDDAO_3V3_T";
regulator-min-microvolt = <3300000>;
@@ -147,7 +147,7 @@
regulator-always-on;
};
- vddio_ao1v8: regulator-vddio_ao1v8 {
+ vddio_ao1v8: regulator-vddio-ao1v8 {
compatible = "regulator-fixed";
regulator-name = "VDDIO_AO1V8";
regulator-min-microvolt = <1800000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts
index 8355ddd7e9ae..3da7922d83f1 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts
@@ -75,7 +75,7 @@
reg = <0x0 0x0 0x0 0x40000000>;
};
- flash_1v8: regulator-flash_1v8 {
+ flash_1v8: regulator-flash-1v8 {
compatible = "regulator-fixed";
regulator-name = "FLASH_1V8";
regulator-min-microvolt = <1800000>;
@@ -84,7 +84,7 @@
regulator-always-on;
};
- main_12v: regulator-main_12v {
+ main_12v: regulator-main-12v {
compatible = "regulator-fixed";
regulator-name = "12V";
regulator-min-microvolt = <12000000>;
@@ -92,7 +92,7 @@
regulator-always-on;
};
- usb_pwr_en: regulator-usb_pwr_en {
+ usb_pwr_en: regulator-usb-pwr-en {
compatible = "regulator-fixed";
regulator-name = "USB_PWR_EN";
regulator-min-microvolt = <5000000>;
@@ -103,7 +103,7 @@
enable-active-high;
};
- vcc_1v8: regulator-vcc_1v8 {
+ vcc_1v8: regulator-vcc-1v8 {
compatible = "regulator-fixed";
regulator-name = "VCC_1V8";
regulator-min-microvolt = <1800000>;
@@ -112,7 +112,7 @@
regulator-always-on;
};
- vcc_3v3: regulator-vcc_3v3 {
+ vcc_3v3: regulator-vcc-3v3 {
compatible = "regulator-fixed";
regulator-name = "VCC_3V3";
regulator-min-microvolt = <3300000>;
@@ -122,7 +122,7 @@
/* FIXME: actually controlled by VDDCPU_B_EN */
};
- vcc_5v: regulator-vcc_5v {
+ vcc_5v: regulator-vcc-5v {
compatible = "regulator-fixed";
regulator-name = "VCC_5V";
regulator-min-microvolt = <5000000>;
@@ -133,7 +133,7 @@
enable-active-high;
};
- vddao_1v8: regulator-vddao_1v8 {
+ vddao_1v8: regulator-vddao-1v8 {
compatible = "regulator-fixed";
regulator-name = "VDDAO_1V8";
regulator-min-microvolt = <1800000>;
@@ -142,7 +142,7 @@
regulator-always-on;
};
- vddao_3v3: regulator-vddao_3v3 {
+ vddao_3v3: regulator-vddao-3v3 {
compatible = "regulator-fixed";
regulator-name = "VDDAO_3V3";
regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts
index 9b55982b6a6b..05c7a1e3f1b7 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts
@@ -66,7 +66,7 @@
clock-names = "ext_clock";
};
- flash_1v8: regulator-flash_1v8 {
+ flash_1v8: regulator-flash-1v8 {
compatible = "regulator-fixed";
regulator-name = "FLASH_1V8";
regulator-min-microvolt = <1800000>;
@@ -75,7 +75,7 @@
regulator-always-on;
};
- dc_in: regulator-dc_in {
+ dc_in: regulator-dc-in {
compatible = "regulator-fixed";
regulator-name = "DC_IN";
regulator-min-microvolt = <5000000>;
@@ -83,7 +83,7 @@
regulator-always-on;
};
- vcc_1v8: regulator-vcc_1v8 {
+ vcc_1v8: regulator-vcc-1v8 {
compatible = "regulator-fixed";
regulator-name = "VCC_1V8";
regulator-min-microvolt = <1800000>;
@@ -92,7 +92,7 @@
regulator-always-on;
};
- vcc_3v3: regulator-vcc_3v3 {
+ vcc_3v3: regulator-vcc-3v3 {
compatible = "regulator-fixed";
regulator-name = "VCC_3V3";
regulator-min-microvolt = <3300000>;
@@ -102,7 +102,7 @@
/* FIXME: actually controlled by VDDCPU_B_EN */
};
- vcc_5v: regulator-vcc_5v {
+ vcc_5v: regulator-vcc-5v {
compatible = "regulator-fixed";
regulator-name = "VCC_5V";
regulator-min-microvolt = <5000000>;
@@ -112,7 +112,7 @@
gpio = <&gpio GPIOH_8 GPIO_OPEN_DRAIN>;
};
- vddao_1v8: regulator-vddao_1v8 {
+ vddao_1v8: regulator-vddao-1v8 {
compatible = "regulator-fixed";
regulator-name = "VDDAO_1V8";
regulator-min-microvolt = <1800000>;
@@ -121,7 +121,7 @@
regulator-always-on;
};
- vddao_3v3: regulator-vddao_3v3 {
+ vddao_3v3: regulator-vddao-3v3 {
compatible = "regulator-fixed";
regulator-name = "VDDAO_3V3";
regulator-min-microvolt = <3300000>;
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 91c9769fda20..d80dd9a3da31 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi
@@ -19,7 +19,7 @@
status = "okay";
};
- hub_5v: regulator-hub_5v {
+ hub_5v: regulator-hub-5v {
compatible = "regulator-fixed";
regulator-name = "HUB_5V";
regulator-min-microvolt = <5000000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid.dtsi
index 9e12a34b2840..09d959aefb18 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid.dtsi
@@ -48,7 +48,7 @@
};
};
- tflash_vdd: regulator-tflash_vdd {
+ tflash_vdd: regulator-tflash-vdd {
compatible = "regulator-fixed";
regulator-name = "TFLASH_VDD";
@@ -60,7 +60,7 @@
regulator-always-on;
};
- tf_io: gpio-regulator-tf_io {
+ tf_io: gpio-regulator-tf-io {
compatible = "regulator-gpio";
regulator-name = "TF_IO";
@@ -74,7 +74,7 @@
<1800000 1>;
};
- flash_1v8: regulator-flash_1v8 {
+ flash_1v8: regulator-flash-1v8 {
compatible = "regulator-fixed";
regulator-name = "FLASH_1V8";
regulator-min-microvolt = <1800000>;
@@ -83,7 +83,7 @@
regulator-always-on;
};
- main_12v: regulator-main_12v {
+ main_12v: regulator-main-12v {
compatible = "regulator-fixed";
regulator-name = "12V";
regulator-min-microvolt = <12000000>;
@@ -91,7 +91,7 @@
regulator-always-on;
};
- usb_pwr_en: regulator-usb_pwr_en {
+ usb_pwr_en: regulator-usb-pwr-en {
compatible = "regulator-fixed";
regulator-name = "USB_PWR_EN";
regulator-min-microvolt = <5000000>;
@@ -103,7 +103,7 @@
enable-active-high;
};
- vcc_5v: regulator-vcc_5v {
+ vcc_5v: regulator-vcc-5v {
compatible = "regulator-fixed";
regulator-name = "5V";
regulator-min-microvolt = <5000000>;
@@ -114,7 +114,7 @@
enable-active-high;
};
- vcc_1v8: regulator-vcc_1v8 {
+ vcc_1v8: regulator-vcc-1v8 {
compatible = "regulator-fixed";
regulator-name = "VCC_1V8";
regulator-min-microvolt = <1800000>;
@@ -123,7 +123,7 @@
regulator-always-on;
};
- vcc_3v3: regulator-vcc_3v3 {
+ vcc_3v3: regulator-vcc-3v3 {
compatible = "regulator-fixed";
regulator-name = "VCC_3V3";
regulator-min-microvolt = <3300000>;
@@ -171,7 +171,7 @@
regulator-always-on;
};
- vddao_1v8: regulator-vddao_1v8 {
+ vddao_1v8: regulator-vddao-1v8 {
compatible = "regulator-fixed";
regulator-name = "VDDAO_1V8";
regulator-min-microvolt = <1800000>;
@@ -180,7 +180,7 @@
regulator-always-on;
};
- vddao_3v3: regulator-vddao_3v3 {
+ vddao_3v3: regulator-vddao-3v3 {
compatible = "regulator-fixed";
regulator-name = "VDDAO_3V3";
regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-w400.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-w400.dtsi
index ac8b7178257e..4cb6930ffb19 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b-w400.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-w400.dtsi
@@ -39,7 +39,7 @@
clock-names = "ext_clock";
};
- flash_1v8: regulator-flash_1v8 {
+ flash_1v8: regulator-flash-1v8 {
compatible = "regulator-fixed";
regulator-name = "FLASH_1V8";
regulator-min-microvolt = <1800000>;
@@ -48,7 +48,7 @@
regulator-always-on;
};
- main_12v: regulator-main_12v {
+ main_12v: regulator-main-12v {
compatible = "regulator-fixed";
regulator-name = "12V";
regulator-min-microvolt = <12000000>;
@@ -56,7 +56,7 @@
regulator-always-on;
};
- vcc_5v: regulator-vcc_5v {
+ vcc_5v: regulator-vcc-5v {
compatible = "regulator-fixed";
regulator-name = "VCC_5V";
regulator-min-microvolt = <5000000>;
@@ -67,7 +67,7 @@
enable-active-high;
};
- vcc_1v8: regulator-vcc_1v8 {
+ vcc_1v8: regulator-vcc-1v8 {
compatible = "regulator-fixed";
regulator-name = "VCC_1V8";
regulator-min-microvolt = <1800000>;
@@ -76,7 +76,7 @@
regulator-always-on;
};
- vcc_3v3: regulator-vcc_3v3 {
+ vcc_3v3: regulator-vcc-3v3 {
compatible = "regulator-fixed";
regulator-name = "VCC_3V3";
regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gx-libretech-pc.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx-libretech-pc.dtsi
index 5e7b9273b062..efd662a452e8 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gx-libretech-pc.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gx-libretech-pc.dtsi
@@ -84,7 +84,7 @@
reg = <0x0 0x0 0x0 0x80000000>;
};
- ao_5v: regulator-ao_5v {
+ ao_5v: regulator-ao-5v {
compatible = "regulator-fixed";
regulator-name = "AO_5V";
regulator-min-microvolt = <5000000>;
@@ -93,7 +93,7 @@
regulator-always-on;
};
- dc_in: regulator-dc_in {
+ dc_in: regulator-dc-in {
compatible = "regulator-fixed";
regulator-name = "DC_IN";
regulator-min-microvolt = <5000000>;
@@ -120,7 +120,7 @@
};
};
- vcc_card: regulator-vcc_card {
+ vcc_card: regulator-vcc-card {
compatible = "regulator-fixed";
regulator-name = "VCC_CARD";
regulator-min-microvolt = <3300000>;
@@ -141,7 +141,7 @@
gpio = <&gpio GPIOH_3 GPIO_OPEN_DRAIN>;
};
- vddio_ao18: regulator-vddio_ao18 {
+ vddio_ao18: regulator-vddio-ao18 {
compatible = "regulator-fixed";
regulator-name = "VDDIO_AO18";
regulator-min-microvolt = <1800000>;
@@ -150,7 +150,7 @@
regulator-always-on;
};
- vddio_ao3v3: regulator-vddio_ao3v3 {
+ vddio_ao3v3: regulator-vddio-ao3v3 {
compatible = "regulator-fixed";
regulator-name = "VDDIO_AO3V3";
regulator-min-microvolt = <3300000>;
@@ -159,7 +159,7 @@
regulator-always-on;
};
- vddio_boot: regulator-vddio_boot {
+ vddio_boot: regulator-vddio-boot {
compatible = "regulator-fixed";
regulator-name = "VDDIO_BOOT";
regulator-min-microvolt = <1800000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
index e59c3c92b1e7..08d6b69ba469 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
@@ -50,28 +50,28 @@
regulator-always-on;
};
- vddio_ao18: regulator-vddio_ao18 {
+ vddio_ao18: regulator-vddio-ao18 {
compatible = "regulator-fixed";
regulator-name = "VDDIO_AO18";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
- vddio_boot: regulator-vddio_boot {
+ vddio_boot: regulator-vddio-boot {
compatible = "regulator-fixed";
regulator-name = "VDDIO_BOOT";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
- vddao_3v3: regulator-vddao_3v3 {
+ vddao_3v3: regulator-vddao-3v3 {
compatible = "regulator-fixed";
regulator-name = "VDDAO_3V3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
- vcc_3v3: regulator-vcc_3v3 {
+ vcc_3v3: regulator-vcc-3v3 {
compatible = "regulator-fixed";
regulator-name = "VCC_3V3";
regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
index 4aab1ab705b4..cca129ce2c58 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
@@ -78,21 +78,21 @@
<3300000 1>;
};
- vddio_boot: regulator-vddio_boot {
+ vddio_boot: regulator-vddio-boot {
compatible = "regulator-fixed";
regulator-name = "VDDIO_BOOT";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
- vddao_3v3: regulator-vddao_3v3 {
+ vddao_3v3: regulator-vddao-3v3 {
compatible = "regulator-fixed";
regulator-name = "VDDAO_3V3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
- vcc_3v3: regulator-vcc_3v3 {
+ vcc_3v3: regulator-vcc-3v3 {
compatible = "regulator-fixed";
regulator-name = "VCC_3V3";
regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
index e6d2de7c45a9..c431986e6a33 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
@@ -67,7 +67,7 @@
regulator-always-on;
};
- hdmi_p5v0: regulator-hdmi_p5v0 {
+ hdmi_p5v0: regulator-hdmi-p5v0 {
compatible = "regulator-fixed";
regulator-name = "HDMI_P5V0";
regulator-min-microvolt = <5000000>;
@@ -76,7 +76,7 @@
vin-supply = <&p5v0>;
};
- tflash_vdd: regulator-tflash_vdd {
+ tflash_vdd: regulator-tflash-vdd {
compatible = "regulator-fixed";
regulator-name = "TFLASH_VDD";
@@ -92,7 +92,7 @@
vin-supply = <&vddio_ao3v3>;
};
- tf_io: gpio-regulator-tf_io {
+ tf_io: gpio-regulator-tf-io {
compatible = "regulator-gpio";
regulator-name = "TF_IO";
@@ -148,7 +148,7 @@
vin-supply = <&p5v0>;
};
- ddr3_1v5: regulator-ddr3_1v5 {
+ ddr3_1v5: regulator-ddr3-1v5 {
compatible = "regulator-fixed";
regulator-name = "DDR3_1V5";
regulator-min-microvolt = <1500000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts
index 591455c50e88..7f94716876d3 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p200.dts
@@ -21,14 +21,14 @@
sound-name-prefix = "DIT";
};
- avdd18_usb_adc: regulator-avdd18_usb_adc {
+ avdd18_usb_adc: regulator-avdd18-usb-adc {
compatible = "regulator-fixed";
regulator-name = "AVDD18_USB_ADC";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
- adc_keys {
+ keys {
compatible = "adc-keys";
io-channels = <&saradc 0>;
io-channel-names = "buttons";
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
index e803a466fe4e..52d57773a77f 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
@@ -53,21 +53,21 @@
regulator-settling-time-down-us = <150000>;
};
- vddio_boot: regulator-vddio_boot {
+ vddio_boot: regulator-vddio-boot {
compatible = "regulator-fixed";
regulator-name = "VDDIO_BOOT";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
- vddao_3v3: regulator-vddao_3v3 {
+ vddao_3v3: regulator-vddao-3v3 {
compatible = "regulator-fixed";
regulator-name = "VDDAO_3V3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
- vcc_3v3: regulator-vcc_3v3 {
+ vcc_3v3: regulator-vcc-3v3 {
compatible = "regulator-fixed";
regulator-name = "VCC_3V3";
regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
index 74df32534231..255e93a0b36d 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi
@@ -47,28 +47,28 @@
enable-active-high;
};
- vddio_boot: regulator-vddio_boot {
+ vddio_boot: regulator-vddio-boot {
compatible = "regulator-fixed";
regulator-name = "VDDIO_BOOT";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
- vddao_3v3: regulator-vddao_3v3 {
+ vddao_3v3: regulator-vddao-3v3 {
compatible = "regulator-fixed";
regulator-name = "VDDAO_3V3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
- vddio_ao18: regulator-vddio_ao18 {
+ vddio_ao18: regulator-vddio-ao18 {
compatible = "regulator-fixed";
regulator-name = "VDDIO_AO18";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
- vcc_3v3: regulator-vcc_3v3 {
+ vcc_3v3: regulator-vcc-3v3 {
compatible = "regulator-fixed";
regulator-name = "VCC_3V3";
regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi
index 94dafb955301..deb295227189 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi
@@ -49,21 +49,21 @@
enable-active-high;
};
- vddio_boot: regulator-vddio_boot {
+ vddio_boot: regulator-vddio-boot {
compatible = "regulator-fixed";
regulator-name = "VDDIO_BOOT";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
- vddao_3v3: regulator-vddao_3v3 {
+ vddao_3v3: regulator-vddao-3v3 {
compatible = "regulator-fixed";
regulator-name = "VDDAO_3V3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
- vddio_ao18: regulator-vddio_ao18 {
+ vddio_ao18: regulator-vddio-ao18 {
compatible = "regulator-fixed";
regulator-name = "VDDIO_AO18";
regulator-min-microvolt = <1800000>;
@@ -71,7 +71,7 @@
regulator-always-on;
};
- vcc_3v3: regulator-vcc_3v3 {
+ vcc_3v3: regulator-vcc-3v3 {
compatible = "regulator-fixed";
regulator-name = "VCC_3V3";
regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s805x-libretech-ac.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s805x-libretech-ac.dts
index a29b49f051ae..90ef9c17d80b 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s805x-libretech-ac.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s805x-libretech-ac.dts
@@ -42,7 +42,7 @@
};
};
- dc_5v: regulator-dc_5v {
+ dc_5v: regulator-dc-5v {
compatible = "regulator-fixed";
regulator-name = "DC_5V";
regulator-min-microvolt = <5000000>;
@@ -89,7 +89,7 @@
regulator-always-on;
};
- vcc_3v3: regulator-vcc_3v3 {
+ vcc_3v3: regulator-vcc-3v3 {
compatible = "regulator-fixed";
regulator-name = "VCC_3V3";
regulator-min-microvolt = <3300000>;
@@ -98,7 +98,7 @@
regulator-always-on;
};
- vddio_ao18: regulator-vddio_ao18 {
+ vddio_ao18: regulator-vddio-ao18 {
compatible = "regulator-fixed";
regulator-name = "VDDIO_AO18";
regulator-min-microvolt = <1800000>;
@@ -107,7 +107,7 @@
regulator-always-on;
};
- vddio_boot: regulator-vddio_boot {
+ vddio_boot: regulator-vddio-boot {
compatible = "regulator-fixed";
regulator-name = "VDDIO_BOOT";
regulator-min-microvolt = <1800000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s805x-p241.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s805x-p241.dts
index c0d6eb55100a..08a4718219b1 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s805x-p241.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s805x-p241.dts
@@ -64,28 +64,28 @@
reg = <0x0 0x0 0x0 0x20000000>;
};
- vddio_boot: regulator-vddio_boot {
+ vddio_boot: regulator-vddio-boot {
compatible = "regulator-fixed";
regulator-name = "VDDIO_BOOT";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
- vddao_3v3: regulator-vddao_3v3 {
+ vddao_3v3: regulator-vddao-3v3 {
compatible = "regulator-fixed";
regulator-name = "VDDAO_3V3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
- vddio_ao18: regulator-vddio_ao18 {
+ vddio_ao18: regulator-vddio-ao18 {
compatible = "regulator-fixed";
regulator-name = "VDDIO_AO18";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
- vcc_3v3: regulator-vcc_3v3 {
+ vcc_3v3: regulator-vcc-3v3 {
compatible = "regulator-fixed";
regulator-name = "VCC_3V3";
regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-jethome-jethub-j80.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-jethome-jethub-j80.dts
index a18d6d241a5a..2b94b6e5285e 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-jethome-jethub-j80.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905w-jethome-jethub-j80.dts
@@ -37,28 +37,28 @@
stdout-path = "serial0:115200n8";
};
- vddio_ao18: regulator-vddio_ao18 {
+ vddio_ao18: regulator-vddio-ao18 {
compatible = "regulator-fixed";
regulator-name = "VDDIO_AO18";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
- vddio_boot: regulator-vddio_boot {
+ vddio_boot: regulator-vddio-boot {
compatible = "regulator-fixed";
regulator-name = "VDDIO_BOOT";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
- vddao_3v3: regulator-vddao_3v3 {
+ vddao_3v3: regulator-vddao-3v3 {
compatible = "regulator-fixed";
regulator-name = "VDDAO_3V3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
- vcc_3v3: regulator-vcc_3v3 {
+ vcc_3v3: regulator-vcc-3v3 {
compatible = "regulator-fixed";
regulator-name = "VCC_3V3";
regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts
index c8d74e61dec1..89fe5110f7a2 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts
@@ -42,21 +42,21 @@
<3300000 1>;
};
- vddio_boot: regulator-vddio_boot {
+ vddio_boot: regulator-vddio-boot {
compatible = "regulator-fixed";
regulator-name = "VDDIO_BOOT";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
- vddao_3v3: regulator-vddao_3v3 {
+ vddao_3v3: regulator-vddao-3v3 {
compatible = "regulator-fixed";
regulator-name = "VDDAO_3V3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
- vcc_3v3: regulator-vcc_3v3 {
+ vcc_3v3: regulator-vcc-3v3 {
compatible = "regulator-fixed";
regulator-name = "VCC_3V3";
regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc-v2.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc-v2.dts
index 2825db91e462..63b20860067c 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc-v2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc-v2.dts
@@ -67,7 +67,7 @@
reg = <0x0 0x0 0x0 0x80000000>;
};
- ao_5v: regulator-ao_5v {
+ ao_5v: regulator-ao-5v {
compatible = "regulator-fixed";
regulator-name = "AO_5V";
regulator-min-microvolt = <5000000>;
@@ -76,7 +76,7 @@
regulator-always-on;
};
- dc_in: regulator-dc_in {
+ dc_in: regulator-dc-in {
compatible = "regulator-fixed";
regulator-name = "DC_IN";
regulator-min-microvolt = <5000000>;
@@ -93,7 +93,7 @@
regulator-always-on;
};
- vcc_card: regulator-vcc_card {
+ vcc_card: regulator-vcc-card {
compatible = "regulator-fixed";
regulator-name = "VCC_CARD";
regulator-min-microvolt = <3300000>;
@@ -114,7 +114,7 @@
gpio = <&gpio GPIOH_3 GPIO_OPEN_DRAIN>;
};
- vddio_ao3v3: regulator-vddio_ao3v3 {
+ vddio_ao3v3: regulator-vddio-ao3v3 {
compatible = "regulator-fixed";
regulator-name = "VDDIO_AO3V3";
regulator-min-microvolt = <3300000>;
@@ -139,7 +139,7 @@
regulator-settling-time-down-us = <50000>;
};
- vddio_ao18: regulator-vddio_ao18 {
+ vddio_ao18: regulator-vddio-ao18 {
compatible = "regulator-fixed";
regulator-name = "VDDIO_AO18";
regulator-min-microvolt = <1800000>;
@@ -148,7 +148,7 @@
regulator-always-on;
};
- vcc_1v8: regulator-vcc_1v8 {
+ vcc_1v8: regulator-vcc-1v8 {
compatible = "regulator-fixed";
regulator-name = "VCC 1V8";
regulator-min-microvolt = <1800000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
index 27093e6ac9e2..8b26c9661be1 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
@@ -93,7 +93,7 @@
regulator-always-on;
};
- vcc_3v3: regulator-vcc_3v3 {
+ vcc_3v3: regulator-vcc-3v3 {
compatible = "regulator-fixed";
regulator-name = "VCC_3V3";
regulator-min-microvolt = <3300000>;
@@ -117,7 +117,7 @@
regulator-settling-time-down-us = <50000>;
};
- vddio_ao18: regulator-vddio_ao18 {
+ vddio_ao18: regulator-vddio-ao18 {
compatible = "regulator-fixed";
regulator-name = "VDDIO_AO18";
regulator-min-microvolt = <1800000>;
@@ -125,7 +125,7 @@
};
/* This is provided by LDOs on the eMMC daugther card */
- vddio_boot: regulator-vddio_boot {
+ vddio_boot: regulator-vddio-boot {
compatible = "regulator-fixed";
regulator-name = "VDDIO_BOOT";
regulator-min-microvolt = <1800000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts
index f1acca5c4434..c79f9f2099bf 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts
@@ -42,21 +42,21 @@
<3300000 1>;
};
- vddio_boot: regulator-vddio_boot {
+ vddio_boot: regulator-vddio-boot {
compatible = "regulator-fixed";
regulator-name = "VDDIO_BOOT";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
- vddao_3v3: regulator-vddao_3v3 {
+ vddao_3v3: regulator-vddao-3v3 {
compatible = "regulator-fixed";
regulator-name = "VDDAO_3V3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
- vcc_3v3: regulator-vcc_3v3 {
+ vcc_3v3: regulator-vcc-3v3 {
compatible = "regulator-fixed";
regulator-name = "VCC_3V3";
regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
index a150cc0e18ff..7e7dc87ede2d 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
@@ -39,28 +39,28 @@
regulator-always-on;
};
- vddio_boot: regulator-vddio_boot {
+ vddio_boot: regulator-vddio-boot {
compatible = "regulator-fixed";
regulator-name = "VDDIO_BOOT";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
- vddao_3v3: regulator-vddao_3v3 {
+ vddao_3v3: regulator-vddao-3v3 {
compatible = "regulator-fixed";
regulator-name = "VDDAO_3V3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
- vddio_ao18: regulator-vddio_ao18 {
+ vddio_ao18: regulator-vddio-ao18 {
compatible = "regulator-fixed";
regulator-name = "VDDIO_AO18";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
- vcc_3v3: regulator-vcc_3v3 {
+ vcc_3v3: regulator-vcc-3v3 {
compatible = "regulator-fixed";
regulator-name = "VCC_3V3";
regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
index 860f307494c5..07e7c3bedea0 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
@@ -112,28 +112,28 @@
regulator-always-on;
};
- vcc_3v3: regulator-vcc_3v3 {
+ vcc_3v3: regulator-vcc-3v3 {
compatible = "regulator-fixed";
regulator-name = "VCC_3V3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
- vddio_ao18: regulator-vddio_ao18 {
+ vddio_ao18: regulator-vddio-ao18 {
compatible = "regulator-fixed";
regulator-name = "VDDIO_AO18";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
- vddio_boot: regulator-vddio_boot {
+ vddio_boot: regulator-vddio-boot {
compatible = "regulator-fixed";
regulator-name = "VDDIO_BOOT";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
- vddao_3v3: regulator-vddao_3v3 {
+ vddao_3v3: regulator-vddao-3v3 {
compatible = "regulator-fixed";
regulator-name = "VDDAO_3V3";
regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-s912-libretech-pc.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-s912-libretech-pc.dts
index 4eda9f634c42..a66f19851ac9 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxm-s912-libretech-pc.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm-s912-libretech-pc.dts
@@ -14,7 +14,7 @@
"amlogic,meson-gxm";
model = "Libre Computer AML-S912-PC";
- typec2_vbus: regulator-typec2_vbus {
+ typec2_vbus: regulator-typec2-vbus {
compatible = "regulator-fixed";
regulator-name = "TYPEC2_VBUS";
regulator-min-microvolt = <5000000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-khadas-vim3.dtsi b/arch/arm64/boot/dts/amlogic/meson-khadas-vim3.dtsi
index 514a6dd4b124..e78cc9b577a0 100644
--- a/arch/arm64/boot/dts/amlogic/meson-khadas-vim3.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-khadas-vim3.dtsi
@@ -80,7 +80,7 @@
clock-names = "ext_clock";
};
- dc_in: regulator-dc_in {
+ dc_in: regulator-dc-in {
compatible = "regulator-fixed";
regulator-name = "DC_IN";
regulator-min-microvolt = <5000000>;
@@ -88,7 +88,7 @@
regulator-always-on;
};
- vcc_5v: regulator-vcc_5v {
+ vcc_5v: regulator-vcc-5v {
compatible = "regulator-fixed";
regulator-name = "VCC_5V";
regulator-min-microvolt = <5000000>;
@@ -99,7 +99,7 @@
enable-active-high;
};
- vcc_1v8: regulator-vcc_1v8 {
+ vcc_1v8: regulator-vcc-1v8 {
compatible = "regulator-fixed";
regulator-name = "VCC_1V8";
regulator-min-microvolt = <1800000>;
@@ -108,7 +108,7 @@
regulator-always-on;
};
- vcc_3v3: regulator-vcc_3v3 {
+ vcc_3v3: regulator-vcc-3v3 {
compatible = "regulator-fixed";
regulator-name = "VCC_3V3";
regulator-min-microvolt = <3300000>;
@@ -118,7 +118,7 @@
/* FIXME: actually controlled by VDDCPU_B_EN */
};
- vddao_1v8: regulator-vddao_1v8 {
+ vddao_1v8: regulator-vddao-1v8 {
compatible = "regulator-fixed";
regulator-name = "VDDIO_AO1V8";
regulator-min-microvolt = <1800000>;
@@ -127,7 +127,7 @@
regulator-always-on;
};
- emmc_1v8: regulator-emmc_1v8 {
+ emmc_1v8: regulator-emmc-1v8 {
compatible = "regulator-fixed";
regulator-name = "EMMC_AO1V8";
regulator-min-microvolt = <1800000>;
@@ -136,7 +136,7 @@
regulator-always-on;
};
- vsys_3v3: regulator-vsys_3v3 {
+ vsys_3v3: regulator-vsys-3v3 {
compatible = "regulator-fixed";
regulator-name = "VSYS_3V3";
regulator-min-microvolt = <3300000>;
@@ -145,7 +145,7 @@
regulator-always-on;
};
- usb_pwr: regulator-usb_pwr {
+ usb_pwr: regulator-usb-pwr {
compatible = "regulator-fixed";
regulator-name = "USB_PWR";
regulator-min-microvolt = <5000000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-libretech-cottonwood.dtsi b/arch/arm64/boot/dts/amlogic/meson-libretech-cottonwood.dtsi
index 35e8f5bae990..082b72703cdf 100644
--- a/arch/arm64/boot/dts/amlogic/meson-libretech-cottonwood.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-libretech-cottonwood.dtsi
@@ -150,7 +150,7 @@
gpio-open-drain;
};
- vddao_3v3: regulator-vddao_3v3 {
+ vddao_3v3: regulator-vddao-3v3 {
compatible = "regulator-fixed";
regulator-name = "VDDAO_3V3";
regulator-min-microvolt = <3300000>;
@@ -171,7 +171,7 @@
pwm-dutycycle-range = <100 0>;
};
- vddio_ao18: regulator-vddio_ao18 {
+ vddio_ao18: regulator-vddio-ao18 {
compatible = "regulator-fixed";
regulator-name = "VDDIO_AO18";
regulator-min-microvolt = <1800000>;
@@ -180,7 +180,7 @@
vin-supply = <&vddao_3v3>;
};
- vddio_c: regulator-vddio_c {
+ vddio_c: regulator-vddio-c {
compatible = "regulator-gpio";
regulator-name = "VDDIO_C";
regulator-min-microvolt = <1800000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi
index 46a34731f7e2..d1fa8b8bf795 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi
@@ -54,7 +54,7 @@
reg = <0x0 0x0 0x0 0x40000000>;
};
- ao_5v: regulator-ao_5v {
+ ao_5v: regulator-ao-5v {
compatible = "regulator-fixed";
regulator-name = "AO_5V";
regulator-min-microvolt = <5000000>;
@@ -63,7 +63,7 @@
regulator-always-on;
};
- dc_in: regulator-dc_in {
+ dc_in: regulator-dc-in {
compatible = "regulator-fixed";
regulator-name = "DC_IN";
regulator-min-microvolt = <5000000>;
@@ -71,7 +71,7 @@
regulator-always-on;
};
- emmc_1v8: regulator-emmc_1v8 {
+ emmc_1v8: regulator-emmc-1v8 {
compatible = "regulator-fixed";
regulator-name = "EMMC_1V8";
regulator-min-microvolt = <1800000>;
@@ -80,7 +80,7 @@
regulator-always-on;
};
- vddao_3v3: regulator-vddao_3v3 {
+ vddao_3v3: regulator-vddao-3v3 {
compatible = "regulator-fixed";
regulator-name = "VDDAO_3V3";
regulator-min-microvolt = <3300000>;
@@ -105,7 +105,7 @@
regulator-always-on;
};
- vddio_ao1v8: regulator-vddio_ao1v8 {
+ vddio_ao1v8: regulator-vddio-ao1v8 {
compatible = "regulator-fixed";
regulator-name = "VDDIO_AO1V8";
regulator-min-microvolt = <1800000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi.dtsi
index 62404743e62d..81dce862902a 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi.dtsi
@@ -82,7 +82,7 @@
reg = <0x0 0x0 0x0 0x40000000>;
};
- emmc_1v8: regulator-emmc_1v8 {
+ emmc_1v8: regulator-emmc-1v8 {
compatible = "regulator-fixed";
regulator-name = "EMMC_1V8";
regulator-min-microvolt = <1800000>;
@@ -91,7 +91,7 @@
regulator-always-on;
};
- dc_in: regulator-dc_in {
+ dc_in: regulator-dc-in {
compatible = "regulator-fixed";
regulator-name = "DC_IN";
regulator-min-microvolt = <5000000>;
@@ -99,7 +99,7 @@
regulator-always-on;
};
- vddio_c: regulator-vddio_c {
+ vddio_c: regulator-vddio-c {
compatible = "regulator-gpio";
regulator-name = "VDDIO_C";
regulator-min-microvolt = <1800000>;
@@ -116,7 +116,7 @@
<3300000 1>;
};
- tflash_vdd: regulator-tflash_vdd {
+ tflash_vdd: regulator-tflash-vdd {
compatible = "regulator-fixed";
regulator-name = "TFLASH_VDD";
regulator-min-microvolt = <3300000>;
@@ -127,7 +127,7 @@
regulator-always-on;
};
- vddao_1v8: regulator-vddao_1v8 {
+ vddao_1v8: regulator-vddao-1v8 {
compatible = "regulator-fixed";
regulator-name = "VDDAO_1V8";
regulator-min-microvolt = <1800000>;
@@ -136,7 +136,7 @@
regulator-always-on;
};
- vddao_3v3: regulator-vddao_3v3 {
+ vddao_3v3: regulator-vddao-3v3 {
compatible = "regulator-fixed";
regulator-name = "VDDAO_3V3";
regulator-min-microvolt = <3300000>;
@@ -165,7 +165,7 @@
};
/* USB Hub Power Enable */
- vl_pwr_en: regulator-vl_pwr_en {
+ vl_pwr_en: regulator-vl-pwr-en {
compatible = "regulator-fixed";
regulator-name = "VL_PWR_EN";
regulator-min-microvolt = <5000000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-hc4.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-hc4.dts
index 846a2d6c20e5..0170139b8d32 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-hc4.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-hc4.dts
@@ -43,7 +43,7 @@
};
/* Powers the SATA Disk 0 regulator, which is enabled when a disk load is detected */
- p12v_0: regulator-p12v_0 {
+ p12v_0: regulator-p12v-0 {
compatible = "regulator-fixed";
regulator-name = "P12V_0";
regulator-min-microvolt = <12000000>;
@@ -56,7 +56,7 @@
};
/* Powers the SATA Disk 1 regulator, which is enabled when a disk load is detected */
- p12v_1: regulator-p12v_1 {
+ p12v_1: regulator-p12v-1 {
compatible = "regulator-fixed";
regulator-name = "P12V_1";
regulator-min-microvolt = <12000000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
index 1db2327bbd13..951eb8e3f0c0 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
@@ -28,7 +28,7 @@
reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>;
};
- tflash_vdd: regulator-tflash_vdd {
+ tflash_vdd: regulator-tflash-vdd {
compatible = "regulator-fixed";
regulator-name = "TFLASH_VDD";
@@ -40,7 +40,7 @@
regulator-always-on;
};
- tf_io: gpio-regulator-tf_io {
+ tf_io: gpio-regulator-tf-io {
compatible = "regulator-gpio";
regulator-name = "TF_IO";
@@ -59,7 +59,7 @@
<1800000 1>;
};
- flash_1v8: regulator-flash_1v8 {
+ flash_1v8: regulator-flash-1v8 {
compatible = "regulator-fixed";
regulator-name = "FLASH_1V8";
regulator-min-microvolt = <1800000>;
@@ -68,7 +68,7 @@
regulator-always-on;
};
- main_12v: regulator-main_12v {
+ main_12v: regulator-main-12v {
compatible = "regulator-fixed";
regulator-name = "12V";
regulator-min-microvolt = <12000000>;
@@ -76,7 +76,7 @@
regulator-always-on;
};
- vcc_5v: regulator-vcc_5v {
+ vcc_5v: regulator-vcc-5v {
compatible = "regulator-fixed";
regulator-name = "5V";
regulator-min-microvolt = <5000000>;
@@ -87,7 +87,7 @@
enable-active-high;
};
- vcc_1v8: regulator-vcc_1v8 {
+ vcc_1v8: regulator-vcc-1v8 {
compatible = "regulator-fixed";
regulator-name = "VCC_1V8";
regulator-min-microvolt = <1800000>;
@@ -96,7 +96,7 @@
regulator-always-on;
};
- vcc_3v3: regulator-vcc_3v3 {
+ vcc_3v3: regulator-vcc-3v3 {
compatible = "regulator-fixed";
regulator-name = "VCC_3V3";
regulator-min-microvolt = <3300000>;
@@ -125,7 +125,7 @@
regulator-always-on;
};
- usb_pwr_en: regulator-usb_pwr_en {
+ usb_pwr_en: regulator-usb-pwr-en {
compatible = "regulator-fixed";
regulator-name = "USB_PWR_EN";
regulator-min-microvolt = <5000000>;
@@ -137,7 +137,7 @@
enable-active-high;
};
- vddao_1v8: regulator-vddao_1v8 {
+ vddao_1v8: regulator-vddao-1v8 {
compatible = "regulator-fixed";
regulator-name = "VDDAO_1V8";
regulator-min-microvolt = <1800000>;
@@ -146,7 +146,7 @@
regulator-always-on;
};
- vddao_3v3: regulator-vddao_3v3 {
+ vddao_3v3: regulator-vddao-3v3 {
compatible = "regulator-fixed";
regulator-name = "VDDAO_3V3";
regulator-min-microvolt = <3300000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts
index 109932068dbe..3581e14cbf18 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts
@@ -127,7 +127,7 @@
reg = <0x0 0x0 0x0 0x40000000>;
};
- ao_5v: regulator-ao_5v {
+ ao_5v: regulator-ao-5v {
compatible = "regulator-fixed";
regulator-name = "AO_5V";
regulator-min-microvolt = <5000000>;
@@ -136,7 +136,7 @@
regulator-always-on;
};
- dc_in: regulator-dc_in {
+ dc_in: regulator-dc-in {
compatible = "regulator-fixed";
regulator-name = "DC_IN";
regulator-min-microvolt = <5000000>;
@@ -144,7 +144,7 @@
regulator-always-on;
};
- emmc_1v8: regulator-emmc_1v8 {
+ emmc_1v8: regulator-emmc-1v8 {
compatible = "regulator-fixed";
regulator-name = "EMMC_1V8";
regulator-min-microvolt = <1800000>;
@@ -153,7 +153,7 @@
regulator-always-on;
};
- vddao_3v3: regulator-vddao_3v3 {
+ vddao_3v3: regulator-vddao-3v3 {
compatible = "regulator-fixed";
regulator-name = "VDDAO_3V3";
regulator-min-microvolt = <3300000>;
@@ -163,7 +163,7 @@
};
/* Used by Tuner, RGB Led & IR Emitter LED array */
- vddao_3v3_t: regulator-vddao_3v3_t {
+ vddao_3v3_t: regulator-vddao-3v3-t {
compatible = "regulator-fixed";
regulator-name = "VDDAO_3V3_T";
regulator-min-microvolt = <3300000>;
@@ -192,7 +192,7 @@
regulator-always-on;
};
- vddio_ao1v8: regulator-vddio_ao1v8 {
+ vddio_ao1v8: regulator-vddio-ao1v8 {
compatible = "regulator-fixed";
regulator-name = "VDDIO_AO1V8";
regulator-min-microvolt = <1800000>;
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-netgear-r8000p.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-netgear-r8000p.dts
index 78204d71ecd2..999d93730240 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-netgear-r8000p.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-netgear-r8000p.dts
@@ -125,6 +125,11 @@
};
};
+&nand_controller {
+ brcm,wp-not-connected;
+ status = "okay";
+};
+
&nandcs {
nand-ecc-strength = <4>;
nand-ecc-step-size = <512>;
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-tplink-archer-c2300-v1.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-tplink-archer-c2300-v1.dts
index fcf092c81b59..19fc03ef47a0 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-tplink-archer-c2300-v1.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-tplink-archer-c2300-v1.dts
@@ -155,6 +155,11 @@
};
};
+&nand_controller {
+ brcm,wp-not-connected;
+ status = "okay";
+};
+
&nandcs {
nand-ecc-strength = <4>;
nand-ecc-step-size = <512>;
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908-asus-gt-ac5300.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908-asus-gt-ac5300.dts
index d94a53d68320..2a0d4ee3bd79 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908-asus-gt-ac5300.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908-asus-gt-ac5300.dts
@@ -166,11 +166,15 @@
};
};
+&nand_controller {
+ brcm,wp-not-connected;
+ status = "okay";
+};
+
&nandcs {
nand-ecc-strength = <4>;
nand-ecc-step-size = <512>;
nand-on-flash-bbt;
- brcm,nand-has-wp;
#address-cells = <1>;
#size-cells = <0>;
@@ -181,16 +185,17 @@
#size-cells = <1>;
partition@0 {
- compatible = "nvmem-cells";
label = "cferom";
reg = <0x0 0x100000>;
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0 0x0 0x100000>;
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
- base_mac_addr: mac@106a0 {
- reg = <0x106a0 0x6>;
+ base_mac_addr: mac@106a0 {
+ reg = <0x106a0 0x6>;
+ };
};
};
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
index 2f124b027bbf..e01cf4f54077 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
@@ -227,9 +227,6 @@
brcm,num-gphy = <5>;
brcm,num-rgmii-ports = <2>;
- #address-cells = <1>;
- #size-cells = <0>;
-
ports: ports {
#address-cells = <1>;
#size-cells = <0>;
@@ -589,7 +586,7 @@
status = "disabled";
};
- nand-controller@1800 {
+ nand_controller: nand-controller@1800 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
@@ -597,7 +594,7 @@
reg-names = "nand", "nand-int-base";
interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "nand_ctlrdy";
- status = "okay";
+ status = "disabled";
nandcs: nand@0 {
compatible = "brcm,nandcs";
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4912.dtsi b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4912.dtsi
index d658c81f7285..14b2adfb817c 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4912.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4912.dtsi
@@ -138,6 +138,20 @@
status = "disabled";
};
+ nand_controller: nand-controller@1800 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+ reg = <0x1800 0x600>, <0x2000 0x10>;
+ reg-names = "nand", "nand-int-base";
+ status = "disabled";
+
+ nandcs: nand@0 {
+ compatible = "brcm,nandcs";
+ reg = <0>;
+ };
+ };
+
uart0: serial@12000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x12000 0x1000>;
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm63146.dtsi b/arch/arm64/boot/dts/broadcom/bcmbca/bcm63146.dtsi
index 4f474d47022e..589b8a1efc72 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm63146.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm63146.dtsi
@@ -119,6 +119,20 @@
status = "disabled";
};
+ nand_controller: nand-controller@1800 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+ reg = <0x1800 0x600>, <0x2000 0x10>;
+ reg-names = "nand", "nand-int-base";
+ status = "disabled";
+
+ nandcs: nand@0 {
+ compatible = "brcm,nandcs";
+ reg = <0>;
+ };
+ };
+
uart0: serial@12000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x12000 0x1000>;
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm63158.dtsi b/arch/arm64/boot/dts/broadcom/bcmbca/bcm63158.dtsi
index 909f254dc47d..48d618e75866 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm63158.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm63158.dtsi
@@ -137,6 +137,20 @@
status = "disabled";
};
+ nand_controller: nand-controller@1800 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+ reg = <0x1800 0x600>, <0x2000 0x10>;
+ reg-names = "nand", "nand-int-base";
+ status = "disabled";
+
+ nandcs: nand@0 {
+ compatible = "brcm,nandcs";
+ reg = <0>;
+ };
+ };
+
uart0: serial@12000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x12000 0x1000>;
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6813.dtsi b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6813.dtsi
index 685ae32951c9..1d1303cf90f3 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6813.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6813.dtsi
@@ -138,6 +138,20 @@
status = "disabled";
};
+ nand_controller: nand-controller@1800 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+ reg = <0x1800 0x600>, <0x2000 0x10>;
+ reg-names = "nand", "nand-int-base";
+ status = "disabled";
+
+ nandcs: nand@0 {
+ compatible = "brcm,nandcs";
+ reg = <0>;
+ };
+ };
+
uart0: serial@12000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x12000 0x1000>;
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6856.dtsi b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6856.dtsi
index 820553ce541b..00c62c1e5df0 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6856.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6856.dtsi
@@ -119,5 +119,19 @@
num-cs = <8>;
status = "disabled";
};
+
+ nand_controller: nand-controller@1800 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+ reg = <0x1800 0x600>, <0x2000 0x10>;
+ reg-names = "nand", "nand-int-base";
+ status = "disabled";
+
+ nandcs: nand@0 {
+ compatible = "brcm,nandcs";
+ reg = <0>;
+ };
+ };
};
};
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi
index 0eb93c298297..caeaf428dc15 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi
@@ -156,5 +156,19 @@
num-cs = <8>;
status = "disabled";
};
+
+ nand_controller: nand-controller@1800 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.1", "brcm,brcmnand";
+ reg = <0x1800 0x600>, <0x2000 0x10>;
+ reg-names = "nand", "nand-int-base";
+ status = "disabled";
+
+ nandcs: nand@0 {
+ compatible = "brcm,nandcs";
+ reg = <0>;
+ };
+ };
};
};
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm94908.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm94908.dts
index c4e6e71f6310..030ffa5364fb 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm94908.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm94908.dts
@@ -32,3 +32,13 @@
&hsspi {
status = "okay";
};
+
+&nand_controller {
+ brcm,wp-not-connected;
+ status = "okay";
+};
+
+&nandcs {
+ nand-on-flash-bbt;
+ brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm94912.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm94912.dts
index e69cd683211a..4b779e6c22e1 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm94912.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm94912.dts
@@ -32,3 +32,13 @@
&hsspi {
status = "okay";
};
+
+&nand_controller {
+ brcm,wp-not-connected;
+ status = "okay";
+};
+
+&nandcs {
+ nand-on-flash-bbt;
+ brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm963146.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm963146.dts
index db2c82d6dfd8..2851e8e41bf4 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm963146.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm963146.dts
@@ -32,3 +32,13 @@
&hsspi {
status = "okay";
};
+
+&nand_controller {
+ brcm,wp-not-connected;
+ status = "okay";
+};
+
+&nandcs {
+ nand-on-flash-bbt;
+ brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm963158.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm963158.dts
index 25c12bc63545..17dc594fe83f 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm963158.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm963158.dts
@@ -32,3 +32,13 @@
&hsspi {
status = "okay";
};
+
+&nand_controller {
+ brcm,wp-not-connected;
+ status = "okay";
+};
+
+&nandcs {
+ nand-on-flash-bbt;
+ brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm96813.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm96813.dts
index faba21f03120..34832a734734 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm96813.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm96813.dts
@@ -32,3 +32,13 @@
&hsspi {
status = "okay";
};
+
+&nand_controller {
+ brcm,wp-not-connected;
+ status = "okay";
+};
+
+&nandcs {
+ nand-on-flash-bbt;
+ brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm96856.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm96856.dts
index 9808331eede2..e1396b5544b7 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm96856.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm96856.dts
@@ -32,3 +32,13 @@
&hsspi {
status = "okay";
};
+
+&nand_controller {
+ brcm,wp-not-connected;
+ status = "okay";
+};
+
+&nandcs {
+ nand-on-flash-bbt;
+ brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm64/boot/dts/broadcom/bcmbca/bcm96858.dts b/arch/arm64/boot/dts/broadcom/bcmbca/bcm96858.dts
index 1f561c8e13b0..30bbf6f2917e 100644
--- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm96858.dts
+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm96858.dts
@@ -32,3 +32,13 @@
&hsspi {
status = "okay";
};
+
+&nand_controller {
+ brcm,wp-not-connected;
+ status = "okay";
+};
+
+&nandcs {
+ nand-on-flash-bbt;
+ brcm,nand-ecc-use-strap;
+};
diff --git a/arch/arm64/boot/dts/exynos/exynos850.dtsi b/arch/arm64/boot/dts/exynos/exynos850.dtsi
index da3f4a791e68..2ba67c3d0681 100644
--- a/arch/arm64/boot/dts/exynos/exynos850.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos850.dtsi
@@ -184,6 +184,16 @@
clock-names = "fin_pll", "mct";
};
+ pdma0: dma-controller@120c0000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0x120c0000 0x1000>;
+ clocks = <&cmu_core CLK_GOUT_PDMA_CORE_ACLK>;
+ clock-names = "apb_pclk";
+ #dma-cells = <1>;
+ interrupts = <GIC_SPI 479 IRQ_TYPE_LEVEL_HIGH>;
+ arm,pl330-broken-no-flushp;
+ };
+
gic: interrupt-controller@12a01000 {
compatible = "arm,gic-400";
#interrupt-cells = <3>;
@@ -728,6 +738,24 @@
<&cmu_peri CLK_GOUT_SPI0_IPCLK>;
clock-names = "pclk", "ipclk";
status = "disabled";
+
+ spi_0: spi@13940000 {
+ compatible = "samsung,exynos850-spi";
+ reg = <0x13940000 0x30>;
+ clocks = <&cmu_peri CLK_GOUT_SPI0_PCLK>,
+ <&cmu_peri CLK_GOUT_SPI0_IPCLK>;
+ clock-names = "spi", "spi_busclk0";
+ dmas = <&pdma0 5>, <&pdma0 4>;
+ dma-names = "tx", "rx";
+ interrupts = <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>;
+ pinctrl-0 = <&spi0_pins>;
+ pinctrl-names = "default";
+ num-cs = <1>;
+ samsung,spi-src-clk = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
};
usi_cmgp0: usi@11d000c0 {
@@ -769,6 +797,24 @@
clock-names = "uart", "clk_uart_baud0";
status = "disabled";
};
+
+ spi_1: spi@11d00000 {
+ compatible = "samsung,exynos850-spi";
+ reg = <0x11d00000 0x30>;
+ clocks = <&cmu_cmgp CLK_GOUT_CMGP_USI0_PCLK>,
+ <&cmu_cmgp CLK_GOUT_CMGP_USI0_IPCLK>;
+ clock-names = "spi", "spi_busclk0";
+ dmas = <&pdma0 12>, <&pdma0 13>;
+ dma-names = "tx", "rx";
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+ pinctrl-0 = <&spi1_pins>;
+ pinctrl-names = "default";
+ num-cs = <1>;
+ samsung,spi-src-clk = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
};
usi_cmgp1: usi@11d200c0 {
@@ -810,6 +856,24 @@
clock-names = "uart", "clk_uart_baud0";
status = "disabled";
};
+
+ spi_2: spi@11d20000 {
+ compatible = "samsung,exynos850-spi";
+ reg = <0x11d20000 0x30>;
+ clocks = <&cmu_cmgp CLK_GOUT_CMGP_USI1_PCLK>,
+ <&cmu_cmgp CLK_GOUT_CMGP_USI1_IPCLK>;
+ clock-names = "spi", "spi_busclk0";
+ dmas = <&pdma0 14>, <&pdma0 15>;
+ dma-names = "tx", "rx";
+ interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+ pinctrl-0 = <&spi2_pins>;
+ pinctrl-names = "default";
+ num-cs = <1>;
+ samsung,spi-src-clk = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ 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 4a71f752200d..6ccade2c8cb4 100644
--- a/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
+++ b/arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
@@ -63,6 +63,20 @@
clock-frequency = <200000000>;
};
+&hsi2c_8 {
+ status = "okay";
+
+ eeprom: eeprom@50 {
+ compatible = "atmel,24c08";
+ reg = <0x50>;
+ };
+};
+
+&hsi2c_12 {
+ status = "okay";
+ /* TODO: add the devices once drivers exist */
+};
+
&pinctrl_far_alive {
key_voldown: key-voldown-pins {
samsung,pins = "gpa7-3";
@@ -99,6 +113,16 @@
status = "okay";
};
+&usi8 {
+ samsung,mode = <USI_V2_I2C>;
+ status = "okay";
+};
+
+&usi12 {
+ samsung,mode = <USI_V2_I2C>;
+ status = "okay";
+};
+
&watchdog_cl0 {
timeout-sec = <30>;
status = "okay";
diff --git a/arch/arm64/boot/dts/exynos/google/gs101-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/google/gs101-pinctrl.dtsi
index e6a9776d4d62..a675f822acec 100644
--- a/arch/arm64/boot/dts/exynos/google/gs101-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/exynos/google/gs101-pinctrl.dtsi
@@ -251,7 +251,7 @@
#interrupt-cells = <2>;
};
- pcie0_clkreq: pcie0-clkreq-pins{
+ pcie0_clkreq: pcie0-clkreq-pins {
samsung,pins = "gph0-1";
samsung,pin-function = <GS101_PIN_FUNC_2>;
samsung,pin-pud = <GS101_PIN_PULL_UP>;
diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
index d838e3a7af6e..55e6bcb3689e 100644
--- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi
+++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
@@ -73,7 +73,7 @@
compatible = "arm,cortex-a55";
reg = <0x0000>;
enable-method = "psci";
- cpu-idle-states = <&ANANKE_CPU_SLEEP>;
+ cpu-idle-states = <&ANANKE_CPU_SLEEP>;
capacity-dmips-mhz = <250>;
dynamic-power-coefficient = <70>;
};
@@ -83,7 +83,7 @@
compatible = "arm,cortex-a55";
reg = <0x0100>;
enable-method = "psci";
- cpu-idle-states = <&ANANKE_CPU_SLEEP>;
+ cpu-idle-states = <&ANANKE_CPU_SLEEP>;
capacity-dmips-mhz = <250>;
dynamic-power-coefficient = <70>;
};
@@ -93,7 +93,7 @@
compatible = "arm,cortex-a55";
reg = <0x0200>;
enable-method = "psci";
- cpu-idle-states = <&ANANKE_CPU_SLEEP>;
+ cpu-idle-states = <&ANANKE_CPU_SLEEP>;
capacity-dmips-mhz = <250>;
dynamic-power-coefficient = <70>;
};
@@ -103,7 +103,7 @@
compatible = "arm,cortex-a55";
reg = <0x0300>;
enable-method = "psci";
- cpu-idle-states = <&ANANKE_CPU_SLEEP>;
+ cpu-idle-states = <&ANANKE_CPU_SLEEP>;
capacity-dmips-mhz = <250>;
dynamic-power-coefficient = <70>;
};
@@ -113,7 +113,7 @@
compatible = "arm,cortex-a76";
reg = <0x0400>;
enable-method = "psci";
- cpu-idle-states = <&ENYO_CPU_SLEEP>;
+ cpu-idle-states = <&ENYO_CPU_SLEEP>;
capacity-dmips-mhz = <620>;
dynamic-power-coefficient = <284>;
};
@@ -123,7 +123,7 @@
compatible = "arm,cortex-a76";
reg = <0x0500>;
enable-method = "psci";
- cpu-idle-states = <&ENYO_CPU_SLEEP>;
+ cpu-idle-states = <&ENYO_CPU_SLEEP>;
capacity-dmips-mhz = <620>;
dynamic-power-coefficient = <284>;
};
@@ -133,7 +133,7 @@
compatible = "arm,cortex-x1";
reg = <0x0600>;
enable-method = "psci";
- cpu-idle-states = <&HERA_CPU_SLEEP>;
+ cpu-idle-states = <&HERA_CPU_SLEEP>;
capacity-dmips-mhz = <1024>;
dynamic-power-coefficient = <650>;
};
@@ -143,7 +143,7 @@
compatible = "arm,cortex-x1";
reg = <0x0700>;
enable-method = "psci";
- cpu-idle-states = <&HERA_CPU_SLEEP>;
+ cpu-idle-states = <&HERA_CPU_SLEEP>;
capacity-dmips-mhz = <1024>;
dynamic-power-coefficient = <650>;
};
@@ -180,14 +180,6 @@
};
};
- /* TODO replace with CCF clock */
- dummy_clk: clock-3 {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <12345>;
- clock-output-names = "pclk";
- };
-
/* ect node is required to be present by bootloader */
ect {
};
@@ -292,6 +284,26 @@
clock-names = "bus", "sss";
};
+ timer@10050000 {
+ compatible = "google,gs101-mct",
+ "samsung,exynos4210-mct";
+ reg = <0x10050000 0x800>;
+ 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>,
+ <GIC_SPI 756 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 757 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 758 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 759 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 760 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 761 IRQ_TYPE_LEVEL_HIGH 0>,
+ <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>;
@@ -339,9 +351,20 @@
};
};
+ cmu_peric0: clock-controller@10800000 {
+ compatible = "google,gs101-cmu-peric0";
+ reg = <0x10800000 0x4000>;
+ #clock-cells = <1>;
+ clocks = <&ext_24_5m>,
+ <&cmu_top CLK_DOUT_CMU_PERIC0_BUS>,
+ <&cmu_top CLK_DOUT_CMU_PERIC0_IP>;
+ clock-names = "oscclk", "bus", "ip";
+ };
+
sysreg_peric0: syscon@10820000 {
compatible = "google,gs101-peric0-sysreg", "syscon";
reg = <0x10820000 0x10000>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_SYSREG_PERIC0_PCLK>;
};
pinctrl_peric0: pinctrl@10840000 {
@@ -350,6 +373,35 @@
interrupts = <GIC_SPI 625 IRQ_TYPE_LEVEL_HIGH 0>;
};
+ usi8: usi@109700c0 {
+ compatible = "google,gs101-usi",
+ "samsung,exynos850-usi";
+ reg = <0x109700c0 0x20>;
+ ranges;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_7>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_7>;
+ clock-names = "pclk", "ipclk";
+ samsung,sysreg = <&sysreg_peric0 0x101c>;
+ status = "disabled";
+
+ hsi2c_8: i2c@10970000 {
+ 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";
+ status = "disabled";
+ };
+ };
+
usi_uart: usi@10a000c0 {
compatible = "google,gs101-usi",
"samsung,exynos850-usi";
@@ -357,7 +409,8 @@
ranges;
#address-cells = <1>;
#size-cells = <1>;
- clocks = <&dummy_clk>, <&dummy_clk>;
+ clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP1_PCLK_0>,
+ <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP1_IPCLK_0>;
clock-names = "pclk", "ipclk";
samsung,sysreg = <&sysreg_peric0 0x1020>;
samsung,mode = <USI_V2_UART>;
@@ -366,19 +419,30 @@
serial_0: serial@10a00000 {
compatible = "google,gs101-uart";
reg = <0x10a00000 0xc0>;
- reg-io-width = <4>;
interrupts = <GIC_SPI 634
IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&dummy_clk 0>, <&dummy_clk 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";
samsung,uart-fifosize = <256>;
status = "disabled";
};
};
+ cmu_peric1: clock-controller@10c00000 {
+ compatible = "google,gs101-cmu-peric1";
+ reg = <0x10c00000 0x4000>;
+ #clock-cells = <1>;
+ clocks = <&ext_24_5m>,
+ <&cmu_top CLK_DOUT_CMU_PERIC1_BUS>,
+ <&cmu_top CLK_DOUT_CMU_PERIC1_IP>;
+ clock-names = "oscclk", "bus", "ip";
+ };
+
sysreg_peric1: syscon@10c20000 {
compatible = "google,gs101-peric1-sysreg", "syscon";
reg = <0x10c20000 0x10000>;
+ clocks = <&cmu_peric1 CLK_GOUT_PERIC1_SYSREG_PERIC1_PCLK>;
};
pinctrl_peric1: pinctrl@10c40000 {
@@ -387,6 +451,35 @@
interrupts = <GIC_SPI 644 IRQ_TYPE_LEVEL_HIGH 0>;
};
+ usi12: usi@10d500c0 {
+ compatible = "google,gs101-usi",
+ "samsung,exynos850-usi";
+ reg = <0x10d500c0 0x20>;
+ ranges;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_5>,
+ <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_5>;
+ clock-names = "pclk", "ipclk";
+ samsung,sysreg = <&sysreg_peric1 0x1010>;
+ status = "disabled";
+
+ hsi2c_12: i2c@10d50000 {
+ 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";
+ status = "disabled";
+ };
+ };
+
pinctrl_hsi1: pinctrl@11840000 {
compatible = "google,gs101-pinctrl";
reg = <0x11840000 0x00001000>;
diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 2cb0212b63c6..045250d0a040 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -99,6 +99,7 @@ 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) += imx8dxl-evk.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8dxp-tqma8xdp-mba8xx.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mm-beacon-kit.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mm-data-modul-edm-sbc.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mm-ddr4-evk.dtb
@@ -152,7 +153,9 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mn-var-som-symphony.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mn-venice-gw7902.dtb
imx8mn-tqma8mqnl-mba8mx-lvds-tm070jvhg33-dtbs += imx8mn-tqma8mqnl-mba8mx.dtb imx8mn-tqma8mqnl-mba8mx-lvds-tm070jvhg33.dtbo
+imx8mn-tqma8mqnl-mba8mx-usbotg-dtbs += imx8mn-tqma8mqnl-mba8mx.dtb imx8mn-tqma8mqnl-mba8mx-usbotg.dtbo
dtb-$(CONFIG_ARCH_MXC) += imx8mn-tqma8mqnl-mba8mx-lvds-tm070jvhg33.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mn-tqma8mqnl-mba8mx-usbotg.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-beacon-kit.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-data-modul-edm-sbc.dtb
@@ -207,8 +210,10 @@ imx8mq-tqma8mq-mba8mx-lvds-tm070jvhg33-dtbs += imx8mq-tqma8mq-mba8mx.dtb imx8mq-
dtb-$(CONFIG_ARCH_MXC) += imx8mq-tqma8mq-mba8mx-lvds-tm070jvhg33.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8qm-apalis-eval.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8qm-apalis-eval-v1.2.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8qm-apalis-ixora-v1.1.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8qm-apalis-v1.1-eval.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8qm-apalis-v1.1-eval-v1.2.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8qm-apalis-v1.1-ixora-v1.1.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8qm-apalis-v1.1-ixora-v1.2.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8qm-mek.dtb
@@ -218,10 +223,13 @@ dtb-$(CONFIG_ARCH_MXC) += imx8qxp-colibri-eval-v3.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8qxp-colibri-iris.dtb
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-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
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
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi
index 1e3fe3897b52..fe9093b3c02e 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi
@@ -290,7 +290,7 @@
dcfg: dcfg@1ee0000 {
compatible = "fsl,ls1012a-dcfg",
"syscon";
- reg = <0x0 0x1ee0000 0x0 0x10000>;
+ reg = <0x0 0x1ee0000 0x0 0x1000>;
big-endian;
};
@@ -351,24 +351,26 @@
};
i2c0: i2c@2180000 {
- compatible = "fsl,vf610-i2c";
+ compatible = "fsl,ls1012a-i2c", "fsl,vf610-i2c";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x0 0x2180000 0x0 0x10000>;
interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(4)>;
+ scl-gpios = <&gpio0 2 0>;
status = "disabled";
};
i2c1: i2c@2190000 {
- compatible = "fsl,vf610-i2c";
+ compatible = "fsl,ls1012a-i2c", "fsl,vf610-i2c";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x0 0x2190000 0x0 0x10000>;
interrupts = <0 57 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
QORIQ_CLK_PLL_DIV(4)>;
+ scl-gpios = <&gpio0 13 0>;
status = "disabled";
};
@@ -499,6 +501,7 @@
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 {
@@ -550,6 +553,7 @@
<0000 0 0 2 &gic 0 111 IRQ_TYPE_LEVEL_HIGH>,
<0000 0 0 3 &gic 0 112 IRQ_TYPE_LEVEL_HIGH>,
<0000 0 0 4 &gic 0 113 IRQ_TYPE_LEVEL_HIGH>;
+ big-endian;
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
index 1515cec23147..754a64be739c 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
@@ -485,7 +485,6 @@
<0x00030005 0x00000042>,
<0x00030006 0x0000004c>,
<0x00030007 0x00000056>;
- big-endian;
#thermal-sensor-cells = <1>;
};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
index 8616d5e0c388..604bf88d70b3 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
@@ -591,6 +591,8 @@
reg = <0x00 0x03400000 0x0 0x00100000>,
<0x20 0x00000000 0x8 0x00000000>;
reg-names = "regs", "addr_space";
+ interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; /* PME interrupt */
+ interrupt-names = "pme";
num-ib-windows = <24>;
num-ob-windows = <256>;
max-functions = /bits/ 8 <2>;
@@ -628,6 +630,8 @@
reg = <0x00 0x03500000 0x0 0x00100000>,
<0x28 0x00000000 0x8 0x00000000>;
reg-names = "regs", "addr_space";
+ interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; /* PME interrupt */
+ interrupt-names = "pme";
num-ib-windows = <6>;
num-ob-windows = <6>;
status = "disabled";
@@ -664,6 +668,8 @@
reg = <0x00 0x03600000 0x0 0x00100000>,
<0x30 0x00000000 0x8 0x00000000>;
reg-names = "regs", "addr_space";
+ interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>; /* PME interrupt */
+ interrupt-names = "pme";
num-ib-windows = <6>;
num-ob-windows = <6>;
status = "disabled";
diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
index 6640b49670ae..e665c629e1a1 100644
--- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
@@ -949,34 +949,50 @@
};
uart0: serial@21c0000 {
- compatible = "arm,sbsa-uart","arm,pl011";
+ compatible = "arm,pl011", "arm,primecell";
+ clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
+ QORIQ_CLK_PLL_DIV(8)>,
+ <&clockgen QORIQ_CLK_PLATFORM_PLL
+ QORIQ_CLK_PLL_DIV(8)>;
+ clock-names = "uartclk", "apb_pclk";
reg = <0x0 0x21c0000 0x0 0x1000>;
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
- current-speed = <115200>;
status = "disabled";
};
uart1: serial@21d0000 {
- compatible = "arm,sbsa-uart","arm,pl011";
+ compatible = "arm,pl011", "arm,primecell";
+ clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
+ QORIQ_CLK_PLL_DIV(8)>,
+ <&clockgen QORIQ_CLK_PLATFORM_PLL
+ QORIQ_CLK_PLL_DIV(8)>;
+ clock-names = "uartclk", "apb_pclk";
reg = <0x0 0x21d0000 0x0 0x1000>;
interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
- current-speed = <115200>;
status = "disabled";
};
uart2: serial@21e0000 {
- compatible = "arm,sbsa-uart","arm,pl011";
+ compatible = "arm,pl011", "arm,primecell";
+ clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
+ QORIQ_CLK_PLL_DIV(8)>,
+ <&clockgen QORIQ_CLK_PLATFORM_PLL
+ QORIQ_CLK_PLL_DIV(8)>;
+ clock-names = "uartclk", "apb_pclk";
reg = <0x0 0x21e0000 0x0 0x1000>;
interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
- current-speed = <115200>;
status = "disabled";
};
uart3: serial@21f0000 {
- compatible = "arm,sbsa-uart","arm,pl011";
+ compatible = "arm,pl011", "arm,primecell";
+ clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
+ QORIQ_CLK_PLL_DIV(8)>,
+ <&clockgen QORIQ_CLK_PLATFORM_PLL
+ QORIQ_CLK_PLL_DIV(8)>;
+ clock-names = "uartclk", "apb_pclk";
reg = <0x0 0x21f0000 0x0 0x1000>;
interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
- current-speed = <115200>;
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/freescale/imx8-apalis-eval-v1.1.dtsi b/arch/arm64/boot/dts/freescale/imx8-apalis-eval-v1.1.dtsi
new file mode 100644
index 000000000000..0f77f78f4d96
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8-apalis-eval-v1.1.dtsi
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2024 Toradex
+ */
+
+#include "imx8-apalis-eval.dtsi"
+
+/* Apalis CAN1 */
+&flexcan1 {
+ status = "okay";
+};
+
+/* Apalis CAN2 */
+&flexcan2 {
+ status = "okay";
+};
+
+/* Apalis MMC1 */
+&usdhc2 {
+ status = "okay";
+};
+
+/* Apalis SD1 */
+&usdhc3 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8-apalis-eval-v1.2.dtsi b/arch/arm64/boot/dts/freescale/imx8-apalis-eval-v1.2.dtsi
new file mode 100644
index 000000000000..f5c6a0164f36
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8-apalis-eval-v1.2.dtsi
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2024 Toradex
+ */
+
+#include "imx8-apalis-eval.dtsi"
+
+/ {
+ reg_3v3_mmc: regulator-3v3-mmc {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enable_3v3_mmc>;
+ enable-active-high;
+ gpio = <&lsio_gpio5 19 GPIO_ACTIVE_HIGH>;
+ off-on-delay-us = <100000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "3.3V_MMC";
+ startup-delay-us = <10000>;
+ };
+
+ reg_3v3_sd: regulator-3v3-sd {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enable_3v3_sd>;
+ enable-active-high;
+ gpio = <&lsio_gpio5 20 GPIO_ACTIVE_HIGH>;
+ off-on-delay-us = <100000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "3.3V_SD";
+ startup-delay-us = <10000>;
+ };
+
+ reg_can1: regulator-can1 {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enable_can1_power>;
+ enable-active-high;
+ gpio = <&lsio_gpio5 22 GPIO_ACTIVE_HIGH>;
+ regulator-name = "5V_SW_CAN1";
+ startup-delay-us = <10000>;
+ };
+
+ reg_can2: regulator-can2 {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enable_can2_power>;
+ enable-active-high;
+ gpio = <&lsio_gpio5 21 GPIO_ACTIVE_HIGH>;
+ regulator-name = "5V_SW_CAN2";
+ startup-delay-us = <10000>;
+ };
+};
+
+/* Apalis CAN1 */
+&flexcan1 {
+ xceiver-supply = <&reg_can1>;
+ status = "okay";
+};
+
+/* Apalis CAN2 */
+&flexcan2 {
+ xceiver-supply = <&reg_can2>;
+ status = "okay";
+};
+
+/* Apalis I2C1 */
+&i2c2 {
+ status = "okay";
+
+ /* Power/Current Measurement Sensor */
+ hwmon@40 {
+ compatible = "ti,ina219";
+ reg = <0x40>;
+ shunt-resistor = <5000>;
+ };
+
+ temperature-sensor@4f {
+ compatible = "ti,tmp75c";
+ reg = <0x4f>;
+ };
+
+ eeprom@57 {
+ compatible = "st,24c02", "atmel,24c02";
+ reg = <0x57>;
+ };
+};
+
+/* Apalis MMC1 */
+&usdhc2 {
+ pinctrl-0 = <&pinctrl_usdhc2_4bit>, <&pinctrl_mmc1_cd>;
+ pinctrl-1 = <&pinctrl_usdhc2_4bit_100mhz>, <&pinctrl_mmc1_cd>;
+ pinctrl-2 = <&pinctrl_usdhc2_4bit_200mhz>, <&pinctrl_mmc1_cd>;
+ pinctrl-3 = <&pinctrl_usdhc2_4bit_sleep>, <&pinctrl_mmc1_cd_sleep>;
+ bus-width = <4>;
+ vmmc-supply = <&reg_3v3_mmc>;
+ status = "okay";
+};
+
+/* Apalis SD1 */
+&usdhc3 {
+ vmmc-supply = <&reg_3v3_sd>;
+ status = "okay";
+};
+
+&iomuxc {
+
+ pinctrl_enable_3v3_mmc: enable3v3mmcgrp {
+ fsl,pins = <IMX8QM_USDHC1_DATA4_LSIO_GPIO5_IO19 0x00000021>; /* MXM3_148 */
+ };
+
+ pinctrl_enable_3v3_sd: enable3v3sdgrp {
+ fsl,pins = <IMX8QM_USDHC1_DATA5_LSIO_GPIO5_IO20 0x00000021>; /* MXM3_152 */
+ };
+
+ pinctrl_enable_can1_power: enablecan1powergrp {
+ fsl,pins = <IMX8QM_USDHC1_DATA7_LSIO_GPIO5_IO22 0x00000021>; /* MXM3_158 */
+ };
+
+ pinctrl_enable_can2_power: enablecan2powergrp {
+ fsl,pins = <IMX8QM_USDHC1_DATA6_LSIO_GPIO5_IO21 0x00000021>; /* MXM3_156 */
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8-apalis-eval.dtsi b/arch/arm64/boot/dts/freescale/imx8-apalis-eval.dtsi
index 685d4294f4f1..deecb96a1596 100644
--- a/arch/arm64/boot/dts/freescale/imx8-apalis-eval.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8-apalis-eval.dtsi
@@ -35,18 +35,6 @@
status = "okay";
};
-/* Apalis CAN1 */
-&flexcan1 {
- status = "okay";
-};
-
-/* Apalis CAN2 */
-&flexcan2 {
- status = "okay";
-};
-
-/* TODO: GPU */
-
/* Apalis I2C1 */
&i2c2 {
status = "okay";
@@ -132,13 +120,3 @@
};
/* TODO: Apalis USBH4 SuperSpeed */
-
-/* Apalis MMC1 */
-&usdhc2 {
- status = "okay";
-};
-
-/* Apalis SD1 */
-&usdhc3 {
- status = "okay";
-};
diff --git a/arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi b/arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi
index f69b0c17560a..160153853b68 100644
--- a/arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi
@@ -261,7 +261,6 @@
reset-assert-us = <2>;
reset-deassert-us = <2>;
reset-gpios = <&lsio_gpio1 11 GPIO_ACTIVE_LOW>;
- reset-names = "phy";
};
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-audio.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-audio.dtsi
index f057c6b21b30..07afeb78ed56 100644
--- a/arch/arm64/boot/dts/freescale/imx8-ss-audio.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-audio.dtsi
@@ -4,6 +4,7 @@
* Dong Aisheng <aisheng.dong@nxp.com>
*/
+#include <dt-bindings/clock/imx8-clock.h>
#include <dt-bindings/clock/imx8-lpcg.h>
#include <dt-bindings/firmware/imx/rsrc.h>
@@ -14,12 +15,174 @@ audio_ipg_clk: clock-audio-ipg {
clock-output-names = "audio_ipg_clk";
};
+clk_ext_aud_mclk0: clock-ext-aud-mclk0 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "ext_aud_mclk0";
+};
+
+clk_ext_aud_mclk1: clock-ext-aud-mclk1 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "ext_aud_mclk1";
+};
+
+clk_esai0_rx_clk: clock-esai0-rx {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "esai0_rx_clk";
+};
+
+clk_esai0_rx_hf_clk: clock-esai0-rx-hf {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "esai0_rx_hf_clk";
+};
+
+clk_esai0_tx_clk: clock-esai0-tx {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "esai0_tx_clk";
+};
+
+clk_esai0_tx_hf_clk: clock-esai0-tx-hf {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "esai0_tx_hf_clk";
+};
+
+clk_spdif0_rx: clock-spdif0-rx {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "spdif0_rx";
+};
+
+clk_sai0_rx_bclk: clock-sai0-rx-bclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "sai0_rx_bclk";
+};
+
+clk_sai0_tx_bclk: clock-sai0-tx-bclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "sai0_tx_bclk";
+};
+
+clk_sai1_rx_bclk: clock-sai1-rx-bclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "sai1_rx_bclk";
+};
+
+clk_sai1_tx_bclk: clock-sai1-tx-bclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "sai1_tx_bclk";
+};
+
+clk_sai2_rx_bclk: clock-sai2-rx-bclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "sai2_rx_bclk";
+};
+
+clk_sai3_rx_bclk: clock-sai3-rx-bclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "sai3_rx_bclk";
+};
+
+clk_sai4_rx_bclk: clock-sai4-rx-bclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "sai4_rx_bclk";
+};
+
audio_subsys: bus@59000000 {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x59000000 0x0 0x59000000 0x1000000>;
+ sai0: sai@59040000 {
+ compatible = "fsl,imx8qm-sai";
+ reg = <0x59040000 0x10000>;
+ interrupts = <GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&sai0_lpcg 1>,
+ <&clk_dummy>,
+ <&sai0_lpcg 0>,
+ <&clk_dummy>,
+ <&clk_dummy>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dma-names = "rx", "tx";
+ dmas = <&edma0 12 0 1>, <&edma0 13 0 0>;
+ power-domains = <&pd IMX_SC_R_SAI_0>;
+ status = "disabled";
+ };
+
+ sai1: sai@59050000 {
+ compatible = "fsl,imx8qm-sai";
+ reg = <0x59050000 0x10000>;
+ interrupts = <GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&sai1_lpcg 1>,
+ <&clk_dummy>,
+ <&sai1_lpcg 0>,
+ <&clk_dummy>,
+ <&clk_dummy>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dma-names = "rx", "tx";
+ dmas = <&edma0 14 0 1>, <&edma0 15 0 0>;
+ power-domains = <&pd IMX_SC_R_SAI_1>;
+ status = "disabled";
+ };
+
+ sai2: sai@59060000 {
+ compatible = "fsl,imx8qm-sai";
+ reg = <0x59060000 0x10000>;
+ interrupts = <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&sai2_lpcg 1>,
+ <&clk_dummy>,
+ <&sai2_lpcg 0>,
+ <&clk_dummy>,
+ <&clk_dummy>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dma-names = "rx";
+ dmas = <&edma0 16 0 1>;
+ power-domains = <&pd IMX_SC_R_SAI_2>;
+ status = "disabled";
+ };
+
+ sai3: sai@59070000 {
+ compatible = "fsl,imx8qm-sai";
+ reg = <0x59070000 0x10000>;
+ interrupts = <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&sai3_lpcg 1>,
+ <&clk_dummy>,
+ <&sai3_lpcg 0>,
+ <&clk_dummy>,
+ <&clk_dummy>;
+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+ dma-names = "rx";
+ dmas = <&edma0 17 0 1>;
+ power-domains = <&pd IMX_SC_R_SAI_3>;
+ status = "disabled";
+ };
+
edma0: dma-controller@591f0000 {
compatible = "fsl,imx8qm-edma";
reg = <0x591f0000 0x190000>;
@@ -76,6 +239,54 @@ audio_subsys: bus@59000000 {
<&pd IMX_SC_R_DMA_0_CH23>;
};
+ sai0_lpcg: clock-controller@59440000 {
+ compatible = "fsl,imx8qxp-lpcg";
+ reg = <0x59440000 0x10000>;
+ #clock-cells = <1>;
+ clocks = <&acm IMX_ADMA_ACM_SAI0_MCLK_SEL>,
+ <&audio_ipg_clk>;
+ clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_4>;
+ clock-output-names = "sai0_lpcg_mclk",
+ "sai0_lpcg_ipg_clk";
+ power-domains = <&pd IMX_SC_R_SAI_0>;
+ };
+
+ sai1_lpcg: clock-controller@59450000 {
+ compatible = "fsl,imx8qxp-lpcg";
+ reg = <0x59450000 0x10000>;
+ #clock-cells = <1>;
+ clocks = <&acm IMX_ADMA_ACM_SAI1_MCLK_SEL>,
+ <&audio_ipg_clk>;
+ clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_4>;
+ clock-output-names = "sai1_lpcg_mclk",
+ "sai1_lpcg_ipg_clk";
+ power-domains = <&pd IMX_SC_R_SAI_1>;
+ };
+
+ sai2_lpcg: clock-controller@59460000 {
+ compatible = "fsl,imx8qxp-lpcg";
+ reg = <0x59460000 0x10000>;
+ #clock-cells = <1>;
+ clocks = <&acm IMX_ADMA_ACM_SAI2_MCLK_SEL>,
+ <&audio_ipg_clk>;
+ clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_4>;
+ clock-output-names = "sai2_lpcg_mclk",
+ "sai2_lpcg_ipg_clk";
+ power-domains = <&pd IMX_SC_R_SAI_2>;
+ };
+
+ sai3_lpcg: clock-controller@59470000 {
+ compatible = "fsl,imx8qxp-lpcg";
+ reg = <0x59470000 0x10000>;
+ #clock-cells = <1>;
+ clocks = <&acm IMX_ADMA_ACM_SAI3_MCLK_SEL>,
+ <&audio_ipg_clk>;
+ clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_4>;
+ clock-output-names = "sai3_lpcg_mclk",
+ "sai3_lpcg_ipg_clk";
+ power-domains = <&pd IMX_SC_R_SAI_3>;
+ };
+
dsp_lpcg: clock-controller@59580000 {
compatible = "fsl,imx8qxp-lpcg";
reg = <0x59580000 0x10000>;
@@ -151,4 +362,123 @@ audio_subsys: bus@59000000 {
<&pd IMX_SC_R_DMA_1_CH9>,
<&pd IMX_SC_R_DMA_1_CH10>;
};
+
+ aud_rec0_lpcg: clock-controller@59d00000 {
+ compatible = "fsl,imx8qxp-lpcg";
+ reg = <0x59d00000 0x10000>;
+ #clock-cells = <1>;
+ clocks = <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_MST_BUS>;
+ clock-indices = <IMX_LPCG_CLK_0>;
+ clock-output-names = "aud_rec_clk0_lpcg_clk";
+ power-domains = <&pd IMX_SC_R_AUDIO_PLL_0>;
+ };
+
+ aud_rec1_lpcg: clock-controller@59d10000 {
+ compatible = "fsl,imx8qxp-lpcg";
+ reg = <0x59d10000 0x10000>;
+ #clock-cells = <1>;
+ clocks = <&clk IMX_SC_R_AUDIO_PLL_1 IMX_SC_PM_CLK_MST_BUS>;
+ clock-indices = <IMX_LPCG_CLK_0>;
+ clock-output-names = "aud_rec_clk1_lpcg_clk";
+ power-domains = <&pd IMX_SC_R_AUDIO_PLL_1>;
+ };
+
+ aud_pll_div0_lpcg: clock-controller@59d20000 {
+ compatible = "fsl,imx8qxp-lpcg";
+ reg = <0x59d20000 0x10000>;
+ #clock-cells = <1>;
+ clocks = <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_SLV_BUS>;
+ clock-indices = <IMX_LPCG_CLK_0>;
+ clock-output-names = "aud_pll_div_clk0_lpcg_clk";
+ power-domains = <&pd IMX_SC_R_AUDIO_PLL_0>;
+ };
+
+ aud_pll_div1_lpcg: clock-controller@59d30000 {
+ compatible = "fsl,imx8qxp-lpcg";
+ reg = <0x59d30000 0x10000>;
+ #clock-cells = <1>;
+ clocks = <&clk IMX_SC_R_AUDIO_PLL_1 IMX_SC_PM_CLK_SLV_BUS>;
+ clock-indices = <IMX_LPCG_CLK_0>;
+ clock-output-names = "aud_pll_div_clk1_lpcg_clk";
+ power-domains = <&pd IMX_SC_R_AUDIO_PLL_1>;
+ };
+
+ mclkout0_lpcg: clock-controller@59d50000 {
+ compatible = "fsl,imx8qxp-lpcg";
+ reg = <0x59d50000 0x10000>;
+ #clock-cells = <1>;
+ clocks = <&acm IMX_ADMA_ACM_MCLKOUT0_SEL>;
+ clock-indices = <IMX_LPCG_CLK_0>;
+ clock-output-names = "mclkout0_lpcg_clk";
+ power-domains = <&pd IMX_SC_R_MCLK_OUT_0>;
+ };
+
+ mclkout1_lpcg: clock-controller@59d60000 {
+ compatible = "fsl,imx8qxp-lpcg";
+ reg = <0x59d60000 0x10000>;
+ #clock-cells = <1>;
+ clocks = <&acm IMX_ADMA_ACM_MCLKOUT1_SEL>;
+ clock-indices = <IMX_LPCG_CLK_0>;
+ clock-output-names = "mclkout1_lpcg_clk";
+ power-domains = <&pd IMX_SC_R_MCLK_OUT_1>;
+ };
+
+ acm: acm@59e00000 {
+ compatible = "fsl,imx8qxp-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_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_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_esai0_rx_clk>,
+ <&clk_esai0_rx_hf_clk>,
+ <&clk_esai0_tx_clk>,
+ <&clk_esai0_tx_hf_clk>,
+ <&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>;
+ 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",
+ "esai0_rx_clk",
+ "esai0_rx_hf_clk",
+ "esai0_tx_clk",
+ "esai0_tx_hf_clk",
+ "spdif0_rx",
+ "sai0_rx_bclk",
+ "sai0_tx_bclk",
+ "sai1_rx_bclk",
+ "sai1_tx_bclk",
+ "sai2_rx_bclk",
+ "sai3_rx_bclk",
+ "sai4_rx_bclk";
+ };
};
diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi
index b0bb77150adc..cab3468b1875 100644
--- a/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi
@@ -5,6 +5,7 @@
*/
#include <dt-bindings/clock/imx8-lpcg.h>
+#include <dt-bindings/dma/fsl-edma.h>
#include <dt-bindings/firmware/imx/rsrc.h>
dma_ipg_clk: clock-dma-ipg {
@@ -93,8 +94,8 @@ dma_subsys: bus@5a000000 {
assigned-clocks = <&clk IMX_SC_R_UART_0 IMX_SC_PM_CLK_PER>;
assigned-clock-rates = <80000000>;
power-domains = <&pd IMX_SC_R_UART_0>;
- dma-names = "tx","rx";
- dmas = <&edma2 9 0 0>, <&edma2 8 0 1>;
+ dma-names = "rx", "tx";
+ dmas = <&edma2 8 0 FSL_EDMA_RX>, <&edma2 9 0 0>;
status = "disabled";
};
@@ -107,8 +108,8 @@ dma_subsys: bus@5a000000 {
assigned-clocks = <&clk IMX_SC_R_UART_1 IMX_SC_PM_CLK_PER>;
assigned-clock-rates = <80000000>;
power-domains = <&pd IMX_SC_R_UART_1>;
- dma-names = "tx","rx";
- dmas = <&edma2 11 0 0>, <&edma2 10 0 1>;
+ dma-names = "rx", "tx";
+ dmas = <&edma2 10 0 FSL_EDMA_RX>, <&edma2 11 0 0>;
status = "disabled";
};
@@ -121,8 +122,8 @@ dma_subsys: bus@5a000000 {
assigned-clocks = <&clk IMX_SC_R_UART_2 IMX_SC_PM_CLK_PER>;
assigned-clock-rates = <80000000>;
power-domains = <&pd IMX_SC_R_UART_2>;
- dma-names = "tx","rx";
- dmas = <&edma2 13 0 0>, <&edma2 12 0 1>;
+ dma-names = "rx", "tx";
+ dmas = <&edma2 12 0 FSL_EDMA_RX>, <&edma2 13 0 0>;
status = "disabled";
};
@@ -135,8 +136,8 @@ dma_subsys: bus@5a000000 {
assigned-clocks = <&clk IMX_SC_R_UART_3 IMX_SC_PM_CLK_PER>;
assigned-clock-rates = <80000000>;
power-domains = <&pd IMX_SC_R_UART_3>;
- dma-names = "tx","rx";
- dmas = <&edma2 15 0 0>, <&edma2 14 0 1>;
+ dma-names = "rx", "tx";
+ dmas = <&edma2 14 0 FSL_EDMA_RX>, <&edma2 15 0 0>;
status = "disabled";
};
@@ -192,29 +193,6 @@ dma_subsys: bus@5a000000 {
<&pd IMX_SC_R_DMA_2_CH15>;
};
- edma3: dma-controller@5a9f0000 {
- compatible = "fsl,imx8qm-edma";
- reg = <0x5a9f0000 0x90000>;
- #dma-cells = <3>;
- dma-channels = <8>;
- interrupts = <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 427 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 428 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 429 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 430 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 431 IRQ_TYPE_LEVEL_HIGH>;
- 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>;
- };
-
spi0_lpcg: clock-controller@5a400000 {
compatible = "fsl,imx8qxp-lpcg";
reg = <0x5a400000 0x10000>;
@@ -460,6 +438,29 @@ dma_subsys: bus@5a000000 {
status = "disabled";
};
+ edma3: dma-controller@5a9f0000 {
+ compatible = "fsl,imx8qm-edma";
+ reg = <0x5a9f0000 0x90000>;
+ #dma-cells = <3>;
+ dma-channels = <8>;
+ interrupts = <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 427 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 428 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 429 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 430 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 431 IRQ_TYPE_LEVEL_HIGH>;
+ 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>;
+ };
+
i2c0_lpcg: clock-controller@5ac00000 {
compatible = "fsl,imx8qxp-lpcg";
reg = <0x5ac00000 0x10000>;
diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-gpu0.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-gpu0.dtsi
new file mode 100644
index 000000000000..9b8a44aa63d6
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-gpu0.dtsi
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019 NXP
+ * Dong Aisheng <aisheng.dong@nxp.com>
+ */
+
+#include <dt-bindings/firmware/imx/rsrc.h>
+
+gpu0_subsys: bus@53000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x53000000 0x0 0x53000000 0x1000000>;
+
+ gpu_3d0: gpu@53100000 {
+ compatible = "vivante,gc";
+ reg = <0x53100000 0x40000>;
+ interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk IMX_SC_R_GPU_0_PID0 IMX_SC_PM_CLK_PER>,
+ <&clk IMX_SC_R_GPU_0_PID0 IMX_SC_PM_CLK_MISC>;
+ clock-names = "core", "shader";
+ assigned-clocks = <&clk IMX_SC_R_GPU_0_PID0 IMX_SC_PM_CLK_PER>,
+ <&clk IMX_SC_R_GPU_0_PID0 IMX_SC_PM_CLK_MISC>;
+ assigned-clock-rates = <700000000>, <850000000>;
+ power-domains = <&pd IMX_SC_R_GPU_0_PID0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts b/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts
index b972658efb17..2123d431e061 100644
--- a/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts
@@ -81,6 +81,24 @@
status = "disabled";
};
+ reg_can0_stby: regulator-4 {
+ compatible = "regulator-fixed";
+ regulator-name = "can0-stby";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pca6416_3 0 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_can1_stby: regulator-5 {
+ compatible = "regulator-fixed";
+ regulator-name = "can1-stby";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pca6416_3 1 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
reg_usdhc2_vmmc: regulator-3 {
compatible = "regulator-fixed";
regulator-name = "SD1_SPWR";
@@ -261,12 +279,81 @@
};
};
+&i2c3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+ status = "okay";
+
+ pca6416_3: gpio@20 {
+ compatible = "ti,tca6416";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&lsio_gpio2>;
+ interrupts = <5 IRQ_TYPE_EDGE_RISING>;
+ };
+
+ pca9548_2: i2c-mux@70 {
+ compatible = "nxp,pca9548";
+ reg = <0x70>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0>;
+ };
+
+ i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x1>;
+ };
+
+ i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x2>;
+ };
+
+ i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x3>;
+ };
+
+ i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x4>;
+ };
+ };
+};
+
&lpuart0 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_lpuart0>;
status = "okay";
};
+&flexcan2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ xceiver-supply = <&reg_can0_stby>;
+ status = "okay";
+};
+
+&flexcan3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan3>;
+ xceiver-supply = <&reg_can1_stby>;
+ status = "okay";
+};
+
&lsio_gpio4 {
status = "okay";
};
@@ -436,6 +523,20 @@
>;
};
+ pinctrl_flexcan2: flexcan2grp {
+ fsl,pins = <
+ IMX8DXL_UART2_TX_ADMA_FLEXCAN1_TX 0x00000021
+ IMX8DXL_UART2_RX_ADMA_FLEXCAN1_RX 0x00000021
+ >;
+ };
+
+ pinctrl_flexcan3: flexcan3grp {
+ fsl,pins = <
+ IMX8DXL_FLEXCAN2_TX_ADMA_FLEXCAN2_TX 0x00000021
+ IMX8DXL_FLEXCAN2_RX_ADMA_FLEXCAN2_RX 0x00000021
+ >;
+ };
+
pinctrl_fec1: fec1grp {
fsl,pins = <
IMX8DXL_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB0_PAD 0x000014a0
diff --git a/arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi b/arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi
index 0a477f6318f1..5d012c95222f 100644
--- a/arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi
@@ -15,6 +15,63 @@
interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
};
+&edma0 {
+ reg = <0x591f0000 0x1a0000>;
+ #dma-cells = <3>;
+ dma-channels = <25>;
+ dma-channel-mask = <0x1c0cc0>;
+ interrupts = <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>, /* asrc 0 */
+ <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 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>, /* spdif0 */
+ <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>, /* sai0 */
+ <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>, /* sai1 */
+ <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>, /* sai2 */
+ <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>, /* sai3 */
+ <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>, /* gpt0 */
+ <GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>, /* gpt1 */
+ <GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH>, /* gpt2 */
+ <GIC_SPI 271 IRQ_TYPE_LEVEL_HIGH>; /* gpt3 */
+ power-domains = <&pd IMX_SC_R_DMA_0_CH0>,
+ <&pd IMX_SC_R_DMA_0_CH1>,
+ <&pd IMX_SC_R_DMA_0_CH2>,
+ <&pd IMX_SC_R_DMA_0_CH3>,
+ <&pd IMX_SC_R_DMA_0_CH4>,
+ <&pd IMX_SC_R_DMA_0_CH5>,
+ <&pd IMX_SC_R_DMA_0_CH6>,
+ <&pd IMX_SC_R_DMA_0_CH7>,
+ <&pd IMX_SC_R_DMA_0_CH8>,
+ <&pd IMX_SC_R_DMA_0_CH9>,
+ <&pd IMX_SC_R_DMA_0_CH10>,
+ <&pd IMX_SC_R_DMA_0_CH11>,
+ <&pd IMX_SC_R_DMA_0_CH12>,
+ <&pd IMX_SC_R_DMA_0_CH13>,
+ <&pd IMX_SC_R_DMA_0_CH14>,
+ <&pd IMX_SC_R_DMA_0_CH15>,
+ <&pd IMX_SC_R_DMA_0_CH16>,
+ <&pd IMX_SC_R_DMA_0_CH17>,
+ <&pd IMX_SC_R_DMA_0_CH18>,
+ <&pd IMX_SC_R_DMA_0_CH19>,
+ <&pd IMX_SC_R_DMA_0_CH20>,
+ <&pd IMX_SC_R_DMA_0_CH21>,
+ <&pd IMX_SC_R_DMA_0_CH22>,
+ <&pd IMX_SC_R_DMA_0_CH23>,
+ <&pd IMX_SC_R_DMA_0_CH24>;
+};
+
&edma2 {
interrupts = <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 289 IRQ_TYPE_LEVEL_HIGH>,
@@ -45,24 +102,44 @@
<GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>;
};
+&flexcan1 {
+ interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&flexcan2 {
+ interrupts = <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&flexcan3 {
+ interrupts = <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>;
+};
+
&i2c0 {
compatible = "fsl,imx8dxl-lpi2c", "fsl,imx7ulp-lpi2c";
interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>;
+ dma-names = "tx","rx";
+ dmas = <&edma3 1 0 0>, <&edma3 0 0 FSL_EDMA_RX>;
};
&i2c1 {
compatible = "fsl,imx8dxl-lpi2c", "fsl,imx7ulp-lpi2c";
interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>;
+ dma-names = "tx","rx";
+ dmas = <&edma3 3 0 0>, <&edma3 2 0 FSL_EDMA_RX>;
};
&i2c2 {
compatible = "fsl,imx8dxl-lpi2c", "fsl,imx7ulp-lpi2c";
interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
+ dma-names = "tx","rx";
+ dmas = <&edma3 5 0 0>, <&edma3 4 0 FSL_EDMA_RX>;
};
&i2c3 {
compatible = "fsl,imx8dxl-lpi2c", "fsl,imx7ulp-lpi2c";
interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+ dma-names = "tx","rx";
+ dmas = <&edma3 7 0 0>, <&edma3 6 0 FSL_EDMA_RX>;
};
&lpuart0 {
diff --git a/arch/arm64/boot/dts/freescale/imx8dxl.dtsi b/arch/arm64/boot/dts/freescale/imx8dxl.dtsi
index f580eb6db9a6..a0674c5c5576 100644
--- a/arch/arm64/boot/dts/freescale/imx8dxl.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8dxl.dtsi
@@ -4,6 +4,7 @@
*/
#include <dt-bindings/clock/imx8-clock.h>
+#include <dt-bindings/dma/fsl-edma.h>
#include <dt-bindings/firmware/imx/rsrc.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
diff --git a/arch/arm64/boot/dts/freescale/imx8dxp-tqma8xdp-mba8xx.dts b/arch/arm64/boot/dts/freescale/imx8dxp-tqma8xdp-mba8xx.dts
new file mode 100644
index 000000000000..f35514b7b338
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8dxp-tqma8xdp-mba8xx.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR X11)
+/*
+ * Copyright 2018-2023 TQ-Systems GmbH <linux@ew.tq-group.com>,
+ * D-82229 Seefeld, Germany.
+ * Author: Alexander Stein
+ */
+
+/dts-v1/;
+
+#include "imx8dxp-tqma8xdp.dtsi"
+#include "mba8xx.dtsi"
+
+/ {
+ model = "TQ-Systems i.MX8DXP TQMa8XDP on MBa8Xx";
+ compatible = "tq,imx8dxp-tqma8xdp-mba8xx", "tq,imx8dxp-tqma8xdp", "fsl,imx8dxp";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8dxp-tqma8xdp.dtsi b/arch/arm64/boot/dts/freescale/imx8dxp-tqma8xdp.dtsi
new file mode 100644
index 000000000000..e2de8517aa0e
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8dxp-tqma8xdp.dtsi
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR X11)
+/*
+ * Copyright 2018-2023 TQ-Systems GmbH <linux@ew.tq-group.com>,
+ * D-82229 Seefeld, Germany.
+ * Author: Alexander Stein
+ */
+
+#include "imx8dxp.dtsi"
+#include "tqma8xx.dtsi"
+
+/ {
+ model = "TQ-Systems i.MX8DXP TQMa8XDP";
+ compatible = "tq,imx8dxp-tqma8xdp", "fsl,imx8dxp";
+};
+
+&pmic_thermal {
+ cooling-maps {
+ map0 {
+ cooling-device =
+ <&A35_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A35_1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8dxp.dtsi b/arch/arm64/boot/dts/freescale/imx8dxp.dtsi
new file mode 100644
index 000000000000..a8f7352332c0
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8dxp.dtsi
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ */
+
+/dts-v1/;
+
+#include "imx8qxp.dtsi"
+
+/delete-node/ &A35_2;
+/delete-node/ &A35_3;
+
+&thermal_zones {
+ cpu0-thermal {
+ cooling-maps {
+ map0 {
+ cooling-device =
+ <&A35_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A35_1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
index b53104ed8919..bd5b365867fd 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
@@ -151,6 +151,28 @@
clocks = <&clk IMX8MM_CLK_SAI3_ROOT>;
};
};
+
+ sound-micfil {
+ compatible = "fsl,imx-audio-card";
+ model = "micfil-audio";
+
+ pri-dai-link {
+ link-name = "micfil hifi";
+ format = "i2s";
+
+ cpu {
+ sound-dai = <&micfil>;
+ };
+ };
+ };
+
+ sound-spdif {
+ compatible = "fsl,imx-audio-spdif";
+ model = "imx-spdif";
+ spdif-controller = <&spdif1>;
+ spdif-out;
+ spdif-in;
+ };
};
&A53_0 {
@@ -434,6 +456,16 @@
status = "okay";
};
+&micfil {
+ #sound-dai-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pdm>;
+ assigned-clocks = <&clk IMX8MM_CLK_PDM>;
+ assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <196608000>;
+ status = "okay";
+};
+
&mipi_csi {
status = "okay";
@@ -509,6 +541,24 @@
status = "okay";
};
+&spdif1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spdif1>;
+ assigned-clocks = <&clk IMX8MM_CLK_SPDIF1>;
+ assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <24576000>;
+ clocks = <&clk IMX8MM_CLK_AUDIO_AHB>, <&clk IMX8MM_CLK_24M>,
+ <&clk IMX8MM_CLK_SPDIF1>, <&clk IMX8MM_CLK_DUMMY>,
+ <&clk IMX8MM_CLK_DUMMY>, <&clk IMX8MM_CLK_DUMMY>,
+ <&clk IMX8MM_CLK_AUDIO_AHB>, <&clk IMX8MM_CLK_DUMMY>,
+ <&clk IMX8MM_CLK_DUMMY>, <&clk IMX8MM_CLK_DUMMY>,
+ <&clk IMX8MM_AUDIO_PLL1_OUT>, <&clk IMX8MM_AUDIO_PLL2_OUT>;
+ clock-names = "core", "rxtx0", "rxtx1", "rxtx2", "rxtx3",
+ "rxtx4", "rxtx5", "rxtx6", "rxtx7", "spba",
+ "pll8k", "pll11k";
+ status = "okay";
+};
+
&uart2 { /* console */
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart2>;
@@ -636,6 +686,18 @@
>;
};
+ pinctrl_pdm: pdmgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI5_MCLK_SAI5_MCLK 0xd6
+ MX8MM_IOMUXC_SAI5_RXC_PDM_CLK 0xd6
+ MX8MM_IOMUXC_SAI5_RXFS_SAI5_RX_SYNC 0xd6
+ MX8MM_IOMUXC_SAI5_RXD0_PDM_DATA0 0xd6
+ MX8MM_IOMUXC_SAI5_RXD1_PDM_DATA1 0xd6
+ MX8MM_IOMUXC_SAI5_RXD2_PDM_DATA2 0xd6
+ MX8MM_IOMUXC_SAI5_RXD3_PDM_DATA3 0xd6
+ >;
+ };
+
pinctrl_pmic: pmicirqgrp {
fsl,pins = <
MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x141
@@ -666,6 +728,13 @@
>;
};
+ pinctrl_spdif1: spdif1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SPDIF_TX_SPDIF1_OUT 0xd6
+ MX8MM_IOMUXC_SPDIF_RX_SPDIF1_IN 0xd6
+ >;
+ };
+
pinctrl_typec1: typec1grp {
fsl,pins = <
MX8MM_IOMUXC_SD1_STROBE_GPIO2_IO11 0x159
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts b/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts
index 8b16bd68576c..33f8d7d1970e 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts
@@ -25,23 +25,21 @@
leds {
compatible = "gpio-leds";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_gpio_led>;
led1 {
label = "led1";
- gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
linux,default-trigger = "heartbeat";
};
led2 {
label = "led2";
- gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio3 8 GPIO_ACTIVE_LOW>;
};
led3 {
label = "led3";
- gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+ gpios = <&gpio3 7 GPIO_ACTIVE_LOW>;
};
};
@@ -52,24 +50,12 @@
reg_rst_eth2: regulator-rst-eth2 {
compatible = "regulator-fixed";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usb_eth2>;
- gpio = <&gpio3 2 GPIO_ACTIVE_HIGH>;
+ gpio = <&gpio1 1 GPIO_ACTIVE_HIGH>;
enable-active-high;
regulator-always-on;
regulator-name = "rst-usb-eth2";
};
- reg_usb1_vbus: regulator-usb1-vbus {
- compatible = "regulator-fixed";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_reg_usb1_vbus>;
- gpio = <&gpio3 25 GPIO_ACTIVE_LOW>;
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- regulator-name = "usb1-vbus";
- };
-
reg_vdd_5v: regulator-5v {
compatible = "regulator-fixed";
regulator-always-on;
@@ -80,9 +66,6 @@
};
&ecspi2 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_ecspi2>;
- cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>;
status = "okay";
can@0 {
@@ -91,7 +74,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_can>;
clocks = <&osc_can>;
- interrupts-extended = <&gpio4 28 IRQ_TYPE_LEVEL_LOW>;
+ interrupts-extended = <&gpio5 1 IRQ_TYPE_LEVEL_LOW>;
/*
* Limit the SPI clock to 15 MHz to prevent issues
* with corrupted data due to chip errata.
@@ -103,9 +86,6 @@
};
&ecspi3 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_ecspi3>;
- cs-gpios = <&gpio5 25 GPIO_ACTIVE_LOW>;
status = "okay";
eeram@0 {
@@ -117,8 +97,8 @@
&fec1 {
pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_enet>;
- phy-connection-type = "rgmii-rxid";
+ pinctrl-0 = <&pinctrl_enet_rgmii>;
+ phy-connection-type = "rgmii-id";
phy-handle = <&ethphy>;
status = "okay";
@@ -127,55 +107,101 @@
#size-cells = <0>;
ethphy: ethernet-phy@0 {
+ compatible = "ethernet-phy-id4f51.e91b";
reg = <0>;
- reset-assert-us = <1>;
- reset-deassert-us = <15000>;
- reset-gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <10000>;
+ reset-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
};
};
};
+/*
+ * Rename SoM signals according to board usage:
+ * GPIO_B_0 -> DIO1_OUT
+ * GPIO_B_1 -> DIO2_OUT
+ */
&gpio1 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_gpio1>;
- gpio-line-names = "", "", "", "dio1-out", "", "", "dio1-in", "dio2-out",
- "dio2-in", "dio3-out", "dio3-in", "dio4-out", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "";
+ gpio-line-names = "", "GPIO_A_0", "", "GPIO_A_1",
+ "", "GPIO_A_2", "GPIO_A_3", "GPIO_A_4",
+ "GPIO_A_5", "GPIO_A_6", "GPIO_A_7", "DIO1_OUT",
+ "DIO2_OUT", "USB_A_OC#", "CAM_MCK", "USB_B_OC#",
+ "ETH_MDC", "ETH_MDIO", "ETH_A_(S)(R)(G)MII_TXD3",
+ "ETH_A_(S)(R)(G)MII_TXD2", "ETH_A_(S)(R)(G)MII_TXD1",
+ "ETH_A_(S)(R)(G)MII_TXD0", "ETH_A_(R)(G)MII_TX_EN(_ER)",
+ "ETH_A_(R)(G)MII_TX_CLK", "ETH_A_(R)(G)MII_RX_DV(_ER)",
+ "ETH_A_(R)(G)MII_RX_CLK", "ETH_A_(S)(R)(G)MII_RXD0",
+ "ETH_A_(S)(R)(G)MII_RXD1", "ETH_A_(R)(G)MII_RXD2",
+ "ETH_A_(R)(G)MII_RXD3";
};
-&gpio5 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_gpio5>;
- gpio-line-names = "", "", "dio4-in", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "";
+/*
+ * Rename SoM signals according to board usage:
+ * GPIO_B_2 -> DIO3_OUT
+ * GPIO_B_3 -> DIO4_OUT
+ */
+&gpio3 {
+ gpio-line-names = "GPIO_C_5", "GPIO_C_4", "SDIO_B_CD#", "SDIO_B_D5",
+ "SDIO_B_D6", "SDIO_B_D7", "GPIO_C_0", "GPIO_C_1",
+ "GPIO_C_2", "GPIO_C_3", "SDIO_B_D0", "SDIO_B_D1",
+ "SDIO_B_D2", "SDIO_B_D3", "", "SDIO_B_D4",
+ "CARRIER_PWR_EN", "SDIO_B_CLK", "SDIO_B_CMD", "DIO3_OUT",
+ "USB_B_EN", "DIO4_OUT", "PCIe_CLKREQ#", "PCIe_A_PERST#",
+ "PCIe_WAKE#", "USB_A_EN";
};
-&i2c4 {
- clock-frequency = <100000>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c4>;
+/*
+ * Rename SoM signals according to board usage:
+ * GPIO_B_4 -> DIO1_IN
+ * GPIO_B_5 -> DIO2_IN
+ * GPIO_B_6 -> DIO3_IN
+ * GPIO_B_7 -> DIO4_IN
+ */
+&gpio4 {
+ gpio-line-names = "GPIO_C_7", "", "I2S_A_DATA_IN", "I2S_B_DATA_IN",
+ "DIO1_IN", "BOOT_SEL0#", "BOOT_SEL1#", "",
+ "", "", "I2S_LRCLK", "I2S_BITCLK",
+ "I2S_A_DATA_OUT", "I2S_B_DATA_OUT", "DIO2_IN", "DIO3_IN",
+ "DIO4_IN", "SPI_A_/WP_(IO2)", "SPI_A_/HOLD_(IO3)", "GPIO_C_6",
+ "I2S_MCLK", "UART_A_TX", "UART_A_RX", "UART_A_CTS",
+ "UART_A_RTS", "", "", "",
+ "PCIe_SM_ALERT", "UART_B_RTS", "UART_B_CTS", "UART_B_RX";
+};
+
+&i2c3 {
status = "okay";
+
+ usb-hub@2c {
+ compatible = "microchip,usb2514b";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb_hub>;
+ reg = <0x2c>;
+ non-removable-ports = <0>, <3>;
+ reset-gpios = <&gpio5 2 GPIO_ACTIVE_LOW>;
+ };
};
&pwm2 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_pwm2>;
status = "okay";
};
+&reg_usb2_vbus {
+ status = "disabled";
+};
+
+&reg_usdhc2_vcc {
+ status = "disabled";
+};
+
+&reg_usdhc3_vcc {
+ status = "disabled";
+};
+
&uart1 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart1>;
uart-has-rtscts;
status = "okay";
};
&uart2 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart2>;
linux,rs485-enabled-at-boot-time;
uart-has-rtscts;
status = "okay";
@@ -183,8 +209,6 @@
&usbotg1 {
dr_mode = "otg";
- disable-over-current;
- vbus-supply = <&reg_usb1_vbus>;
status = "okay";
};
@@ -195,14 +219,17 @@
#size-cells = <0>;
status = "okay";
+ /* VBUS is controlled by the hub */
+ /delete-property/ vbus-supply;
+
usb1@1 {
- compatible = "usb424,9514";
+ compatible = "usb424,2514";
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
usbnet: ethernet@1 {
- compatible = "usb424,ec00";
+ compatible = "usbb95,772b";
reg = <1>;
local-mac-address = [ 00 00 00 00 00 00 ];
};
@@ -210,167 +237,20 @@
};
&usdhc2 {
- pinctrl-names = "default", "state_100mhz", "state_200mhz";
- pinctrl-0 = <&pinctrl_usdhc2>;
- pinctrl-1 = <&pinctrl_usdhc2_100mhz>;
- pinctrl-2 = <&pinctrl_usdhc2_200mhz>;
vmmc-supply = <&reg_vdd_3v3>;
- vqmmc-supply = <&reg_nvcc_sd>;
- cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
status = "okay";
};
&iomuxc {
pinctrl_can: cangrp {
fsl,pins = <
- MX8MM_IOMUXC_SAI3_RXFS_GPIO4_IO28 0x19
- >;
- };
-
- pinctrl_ecspi2: ecspi2grp {
- fsl,pins = <
- MX8MM_IOMUXC_ECSPI2_MISO_ECSPI2_MISO 0x82
- MX8MM_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI 0x82
- MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0x82
- MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13 0x19
- >;
- };
-
- pinctrl_ecspi3: ecspi3grp {
- fsl,pins = <
- MX8MM_IOMUXC_UART2_RXD_ECSPI3_MISO 0x82
- MX8MM_IOMUXC_UART1_TXD_ECSPI3_MOSI 0x82
- MX8MM_IOMUXC_UART1_RXD_ECSPI3_SCLK 0x82
- MX8MM_IOMUXC_UART2_TXD_GPIO5_IO25 0x19
- >;
- };
-
- pinctrl_enet: enetgrp {
- fsl,pins = <
- MX8MM_IOMUXC_ENET_MDC_ENET1_MDC 0x3
- MX8MM_IOMUXC_ENET_MDIO_ENET1_MDIO 0x3
- MX8MM_IOMUXC_ENET_TD3_ENET1_RGMII_TD3 0x1f
- MX8MM_IOMUXC_ENET_TD2_ENET1_RGMII_TD2 0x1f
- MX8MM_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x1f
- MX8MM_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x1f
- MX8MM_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 0x91
- MX8MM_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x91
- MX8MM_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x91
- MX8MM_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x91
- MX8MM_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x1f
- MX8MM_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91
- MX8MM_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91
- MX8MM_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f
- MX8MM_IOMUXC_GPIO1_IO01_GPIO1_IO1 0x19 /* PHY RST */
- MX8MM_IOMUXC_GPIO1_IO05_GPIO1_IO5 0x19 /* ETH IRQ */
- >;
- };
-
- pinctrl_gpio_led: gpioledgrp {
- fsl,pins = <
- MX8MM_IOMUXC_GPIO1_IO12_GPIO1_IO12 0x19
- MX8MM_IOMUXC_GPIO1_IO13_GPIO1_IO13 0x19
- MX8MM_IOMUXC_GPIO1_IO14_GPIO1_IO14 0x19
- >;
- };
-
- pinctrl_gpio1: gpio1grp {
- fsl,pins = <
- MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x19
- MX8MM_IOMUXC_GPIO1_IO07_GPIO1_IO7 0x19
- MX8MM_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x19
- MX8MM_IOMUXC_GPIO1_IO11_GPIO1_IO11 0x19
- MX8MM_IOMUXC_GPIO1_IO06_GPIO1_IO6 0x19
- MX8MM_IOMUXC_GPIO1_IO08_GPIO1_IO8 0x19
- MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10 0x19
- >;
- };
-
- pinctrl_gpio5: gpio5grp {
- fsl,pins = <
- MX8MM_IOMUXC_SAI3_MCLK_GPIO5_IO2 0x19
- >;
- };
-
- pinctrl_i2c4: i2c4grp {
- fsl,pins = <
- MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL 0x400001c3
- MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA 0x400001c3
- >;
- };
-
- pinctrl_pwm2: pwm2grp {
- fsl,pins = <
- MX8MM_IOMUXC_SPDIF_RX_PWM2_OUT 0x19
- >;
- };
-
- pinctrl_reg_usb1_vbus: regusb1vbusgrp {
- fsl,pins = <
- MX8MM_IOMUXC_SAI5_MCLK_GPIO3_IO25 0x19
- >;
- };
-
- pinctrl_uart1: uart1grp {
- fsl,pins = <
- MX8MM_IOMUXC_SAI2_RXC_UART1_DCE_RX 0x140
- MX8MM_IOMUXC_SAI2_RXFS_UART1_DCE_TX 0x140
- MX8MM_IOMUXC_SAI2_RXD0_UART1_DCE_RTS_B 0x140
- MX8MM_IOMUXC_SAI2_TXFS_UART1_DCE_CTS_B 0x140
- >;
- };
-
- pinctrl_uart2: uart2grp {
- fsl,pins = <
- MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX 0x140
- MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX 0x140
- MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B 0x140
- MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B 0x140
- >;
- };
-
- pinctrl_usb_eth2: usbeth2grp {
- fsl,pins = <
- MX8MM_IOMUXC_NAND_CE1_B_GPIO3_IO2 0x19
- >;
- };
-
- pinctrl_usdhc2: usdhc2grp {
- fsl,pins = <
- MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x190
- MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d0
- MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d0
- MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d0
- MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d0
- MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d0
- MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x019
- MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
- >;
- };
-
- pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
- fsl,pins = <
- MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x194
- MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d4
- MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d4
- MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d4
- MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d4
- MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d4
- MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x019
- MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
+ MX8MM_IOMUXC_SAI3_TXD_GPIO5_IO1 0x19 /* SDIO_B_PWR_EN */
>;
};
- pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
+ pinctrl_usb_hub: usbhubgrp {
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_SD2_CD_B_GPIO2_IO12 0x019
- MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
+ MX8MM_IOMUXC_SAI3_MCLK_GPIO5_IO2 0x19 /* SDIO_B_WP */
>;
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts b/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts
index dcec57c20399..aab8e2421650 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts
@@ -279,8 +279,8 @@
pinctrl_i2c4: i2c4grp {
fsl,pins = <
- MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL 0x400001c3
- MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA 0x400001c3
+ MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL 0x40000083
+ MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA 0x40000083
>;
};
@@ -292,19 +292,19 @@
pinctrl_uart1: uart1grp {
fsl,pins = <
- MX8MM_IOMUXC_SAI2_RXC_UART1_DCE_RX 0x140
- MX8MM_IOMUXC_SAI2_RXFS_UART1_DCE_TX 0x140
- MX8MM_IOMUXC_SAI2_RXD0_UART1_DCE_RTS_B 0x140
- MX8MM_IOMUXC_SAI2_TXFS_UART1_DCE_CTS_B 0x140
+ MX8MM_IOMUXC_SAI2_RXC_UART1_DCE_RX 0x0
+ MX8MM_IOMUXC_SAI2_RXFS_UART1_DCE_TX 0x0
+ MX8MM_IOMUXC_SAI2_RXD0_UART1_DCE_RTS_B 0x0
+ MX8MM_IOMUXC_SAI2_TXFS_UART1_DCE_CTS_B 0x0
>;
};
pinctrl_uart2: uart2grp {
fsl,pins = <
- MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX 0x140
- MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX 0x140
- MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B 0x140
- MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B 0x140
+ MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX 0x0
+ MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX 0x0
+ MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B 0x0
+ MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B 0x0
>;
};
@@ -316,40 +316,40 @@
pinctrl_usdhc2: usdhc2grp {
fsl,pins = <
- MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x190
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x90
MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d0
MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d0
MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d0
MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d0
MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d0
- MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x019
- MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
+ MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x19
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xd0
>;
};
pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
fsl,pins = <
- MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x194
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x94
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_SD2_CD_B_GPIO2_IO12 0x019
- MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
+ MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x19
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xd0
>;
};
pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
fsl,pins = <
- MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x196
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x96
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_SD2_CD_B_GPIO2_IO12 0x019
- MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x1d0
+ MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x19
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xd0
>;
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi
index 6e75ab879bf5..663ae52b4852 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi
@@ -3,6 +3,7 @@
* Copyright (C) 2022 Kontron Electronics GmbH
*/
+#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include "imx8mm.dtsi"
@@ -28,6 +29,73 @@
chosen {
stdout-path = &uart3;
};
+
+ reg_vdd_carrier: regulator-vdd-carrier {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_vdd_carrier>;
+ gpio = <&gpio3 16 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "VDD_CARRIER";
+
+ regulator-state-standby {
+ regulator-on-in-suspend;
+ };
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+
+ regulator-state-disk {
+ regulator-off-in-suspend;
+ };
+ };
+
+ reg_usb1_vbus: regulator-usb1-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_usb1_vbus>;
+ enable-active-high;
+ gpio = <&gpio3 25 GPIO_ACTIVE_HIGH>;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-name = "VBUS_USB1";
+ };
+
+ reg_usb2_vbus: regulator-usb2-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_usb2_vbus>;
+ enable-active-high;
+ gpio = <&gpio3 20 GPIO_ACTIVE_HIGH>;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-name = "VBUS_USB2";
+ };
+
+ reg_usdhc2_vcc: regulator-usdhc2-vcc {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_usdhc2_vcc>;
+ enable-active-high;
+ gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "VCC_SDIO_A";
+ };
+
+ reg_usdhc3_vcc: regulator-usdhc3-vcc {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_usdhc3_vcc>;
+ enable-active-high;
+ gpio = <&gpio5 1 GPIO_ACTIVE_HIGH>;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "VCC_SDIO_B";
+ };
};
&A53_0 {
@@ -96,6 +164,79 @@
};
};
+&ecspi2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi2>, <&pinctrl_ecspi2_gpio>;
+ cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>;
+};
+
+&ecspi3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi3>;
+ cs-gpios = <&gpio5 25 GPIO_ACTIVE_LOW>;
+};
+
+&gpio1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio1>;
+ gpio-line-names = "", "GPIO_A_0", "", "GPIO_A_1",
+ "", "GPIO_A_2", "GPIO_A_3", "GPIO_A_4",
+ "GPIO_A_5", "GPIO_A_6", "GPIO_A_7", "GPIO_B_0",
+ "GPIO_B_1", "USB_A_OC#", "CAM_MCK", "USB_B_OC#",
+ "ETH_MDC", "ETH_MDIO", "ETH_A_(S)(R)(G)MII_TXD3",
+ "ETH_A_(S)(R)(G)MII_TXD2", "ETH_A_(S)(R)(G)MII_TXD1",
+ "ETH_A_(S)(R)(G)MII_TXD0", "ETH_A_(R)(G)MII_TX_EN(_ER)",
+ "ETH_A_(R)(G)MII_TX_CLK", "ETH_A_(R)(G)MII_RX_DV(_ER)",
+ "ETH_A_(R)(G)MII_RX_CLK", "ETH_A_(S)(R)(G)MII_RXD0",
+ "ETH_A_(S)(R)(G)MII_RXD1", "ETH_A_(R)(G)MII_RXD2",
+ "ETH_A_(R)(G)MII_RXD3";
+};
+
+&gpio2 {
+ gpio-line-names = "", "", "", "",
+ "", "", "", "",
+ "", "", "", "",
+ "SDIO_A_CD#", "SDIO_A_CLK", "SDIO_A_CMD", "SDIO_A_D0",
+ "SDIO_A_D1", "SDIO_A_D2", "SDIO_A_D3", "SDIO_A_PWR_EN",
+ "SDIO_A_WP";
+};
+
+&gpio3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio3>;
+ gpio-line-names = "GPIO_C_5", "GPIO_C_4", "SDIO_B_CD#", "SDIO_B_D5",
+ "SDIO_B_D6", "SDIO_B_D7", "GPIO_C_0", "GPIO_C_1",
+ "GPIO_C_2", "GPIO_C_3", "SDIO_B_D0", "SDIO_B_D1",
+ "SDIO_B_D2", "SDIO_B_D3", "", "SDIO_B_D4",
+ "CARRIER_PWR_EN", "SDIO_B_CLK", "SDIO_B_CMD", "GPIO_B_2",
+ "USB_B_EN", "GPIO_B_3", "PCIe_CLKREQ#", "PCIe_A_PERST#",
+ "PCIe_WAKE#", "USB_A_EN";
+};
+
+&gpio4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio4>;
+ gpio-line-names = "GPIO_C_7", "", "I2S_A_DATA_IN", "I2S_B_DATA_IN",
+ "GPIO_B_4", "BOOT_SEL0#", "BOOT_SEL1#", "",
+ "", "", "I2S_LRCLK", "I2S_BITCLK",
+ "I2S_A_DATA_OUT", "I2S_B_DATA_OUT", "GPIO_B_5", "GPIO_B_6",
+ "GPIO_B_7", "SPI_A_/WP_(IO2)", "SPI_A_/HOLD_(IO3)", "GPIO_C_6",
+ "I2S_MCLK", "UART_A_TX", "UART_A_RX", "UART_A_CTS",
+ "UART_A_RTS", "", "", "",
+ "PCIe_SM_ALERT", "UART_B_RTS", "UART_B_CTS", "UART_B_RX";
+};
+
+&gpio5 {
+ gpio-line-names = "UART_B_TX", "SDIO_B_PWR_EN", "SDIO_B_WP", "PWM_2",
+ "PWM_1", "PWM_0", "", "",
+ "", "", "SPI_A_SCK", "SPI_A_SDO_(IO1)",
+ "SPI_A_SCK", "SPI_A_CS0#", "", "",
+ "I2C_A_SCL", "I2C_A_SDA", "I2C_B_SCL", "I2C_B_SDA",
+ "PCIe_SMCLK", "PCIe_SMDAT", "SPI_B_SCK", "SPI_B_SDO",
+ "SPI_B_SDI", "SPI_B_CS0#", "UART_CON_RX", "UART_CON_TX",
+ "UART_C_RX", "UART_C_TX";
+};
+
&i2c1 {
clock-frequency = <400000>;
pinctrl-names = "default";
@@ -205,22 +346,86 @@
};
};
+ eeprom: eeprom@50 {
+ compatible = "atmel,24c64";
+ reg = <0x50>;
+ address-width = <16>;
+ pagesize = <32>;
+ size = <8192>;
+ };
+
rv3028: rtc@52 {
compatible = "microcrystal,rv3028";
reg = <0x52>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_rtc>;
- interrupts-extended = <&gpio4 1 IRQ_TYPE_LEVEL_HIGH>;
- trickle-diode-disable;
+ interrupts-extended = <&gpio4 1 IRQ_TYPE_LEVEL_LOW>;
};
};
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2>;
+};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c3>;
+};
+
+&i2c4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c4>;
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm1>;
+};
+
+&pwm2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm2>;
+};
+
+&pwm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm3>;
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2>;
+};
+
&uart3 { /* console */
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart3>;
status = "okay";
};
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart4>;
+};
+
+&usbotg1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb1>;
+ vbus-supply = <&reg_usb1_vbus>;
+};
+
+&usbotg2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb2>;
+ vbus-supply = <&reg_usb2_vbus>;
+};
+
&usdhc1 {
pinctrl-names = "default", "state_100mhz", "state_200mhz";
pinctrl-0 = <&pinctrl_usdhc1>;
@@ -233,6 +438,26 @@
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>;
+ vmmc-supply = <&reg_usdhc2_vcc>;
+ vqmmc-supply = <&reg_nvcc_sd>;
+ cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+};
+
+&usdhc3 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc3>, <&pinctrl_usdhc3_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc3_100mhz>, <&pinctrl_usdhc3_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc3_200mhz>, <&pinctrl_usdhc3_gpio>;
+ vmmc-supply = <&reg_usdhc3_vcc>;
+ vqmmc-supply = <&reg_nvcc_sd>;
+ cd-gpios = <&gpio3 2 GPIO_ACTIVE_LOW>;
+};
+
&wdog1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_wdog>;
@@ -241,6 +466,12 @@
};
&iomuxc {
+ pinctrl_csi_mck: csimckgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO14_CCMSRCGPCMIX_CLKO1 0x59 /* CAM_MCK */
+ >;
+ };
+
pinctrl_ecspi1: ecspi1grp {
fsl,pins = <
MX8MM_IOMUXC_ECSPI1_MISO_ECSPI1_MISO 0x82
@@ -250,10 +481,140 @@
>;
};
+ pinctrl_ecspi2: ecspi2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_ECSPI2_MISO_ECSPI2_MISO 0x82 /* SPI_A_SDI_(IO0) */
+ MX8MM_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI 0x82 /* SPI_A_SDO_(IO1) */
+ MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0x82 /* SPI_A_SCK */
+ MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13 0x19 /* SPI_A_CS0# */
+ >;
+ };
+
+ pinctrl_ecspi2_gpio: ecspi2gpiogrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI1_TXD5_GPIO4_IO17 0x19 /* SPI_A_/WP_(IO2) */
+ MX8MM_IOMUXC_SAI1_TXD6_GPIO4_IO18 0x19 /* SPI_A_/HOLD_(IO3) */
+ >;
+ };
+
+ pinctrl_ecspi3: ecspi3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART2_RXD_ECSPI3_MISO 0x82 /* SPI_B_SDI */
+ MX8MM_IOMUXC_UART1_TXD_ECSPI3_MOSI 0x82 /* SPI_B_SDO */
+ MX8MM_IOMUXC_UART1_RXD_ECSPI3_SCLK 0x82 /* SPI_B_SCK */
+ MX8MM_IOMUXC_UART2_TXD_GPIO5_IO25 0x19 /* SPI_B_CS0# */
+ >;
+ };
+
+ pinctrl_enet_rgmii: enetrgmiigrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_ENET_MDC_ENET1_MDC 0x03 /* ETH_MDC */
+ MX8MM_IOMUXC_ENET_MDIO_ENET1_MDIO 0x03 /* ETH_MDIO */
+ MX8MM_IOMUXC_ENET_TD3_ENET1_RGMII_TD3 0x1f /* ETH_A_(S)(R)(G)MII_TXD3 */
+ MX8MM_IOMUXC_ENET_TD2_ENET1_RGMII_TD2 0x1f /* ETH_A_(S)(R)(G)MII_TXD2 */
+ MX8MM_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x1f /* ETH_A_(S)(R)(G)MII_TXD1 */
+ MX8MM_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x1f /* ETH_A_(S)(R)(G)MII_TXD0 */
+ MX8MM_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 0x91 /* ETH_A_(R)(G)MII_RXD3 */
+ MX8MM_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x91 /* ETH_A_(R)(G)MII_RXD2 */
+ MX8MM_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x91 /* ETH_A_(S)(R)(G)MII_RXD1 */
+ MX8MM_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x91 /* ETH_A_(S)(R)(G)MII_RXD0 */
+ MX8MM_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x1f /* ETH_A_(R)(G)MII_TX_CLK */
+ MX8MM_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91 /* ETH_A_(R)(G)MII_RX_CLK */
+ MX8MM_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91 /* ETH_A_(R)(G)MII_RX_DV(_ER) */
+ MX8MM_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f /* ETH_A_(R)(G)MII_TX_EN(_ER) */
+ >;
+ };
+
+ pinctrl_enet_rmii: enetrmiigrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_ENET_MDC_ENET1_MDC 0x03 /* ETH_MDC */
+ MX8MM_IOMUXC_ENET_MDIO_ENET1_MDIO 0x03 /* ETH_MDIO */
+ MX8MM_IOMUXC_ENET_TD2_ENET1_TX_CLK 0x4000001f /* ETH_A_(S)(R)(G)MII_TXD2 */
+ MX8MM_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x56 /* ETH_A_(S)(R)(G)MII_TXD1 */
+ MX8MM_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x56 /* ETH_A_(S)(R)(G)MII_TXD0 */
+ MX8MM_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x56 /* ETH_A_(S)(R)(G)MII_RXD1 */
+ MX8MM_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x56 /* ETH_A_(S)(R)(G)MII_RXD0 */
+ MX8MM_IOMUXC_ENET_RXC_ENET1_RX_ER 0x56 /* ETH_A_(R)(G)MII_RX_CLK */
+ MX8MM_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x56 /* ETH_A_(R)(G)MII_RX_DV(_ER) */
+ MX8MM_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x56 /* ETH_A_(R)(G)MII_TX_EN(_ER) */
+ >;
+ };
+
+ pinctrl_gpio1: gpio1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO01_GPIO1_IO1 0x19 /* GPIO_A_0 */
+ MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x19 /* GPIO_A_1 */
+ MX8MM_IOMUXC_GPIO1_IO05_GPIO1_IO5 0x19 /* GPIO_A_2 */
+ MX8MM_IOMUXC_GPIO1_IO06_GPIO1_IO6 0x19 /* GPIO_A_3 */
+ MX8MM_IOMUXC_GPIO1_IO07_GPIO1_IO7 0x19 /* GPIO_A_4 */
+ MX8MM_IOMUXC_GPIO1_IO08_GPIO1_IO8 0x19 /* GPIO_A_5 */
+ MX8MM_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x19 /* GPIO_A_6 */
+ MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10 0x19 /* GPIO_A_7 */
+ MX8MM_IOMUXC_GPIO1_IO11_GPIO1_IO11 0x19 /* GPIO_B_0 */
+ MX8MM_IOMUXC_GPIO1_IO12_GPIO1_IO12 0x19 /* GPIO_B_1 */
+ >;
+ };
+
+ pinctrl_gpio3: gpio3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_ALE_GPIO3_IO0 0x19 /* GPIO_C_5 */
+ MX8MM_IOMUXC_NAND_CE0_B_GPIO3_IO1 0x19 /* GPIO_C_4 */
+ MX8MM_IOMUXC_NAND_DATA00_GPIO3_IO6 0x19 /* GPIO_C_0 */
+ MX8MM_IOMUXC_NAND_DATA01_GPIO3_IO7 0x19 /* GPIO_C_1 */
+ MX8MM_IOMUXC_NAND_DATA02_GPIO3_IO8 0x19 /* GPIO_C_2 */
+ MX8MM_IOMUXC_NAND_DATA03_GPIO3_IO9 0x19 /* GPIO_C_3 */
+ MX8MM_IOMUXC_SAI5_RXFS_GPIO3_IO19 0x19 /* GPIO_B_2 */
+ MX8MM_IOMUXC_SAI5_RXD0_GPIO3_IO21 0x19 /* GPIO_B_3 */
+ >;
+ };
+
+ pinctrl_gpio4: gpio4grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI1_RXFS_GPIO4_IO0 0x19 /* GPIO_C_7 */
+ MX8MM_IOMUXC_SAI1_RXD2_GPIO4_IO4 0x19 /* GPIO_B_4 */
+ MX8MM_IOMUXC_SAI1_RXD3_GPIO4_IO5 0x19 /* BOOT_SEL0# */
+ MX8MM_IOMUXC_SAI1_RXD4_GPIO4_IO6 0x19 /* BOOT_SEL1# */
+ MX8MM_IOMUXC_SAI1_TXD2_GPIO4_IO14 0x19 /* GPIO_B_5 */
+ MX8MM_IOMUXC_SAI1_TXD3_GPIO4_IO15 0x19 /* GPIO_B_6 */
+ MX8MM_IOMUXC_SAI1_TXD4_GPIO4_IO16 0x19 /* GPIO_B_7 */
+ MX8MM_IOMUXC_SAI1_TXD7_GPIO4_IO19 0x19 /* GPIO_C_6 */
+ >;
+ };
+
pinctrl_i2c1: i2c1grp {
fsl,pins = <
- MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x400001c3
- MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x400001c3
+ MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x40000083
+ MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x40000083
+ >;
+ };
+
+ pinctrl_i2c2: i2c2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C2_SCL_I2C2_SCL 0x40000083 /* I2C_A_SCL */
+ MX8MM_IOMUXC_I2C2_SDA_I2C2_SDA 0x40000083 /* I2C_A_SDA */
+ >;
+ };
+
+ pinctrl_i2c3: i2c3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C3_SCL_I2C3_SCL 0x40000083 /* I2C_B_SCL */
+ MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA 0x40000083 /* I2C_B_SDA */
+ >;
+ };
+
+ pinctrl_i2c4: i2c4grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL 0x40000083 /* PCIe_SMCLK and I2C_CAM_SCL/CSI_TX_P */
+ MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA 0x40000083 /* PCIe_SMDAT and I2C_CAM_SDA/CSI_TX_N */
+ >;
+ };
+
+ pinctrl_pcie: pciegrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI5_RXD1_GPIO3_IO22 0x19 /* PCIe_CLKREQ# */
+ MX8MM_IOMUXC_SAI5_RXD2_GPIO3_IO23 0x19 /* PCIe_A_PERST# */
+ MX8MM_IOMUXC_SAI5_RXD3_GPIO3_IO24 0x19 /* PCIe_WAKE# */
+ MX8MM_IOMUXC_SAI3_RXFS_GPIO4_IO28 0x19 /* PCIe_SM_ALERT */
>;
};
@@ -263,16 +624,113 @@
>;
};
+ pinctrl_pwm1: pwm1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SPDIF_EXT_CLK_PWM1_OUT 0x19 /* PWM_0 */
+ >;
+ };
+
+ pinctrl_pwm2: pwm2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SPDIF_RX_PWM2_OUT 0x19 /* PWM_1 */
+ >;
+ };
+
+ pinctrl_pwm3: pwm3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SPDIF_TX_PWM3_OUT 0x19 /* PWM_2 */
+ >;
+ };
+
+ pinctrl_reg_usb1_vbus: regusb1vbusgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI5_MCLK_GPIO3_IO25 0x19 /* USB_A_EN */
+ >;
+ };
+
+ pinctrl_reg_usb2_vbus: regusb2vbusgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI5_RXC_GPIO3_IO20 0x19 /* USB_B_EN */
+ >;
+ };
+
+ pinctrl_reg_usdhc2_vcc: regusdhc2vccgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x19 /* SDIO_A_PWR_EN */
+ >;
+ };
+
+ pinctrl_reg_usdhc3_vcc: regusdhc3vccgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI3_TXD_GPIO5_IO1 0x19 /* SDIO_B_PWR_EN */
+ >;
+ };
+
+ pinctrl_reg_vdd_carrier: regvddcarriergrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_READY_B_GPIO3_IO16 0x19 /* CARRIER_PWR_EN */
+ >;
+ };
+
pinctrl_rtc: rtcgrp {
fsl,pins = <
MX8MM_IOMUXC_SAI1_RXC_GPIO4_IO1 0x19
>;
};
+ pinctrl_sai1: sai1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI1_RXD0_SAI1_RX_DATA0 0xd6 /* I2S_A_DATA_IN */
+ MX8MM_IOMUXC_SAI1_TXD0_SAI1_TX_DATA0 0xd6 /* I2S_A_DATA_OUT */
+ MX8MM_IOMUXC_SAI1_RXD1_SAI1_RX_DATA1 0xd6 /* I2S_B_DATA_IN */
+ MX8MM_IOMUXC_SAI1_TXD1_SAI1_TX_DATA1 0xd6 /* I2S_B_DATA_OUT */
+ MX8MM_IOMUXC_SAI1_MCLK_SAI1_MCLK 0xd6 /* I2S_MCLK */
+ MX8MM_IOMUXC_SAI1_TXFS_SAI1_TX_SYNC 0xd6 /* I2S_LRCLK */
+ MX8MM_IOMUXC_SAI1_TXC_SAI1_TX_BCLK 0xd6 /* I2S_BITCLK */
+ >;
+ };
+
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI2_RXC_UART1_DCE_RX 0x0 /* UART_A_RX */
+ MX8MM_IOMUXC_SAI2_RXFS_UART1_DCE_TX 0x0 /* UART_A_TX */
+ MX8MM_IOMUXC_SAI2_RXD0_UART1_DCE_RTS_B 0x0 /* UART_A_CTS */
+ MX8MM_IOMUXC_SAI2_TXFS_UART1_DCE_CTS_B 0x0 /* UART_A_RTS */
+ >;
+ };
+
+ pinctrl_uart2: uart2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX 0x0 /* UART_B_RX */
+ MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX 0x0 /* UART_B_TX */
+ MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B 0x0 /* UART_B_CTS */
+ MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B 0x0 /* UART_B_RTS */
+ >;
+ };
+
pinctrl_uart3: uart3grp {
fsl,pins = <
- MX8MM_IOMUXC_UART3_RXD_UART3_DCE_RX 0x140
- MX8MM_IOMUXC_UART3_TXD_UART3_DCE_TX 0x140
+ MX8MM_IOMUXC_UART3_RXD_UART3_DCE_RX 0x140 /* UART_CON_RX */
+ MX8MM_IOMUXC_UART3_TXD_UART3_DCE_TX 0x140 /* UART_CON_TX */
+ >;
+ };
+
+ pinctrl_uart4: uart4grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_UART4_RXD_UART4_DCE_RX 0x0 /* UART_C_RX */
+ MX8MM_IOMUXC_UART4_TXD_UART4_DCE_TX 0x0 /* UART_C_TX */
+ >;
+ };
+
+ pinctrl_usb1: usb1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO13_USB1_OTG_OC 0x19 /* USB_A_OC# */
+ >;
+ };
+
+ pinctrl_usb2: usb2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO15_USB2_OTG_OC 0x19 /* USB_B_OC# */
>;
};
@@ -327,6 +785,103 @@
>;
};
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x90 /* SDIO_A_CLK */
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d0 /* SDIO_A_CMD */
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d0 /* SDIO_A_D0 */
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d0 /* SDIO_A_D1 */
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d0 /* SDIO_A_D2 */
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d0 /* SDIO_A_D3 */
+ MX8MM_IOMUXC_SD2_WP_USDHC2_WP 0x400000d6 /* SDIO_A_WP */
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x90
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x94 /* SDIO_A_CLK */
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d4 /* SDIO_A_CMD */
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d4 /* SDIO_A_D0 */
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d4 /* SDIO_A_D1 */
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d4 /* SDIO_A_D2 */
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d4 /* SDIO_A_D3 */
+ MX8MM_IOMUXC_SD2_WP_USDHC2_WP 0x400000d6 /* SDIO_A_WP */
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x90
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x96 /* SDIO_A_CLK */
+ MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD 0x1d6 /* SDIO_A_CMD */
+ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d6 /* SDIO_A_D0 */
+ MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d6 /* SDIO_A_D1 */
+ MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d6 /* SDIO_A_D2 */
+ MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d6 /* SDIO_A_D3 */
+ MX8MM_IOMUXC_SD2_WP_USDHC2_WP 0x400000d6 /* SDIO_A_WP */
+ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0x90
+ >;
+ };
+
+ pinctrl_usdhc2_gpio: usdhc2gpiogrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x19 /* SDIO_A_CD# */
+ >;
+ };
+
+ pinctrl_usdhc3: usdhc3grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x90 /* SDIO_B_CLK */
+ MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x90 /* SDIO_B_CMD */
+ MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x90 /* SDIO_B_D0 */
+ MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x90 /* SDIO_B_D1 */
+ MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x90 /* SDIO_B_D2 */
+ MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x90 /* SDIO_B_D3 */
+ MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x90 /* SDIO_B_D4 */
+ MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x90 /* SDIO_B_D5 */
+ MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x90 /* SDIO_B_D6 */
+ MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x90 /* SDIO_B_D7 */
+ >;
+ };
+
+ pinctrl_usdhc3_100mhz: usdhc3-100mhzgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x94 /* SDIO_B_CLK */
+ MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x94 /* SDIO_B_CMD */
+ MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x94 /* SDIO_B_D0 */
+ MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x94 /* SDIO_B_D1 */
+ MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x94 /* SDIO_B_D2 */
+ MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x94 /* SDIO_B_D3 */
+ MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x94 /* SDIO_B_D4 */
+ MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x94 /* SDIO_B_D5 */
+ MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x94 /* SDIO_B_D6 */
+ MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x94 /* SDIO_B_D7 */
+ >;
+ };
+
+ pinctrl_usdhc3_200mhz: usdhc3-200mhzgrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK 0x96 /* SDIO_B_CLK */
+ MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD 0x96 /* SDIO_B_CMD */
+ MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0 0x96 /* SDIO_B_D0 */
+ MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1 0x96 /* SDIO_B_D1 */
+ MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2 0x96 /* SDIO_B_D2 */
+ MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3 0x96 /* SDIO_B_D3 */
+ MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4 0x96 /* SDIO_B_D4 */
+ MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5 0x96 /* SDIO_B_D5 */
+ MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6 0x96 /* SDIO_B_D6 */
+ MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7 0x96 /* SDIO_B_D7 */
+ >;
+ };
+
+ pinctrl_usdhc3_gpio: usdhc3gpiogrp {
+ fsl,pins = <
+ MX8MM_IOMUXC_NAND_CE1_B_GPIO3_IO2 0x19 /* SDIO_B_CD# */
+ MX8MM_IOMUXC_SAI3_MCLK_GPIO5_IO2 0x19 /* SDIO_B_WP */
+ >;
+ };
+
pinctrl_wdog: wdoggrp {
fsl,pins = <
MX8MM_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-sl.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-kontron-sl.dtsi
index 1f8326613ee9..2076148e0862 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-sl.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-sl.dtsi
@@ -237,8 +237,8 @@
pinctrl_i2c1: i2c1grp {
fsl,pins = <
- MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x400001c3
- MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x400001c3
+ MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x40000083
+ MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x40000083
>;
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts b/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts
index ea6e8b85169f..01b632b220dc 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts
@@ -5,6 +5,8 @@
/dts-v1/;
+#include <dt-bindings/phy/phy-imx8-pcie.h>
+
#include "imx8mm-tqma8mqml.dtsi"
#include "mba8mx.dtsi"
@@ -74,19 +76,23 @@
};
&pcie_phy {
- clocks = <&pcie0_refclk>;
+ fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>;
+ fsl,clkreq-unsupported;
+ clocks = <&pcieclk 2>;
+ clock-names = "ref";
status = "okay";
};
+/* PCIe slot on X36 */
&pcie0 {
reset-gpio = <&expander0 14 GPIO_ACTIVE_LOW>;
- clocks = <&clk IMX8MM_CLK_PCIE1_ROOT>, <&pcie0_refclk>,
+ clocks = <&clk IMX8MM_CLK_PCIE1_ROOT>, <&pcieclk 3>,
<&clk IMX8MM_CLK_PCIE1_AUX>;
assigned-clocks = <&clk IMX8MM_CLK_PCIE1_AUX>,
- <&clk IMX8MM_CLK_PCIE1_CTRL>;
+ <&clk IMX8MM_CLK_PCIE1_CTRL>;
assigned-clock-rates = <10000000>, <250000000>;
assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_50M>,
- <&clk IMX8MM_SYS_PLL2_250M>;
+ <&clk IMX8MM_SYS_PLL2_250M>;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi
index 6425773f68e0..41c966147b94 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi
@@ -47,25 +47,20 @@
gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
status = "okay";
};
-
- reg_usb_otg1_vbus: regulator-usb-otg1 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_reg_usb1_en>;
- compatible = "regulator-fixed";
- regulator-name = "usb_otg1_vbus";
- gpio = <&gpio1 10 GPIO_ACTIVE_HIGH>;
- enable-active-high;
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- };
};
-/* off-board header */
&ecspi2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_spi2>;
- cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>;
+ cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>,
+ <&gpio1 10 GPIO_ACTIVE_LOW>;
status = "okay";
+
+ tpm@1 {
+ compatible = "tcg,tpm_tis-spi";
+ reg = <0x1>;
+ spi-max-frequency = <36000000>;
+ };
};
&gpio1 {
@@ -144,9 +139,10 @@
};
&usbotg1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg1>;
dr_mode = "otg";
over-current-active-low;
- vbus-supply = <&reg_usb_otg1_vbus>;
status = "okay";
};
@@ -204,20 +200,13 @@
>;
};
- pinctrl_reg_usb1_en: regusb1grp {
- fsl,pins = <
- MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10 0x41
- MX8MM_IOMUXC_GPIO1_IO12_GPIO1_IO12 0x141
- MX8MM_IOMUXC_GPIO1_IO13_USB1_OTG_OC 0x41
- >;
- };
-
pinctrl_spi2: spi2grp {
fsl,pins = <
MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0xd6
MX8MM_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI 0xd6
MX8MM_IOMUXC_ECSPI2_MISO_ECSPI2_MISO 0xd6
MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13 0xd6
+ MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10 0xd6
>;
};
@@ -234,4 +223,11 @@
MX8MM_IOMUXC_UART3_TXD_UART3_DCE_TX 0x140
>;
};
+
+ pinctrl_usbotg1: usbotg1grp {
+ fsl,pins = <
+ MX8MM_IOMUXC_GPIO1_IO12_GPIO1_IO12 0x141
+ MX8MM_IOMUXC_GPIO1_IO13_USB1_OTG_OC 0x41
+ >;
+ };
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts
index 87b80e2412cb..5e2cbaf27e0f 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts
@@ -285,7 +285,8 @@
&ecspi1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_spi1>;
- cs-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>;
+ cs-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>,
+ <&gpio4 24 GPIO_ACTIVE_LOW>;
status = "okay";
flash@0 {
@@ -294,6 +295,12 @@
spi-max-frequency = <40000000>;
status = "okay";
};
+
+ tpm@1 {
+ compatible = "tcg,tpm_tis-spi";
+ reg = <0x1>;
+ spi-max-frequency = <36000000>;
+ };
};
&fec1 {
@@ -319,7 +326,7 @@
&gpio4 {
gpio-line-names = "", "", "", "",
- "", "", "uart3_rs232#", "uart3_rs422#",
+ "dig1_ctl", "dig2_ctl", "uart3_rs232#", "uart3_rs422#",
"uart3_rs485#", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "",
"", "", "", "uart4_rs485#", "", "sim1det#", "sim2det#", "";
@@ -842,6 +849,8 @@
pinctrl_hog: hoggrp {
fsl,pins = <
+ MX8MM_IOMUXC_SAI1_RXD2_GPIO4_IO4 0x40000041 /* DIG1_CTL */
+ MX8MM_IOMUXC_SAI1_RXD3_GPIO4_IO5 0x40000041 /* DIG2_CTL */
MX8MM_IOMUXC_SPDIF_TX_GPIO5_IO3 0x40000041 /* DIG2_OUT */
MX8MM_IOMUXC_SPDIF_RX_GPIO5_IO4 0x40000041 /* DIG2_IN */
MX8MM_IOMUXC_GPIO1_IO06_GPIO1_IO6 0x40000041 /* DIG1_IN */
@@ -987,6 +996,7 @@
MX8MM_IOMUXC_ECSPI1_MOSI_ECSPI1_MOSI 0x82
MX8MM_IOMUXC_ECSPI1_MISO_ECSPI1_MISO 0x82
MX8MM_IOMUXC_ECSPI1_SS0_GPIO5_IO9 0x140
+ MX8MM_IOMUXC_SAI2_TXFS_GPIO4_IO24 0x140
>;
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-beacon-kit.dts b/arch/arm64/boot/dts/freescale/imx8mn-beacon-kit.dts
index 35b8d2060cd9..bbd80896db96 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-beacon-kit.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mn-beacon-kit.dts
@@ -99,8 +99,6 @@
};
&lcdif {
- assigned-clocks = <&clk IMX8MN_VIDEO_PLL1>;
- assigned-clock-rates = <594000000>;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi b/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi
index a0e13d3324ed..269e70f66a13 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi
@@ -110,6 +110,20 @@
spdif-out;
spdif-in;
};
+
+ sound-micfil {
+ compatible = "fsl,imx-audio-card";
+ model = "micfil-audio";
+
+ pri-dai-link {
+ link-name = "micfil hifi";
+ format = "i2s";
+
+ cpu {
+ sound-dai = <&micfil>;
+ };
+ };
+ };
};
&easrc {
@@ -285,6 +299,16 @@
status = "okay";
};
+&micfil {
+ #sound-dai-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pdm>;
+ assigned-clocks = <&clk IMX8MN_CLK_PDM>;
+ assigned-clock-parents = <&clk IMX8MN_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <196608000>;
+ status = "okay";
+};
+
&mipi_csi {
status = "okay";
@@ -522,6 +546,18 @@
>;
};
+ pinctrl_pdm: pdmgrp {
+ fsl,pins = <
+ MX8MN_IOMUXC_SAI5_MCLK_SAI5_MCLK 0xd6
+ MX8MN_IOMUXC_SAI5_RXC_PDM_CLK 0xd6
+ MX8MN_IOMUXC_SAI5_RXFS_SAI5_RX_SYNC 0xd6
+ MX8MN_IOMUXC_SAI5_RXD0_PDM_BIT_STREAM0 0xd6
+ MX8MN_IOMUXC_SAI5_RXD1_PDM_BIT_STREAM1 0xd6
+ MX8MN_IOMUXC_SAI5_RXD2_PDM_BIT_STREAM2 0xd6
+ MX8MN_IOMUXC_SAI5_RXD3_PDM_BIT_STREAM3 0xd6
+ >;
+ };
+
pinctrl_pmic: pmicirqgrp {
fsl,pins = <
MX8MN_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x141
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-rve-gateway.dts b/arch/arm64/boot/dts/freescale/imx8mn-rve-gateway.dts
index 1b633bd1ebb6..ea1855171fb0 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-rve-gateway.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mn-rve-gateway.dts
@@ -10,7 +10,7 @@
/ {
model = "RVE gateway";
- compatible = "rve,rve-gateway", "variscite,var-som-mx8mn", "fsl,imx8mn";
+ compatible = "rve,gateway", "variscite,var-som-mx8mn", "fsl,imx8mn";
crystal_duart_24m: crystal-duart-24m {
compatible = "fixed-clock";
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx-usbotg.dtso b/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx-usbotg.dtso
new file mode 100644
index 000000000000..96db07fc9bec
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx-usbotg.dtso
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+/*
+ * Copyright (c) 2022-2024 TQ-Systems GmbH <linux@ew.tq-group.com>,
+ * D-82229 Seefeld, Germany.
+ * Author: Alexander Stein
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+#include "imx8mn-pinfunc.h"
+
+&{/} {
+ connector {
+ compatible = "gpio-usb-b-connector", "usb-b-connector";
+ type = "micro";
+ label = "X19";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb1_connector>;
+ id-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
+
+ port {
+ usb_dr_connector: endpoint {
+ remote-endpoint = <&usb1_drd_sw>;
+ };
+ };
+ };
+};
+
+&rst_usb_hub_hog {
+ output-low;
+};
+
+&sel_usb_hub_hog {
+ output-low;
+};
+
+&usbotg1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg>;
+ dr_mode = "otg";
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ power-active-high;
+ /delete-property/ disable-over-current;
+ over-current-active-low;
+ usb-role-switch;
+ status = "okay";
+
+ port {
+ usb1_drd_sw: endpoint {
+ remote-endpoint = <&usb_dr_connector>;
+ };
+ };
+};
+
+&iomuxc {
+ pinctrl_usb1_connector: usb1-connectorgrp {
+ fsl,pins = <MX8MN_IOMUXC_GPIO1_IO10_GPIO1_IO10 0x1c0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx.dts b/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx.dts
index c07d59147ab5..433d8bba4425 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl-mba8mx.dts
@@ -41,7 +41,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usb0hub_sel>;
- sel-usb-hub-hog {
+ sel_usb_hub_hog: sel-usb-hub-hog {
gpio-hog;
gpios = <1 GPIO_ACTIVE_HIGH>;
output-high;
@@ -198,8 +198,7 @@
pinctrl_usbotg: usbotggrp {
fsl,pins = <MX8MN_IOMUXC_GPIO1_IO12_USB1_OTG_PWR 0x84>,
- <MX8MN_IOMUXC_GPIO1_IO13_USB1_OTG_OC 0x84>,
- <MX8MN_IOMUXC_GPIO1_IO10_USB1_OTG_ID 0x1C4>;
+ <MX8MN_IOMUXC_GPIO1_IO13_USB1_OTG_OC 0x84>;
};
pinctrl_usdhc2: usdhc2grp {
diff --git a/arch/arm64/boot/dts/freescale/imx8mn.dtsi b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
index 136e75c51251..932c8b05c75f 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
@@ -1168,7 +1168,7 @@
<&clk IMX8MN_SYS_PLL1_800M>;
assigned-clock-rates = <266000000>,
<24000000>,
- <594000000>,
+ <24000000>,
<500000000>,
<200000000>;
#power-domain-cells = <1>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi
index e5da90804780..8be251b69378 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-beacon-som.dtsi
@@ -50,6 +50,8 @@
phy-mode = "rgmii-id";
phy-handle = <&ethphy0>;
snps,force_thresh_dma_mode;
+ snps,mtl-rx-config = <&mtl_rx_setup>;
+ snps,mtl-tx-config = <&mtl_tx_setup>;
status = "okay";
mdio {
@@ -66,6 +68,71 @@
interrupts = <10 IRQ_TYPE_LEVEL_LOW>;
};
};
+
+ mtl_rx_setup: rx-queues-config {
+ snps,rx-queues-to-use = <5>;
+ snps,rx-sched-sp;
+
+ queue0 {
+ snps,dcb-algorithm;
+ snps,priority = <0x1>;
+ snps,map-to-dma-channel = <0>;
+ };
+
+ queue1 {
+ snps,dcb-algorithm;
+ snps,priority = <0x2>;
+ snps,map-to-dma-channel = <1>;
+ };
+
+ queue2 {
+ snps,dcb-algorithm;
+ snps,priority = <0x4>;
+ snps,map-to-dma-channel = <2>;
+ };
+
+ queue3 {
+ snps,dcb-algorithm;
+ snps,priority = <0x8>;
+ snps,map-to-dma-channel = <3>;
+ };
+
+ queue4 {
+ snps,dcb-algorithm;
+ snps,priority = <0xf0>;
+ snps,map-to-dma-channel = <4>;
+ };
+ };
+
+ mtl_tx_setup: tx-queues-config {
+ snps,tx-queues-to-use = <5>;
+ snps,tx-sched-sp;
+
+ queue0 {
+ snps,dcb-algorithm;
+ snps,priority = <0x1>;
+ };
+
+ queue1 {
+ snps,dcb-algorithm;
+ snps,priority = <0x2>;
+ };
+
+ queue2 {
+ snps,dcb-algorithm;
+ snps,priority = <0x4>;
+ };
+
+ queue3 {
+ snps,dcb-algorithm;
+ snps,priority = <0x8>;
+ };
+
+ queue4 {
+ snps,dcb-algorithm;
+ snps,priority = <0xf0>;
+ };
+ };
};
&flexspi {
@@ -206,6 +273,10 @@
assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_80M>;
uart-has-rtscts;
status = "okay";
+
+ bluetooth {
+ compatible = "nxp,88w8997-bt";
+ };
};
&usdhc1 {
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts
index 5828c9d7821d..7e1b58dbe23a 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts
@@ -6,6 +6,7 @@
/dts-v1/;
#include <dt-bindings/net/qca-ar803x.h>
+#include <dt-bindings/phy/phy-imx8-pcie.h>
#include "imx8mp.dtsi"
/ {
@@ -45,6 +46,19 @@
clock-frequency = <25000000>;
};
+ clk_pwm4: clock-pwm4 {
+ compatible = "pwm-clock";
+ #clock-cells = <0>;
+ clock-frequency = <12000000>;
+ clock-output-names = "codec-pwm4";
+ /*
+ * 1 / 83 ns ~= 12 MHz , but since the PWM input clock is 24 MHz
+ * and the calculated PWM period is 1 and duty cycle is 50%, the
+ * result is exactly 12 MHz, which is fine for SGTL5000 MCLK.
+ */
+ pwms = <&pwm4 0 83 0>;
+ };
+
panel: panel {
/* Compatible string is filled in by panel board DT Overlay. */
backlight = <&backlight>;
@@ -82,6 +96,24 @@
vin-supply = <&buck4>;
};
+ sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "SGTL5000-Card";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,bitclock-master = <&codec_dai>;
+ simple-audio-card,frame-master = <&codec_dai>;
+ simple-audio-card,widgets = "Headphone", "Headphone Jack";
+ simple-audio-card,routing = "Headphone Jack", "HP_OUT";
+
+ cpu_dai: simple-audio-card,cpu {
+ sound-dai = <&sai3>;
+ };
+
+ codec_dai: simple-audio-card,codec {
+ sound-dai = <&sgtl5000>;
+ };
+ };
+
watchdog { /* TPS3813 */
compatible = "linux,wdt-gpio";
pinctrl-names = "default";
@@ -121,7 +153,7 @@
flash@0 { /* W25Q128JVEI */
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <100000000>; /* Up to 133 MHz */
+ spi-max-frequency = <40000000>;
spi-tx-bus-width = <1>;
spi-rx-bus-width = <1>;
};
@@ -288,6 +320,15 @@
sda-gpios = <&gpio5 15 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
status = "okay";
+ sgtl5000: audio-codec@a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ #sound-dai-cells = <0>;
+ clocks = <&clk_pwm4>;
+ VDDA-supply = <&buck4>;
+ VDDIO-supply = <&buck4>;
+ };
+
usb-hub@2c {
compatible = "microchip,usb2514bi";
reg = <0x2c>;
@@ -429,6 +470,21 @@
status = "okay";
};
+&pcie_phy {
+ clocks = <&pcieclk 0>;
+ clock-names = "ref";
+ fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>;
+ status = "okay";
+};
+
+&pcie {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcie0>;
+ fsl,max-link-speed = <3>;
+ reset-gpio = <&gpio1 5 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
&pwm1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_panel_pwm>;
@@ -436,6 +492,23 @@
status = "disabled";
};
+&pwm4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm4>;
+ status = "okay";
+};
+
+&sai3 {
+ #clock-cells = <0>;
+ #sound-dai-cells = <0>;
+ assigned-clocks = <&clk IMX8MP_CLK_SAI3>;
+ assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL1_OUT>;
+ assigned-clock-rates = <12288000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai3>;
+ status = "okay";
+};
+
/* SD slot */
&usdhc2 {
pinctrl-names = "default", "state_100mhz", "state_200mhz";
@@ -785,6 +858,12 @@
>;
};
+ pinctrl_pwm4: pwm4-grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI3_MCLK__PWM4_OUT 0xd6
+ >;
+ };
+
pinctrl_rtc: rtc-grp {
fsl,pins = <
/* RTC_IRQ# */
@@ -816,7 +895,6 @@
MX8MP_IOMUXC_SAI3_TXFS__AUDIOMIX_SAI3_TX_SYNC 0xd6
MX8MP_IOMUXC_SAI3_TXD__AUDIOMIX_SAI3_TX_DATA00 0xd6
MX8MP_IOMUXC_SAI3_TXC__AUDIOMIX_SAI3_TX_BCLK 0xd6
- MX8MP_IOMUXC_SAI3_MCLK__AUDIOMIX_SAI3_MCLK 0xd6
MX8MP_IOMUXC_SAI3_RXD__AUDIOMIX_SAI3_RX_DATA00 0xd6
>;
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
index f87fa5a948cc..9beba8d6a0df 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
@@ -23,7 +23,7 @@
port {
hdmi_connector_in: endpoint {
- remote-endpoint = <&adv7533_out>;
+ remote-endpoint = <&adv7535_out>;
};
};
};
@@ -107,6 +107,13 @@
enable-active-high;
};
+ reg_vext_3v3: regulator-vext-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VEXT_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
sound {
compatible = "simple-audio-card";
simple-audio-card,name = "wm8960-audio";
@@ -364,7 +371,7 @@
regulator-always-on;
};
- BUCK5 {
+ reg_buck5: BUCK5 {
regulator-name = "BUCK5";
regulator-min-microvolt = <1650000>;
regulator-max-microvolt = <1950000>;
@@ -415,14 +422,16 @@
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";
+ avdd-supply = <&reg_buck5>;
+ dvdd-supply = <&reg_buck5>;
+ pvdd-supply = <&reg_buck5>;
+ a2vdd-supply = <&reg_buck5>;
+ v3p3-supply = <&reg_vext_3v3>;
+ v1p2-supply = <&reg_buck5>;
ports {
#address-cells = <1>;
@@ -431,7 +440,7 @@
port@0 {
reg = <0>;
- adv7533_in: endpoint {
+ adv7535_in: endpoint {
remote-endpoint = <&dsi_out>;
};
};
@@ -439,7 +448,7 @@
port@1 {
reg = <1>;
- adv7533_out: endpoint {
+ adv7535_out: endpoint {
remote-endpoint = <&hdmi_connector_in>;
};
};
@@ -524,7 +533,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/imx8mp-phyboard-pollux-rdk.dts b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
index c8640cac3edc..00a240484c25 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts
@@ -19,6 +19,30 @@
stdout-path = &uart1;
};
+ backlight_lvds: backlight {
+ compatible = "pwm-backlight";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lvds1>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <11>;
+ enable-gpios = <&gpio2 20 GPIO_ACTIVE_LOW>;
+ num-interpolated-steps = <2>;
+ power-supply = <&reg_lvds1_reg_en>;
+ pwms = <&pwm3 0 50000 0>;
+ };
+
+ panel1_lvds: panel-lvds {
+ compatible = "edt,etml1010g3dra";
+ backlight = <&backlight_lvds>;
+ power-supply = <&reg_vcc_3v3_sw>;
+
+ port {
+ panel1_in: endpoint {
+ remote-endpoint = <&ldb_lvds_ch1>;
+ };
+ };
+ };
+
reg_can1_stby: regulator-can1-stby {
compatible = "regulator-fixed";
pinctrl-names = "default";
@@ -39,6 +63,15 @@
regulator-name = "can2-stby";
};
+ reg_lvds1_reg_en: regulator-lvds1 {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+ regulator-max-microvolt = <1200000>;
+ regulator-min-microvolt = <1200000>;
+ regulator-name = "lvds1_reg_en";
+ };
+
reg_usb1_vbus: regulator-usb1-vbus {
compatible = "regulator-fixed";
pinctrl-names = "default";
@@ -61,6 +94,13 @@
startup-delay-us = <100>;
off-on-delay-us = <12000>;
};
+
+ reg_vcc_3v3_sw: regulator-vcc-3v3-sw {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_3V3_SW";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
};
&eqos {
@@ -135,10 +175,41 @@
};
};
+&lcdif2 {
+ status = "okay";
+};
+
+&lvds_bridge {
+ status = "okay";
+
+ ports {
+ port@2 {
+ ldb_lvds_ch1: endpoint {
+ remote-endpoint = <&panel1_in>;
+ };
+ };
+ };
+};
+
&snvs_pwrkey {
status = "okay";
};
+&pwm3 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm3>;
+};
+
+&rv3028 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_rtc>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <19 IRQ_TYPE_LEVEL_LOW>;
+ wakeup-source;
+ trickle-resistor-ohms = <3000>;
+};
+
/* debug console */
&uart1 {
pinctrl-names = "default";
@@ -239,12 +310,12 @@
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 0x16
- MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1 0x16
- MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2 0x16
- MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3 0x16
- MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x16
- MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x16
+ 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 0x12
MX8MP_IOMUXC_SAI1_MCLK__GPIO4_IO20 0x10
>;
};
@@ -289,16 +360,34 @@
>;
};
+ pinctrl_lvds1: lvds1grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SD2_WP__GPIO2_IO20 0x12
+ >;
+ };
+
+ pinctrl_pwm3: pwm3grp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SPDIF_TX__PWM3_OUT 0x12
+ >;
+ };
+
pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp {
fsl,pins = <
MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19 0x40
>;
};
+ pinctrl_rtc: rtcgrp {
+ fsl,pins = <
+ MX8MP_IOMUXC_SAI1_TXD7__GPIO4_IO19 0x1C0
+ >;
+ };
+
pinctrl_uart1: uart1grp {
fsl,pins = <
- MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX 0x40
- MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX 0x40
+ MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX 0x140
+ MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX 0x140
>;
};
@@ -319,7 +408,7 @@
pinctrl_usdhc2_pins: usdhc2-gpiogrp {
fsl,pins = <
- MX8MP_IOMUXC_SD2_CD_B__GPIO2_IO12 0x1c4
+ MX8MP_IOMUXC_SD2_CD_B__GPIO2_IO12 0x40
>;
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
index c976c3b6cbc6..e6ffa6a6b68b 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi
@@ -175,7 +175,6 @@
rv3028: rtc@52 {
compatible = "microcrystal,rv3028";
reg = <0x52>;
- trickle-resistor-ohms = <3000>;
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw71xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw71xx.dtsi
index 0e8d0f3c7ea8..e7bf032265e0 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw71xx.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw71xx.dtsi
@@ -63,8 +63,15 @@
&ecspi2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_spi2>;
- cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>;
+ cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>,
+ <&gpio1 10 GPIO_ACTIVE_LOW>;
status = "okay";
+
+ tpm@1 {
+ compatible = "tcg,tpm_tis-spi";
+ reg = <0x1>;
+ spi-max-frequency = <36000000>;
+ };
};
&gpio4 {
@@ -228,6 +235,7 @@
MX8MP_IOMUXC_ECSPI2_MOSI__ECSPI2_MOSI 0x140
MX8MP_IOMUXC_ECSPI2_MISO__ECSPI2_MISO 0x140
MX8MP_IOMUXC_ECSPI2_SS0__GPIO5_IO13 0x140
+ MX8MP_IOMUXC_GPIO1_IO10__GPIO1_IO10 0x140
>;
};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi
index c3305f0d4001..faa17cbbe2fd 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi
@@ -552,7 +552,7 @@
regulator-name = "On-module +V3.3_ADC (LDO4)";
};
- LDO5 {
+ reg_vdd_sdio: LDO5 {
regulator-max-microvolt = <3300000>;
regulator-min-microvolt = <1800000>;
regulator-name = "On-module +V3.3_1.8_SD (LDO5)";
@@ -885,6 +885,7 @@
pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_cd>;
pinctrl-3 = <&pinctrl_usdhc2_sleep>, <&pinctrl_usdhc2_cd_sleep>;
vmmc-supply = <&reg_usdhc2_vmmc>;
+ vqmmc-supply = <&reg_vdd_sdio>;
};
/* On-module eMMC */
diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 39a550c1cd26..bfc5c81a5bd4 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -1636,8 +1636,10 @@
<&clk IMX8MP_CLK_MEDIA_MIPI_PHY1_REF_ROOT>,
<&clk IMX8MP_CLK_MEDIA_AXI_ROOT>;
clock-names = "pclk", "wrap", "phy", "axi";
- assigned-clocks = <&clk IMX8MP_CLK_MEDIA_CAM1_PIX>;
- assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_1000M>;
+ assigned-clocks = <&clk IMX8MP_CLK_MEDIA_CAM1_PIX>,
+ <&clk IMX8MP_CLK_MEDIA_MIPI_PHY1_REF>;
+ assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_1000M>,
+ <&clk IMX8MP_CLK_24M>;
assigned-clock-rates = <500000000>;
power-domains = <&media_blk_ctrl IMX8MP_MEDIABLK_PD_MIPI_CSI2_1>;
status = "disabled";
@@ -1670,8 +1672,10 @@
<&clk IMX8MP_CLK_MEDIA_MIPI_PHY1_REF_ROOT>,
<&clk IMX8MP_CLK_MEDIA_AXI_ROOT>;
clock-names = "pclk", "wrap", "phy", "axi";
- assigned-clocks = <&clk IMX8MP_CLK_MEDIA_CAM2_PIX>;
- assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_1000M>;
+ assigned-clocks = <&clk IMX8MP_CLK_MEDIA_CAM1_PIX>,
+ <&clk IMX8MP_CLK_MEDIA_MIPI_PHY1_REF>;
+ assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_1000M>,
+ <&clk IMX8MP_CLK_24M>;
assigned-clock-rates = <266000000>;
power-domains = <&media_blk_ctrl IMX8MP_MEDIABLK_PD_MIPI_CSI2_2>;
status = "disabled";
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dts b/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dts
index b302daca4ce6..0165f3a25985 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-mba8mx.dts
@@ -28,18 +28,6 @@
id-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
};
- pcie0_refclk: pcie0-refclk {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <100000000>;
- };
-
- pcie1_refclk: pcie1-refclk {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <100000000>;
- };
-
reg_otg_vbus: regulator-otg-vbus {
compatible = "regulator-fixed";
pinctrl-names = "default";
@@ -103,23 +91,24 @@
gpios = <&gpio3 16 GPIO_ACTIVE_HIGH>;
};
+/* PCIe slot on X36 */
&pcie0 {
reset-gpio = <&expander0 14 GPIO_ACTIVE_LOW>;
clocks = <&clk IMX8MQ_CLK_PCIE1_ROOT>,
- <&pcie0_refclk>,
- <&clk IMX8MQ_CLK_PCIE1_PHY>,
+ <&pcieclk 3>,
+ <&pcieclk 2>,
<&clk IMX8MQ_CLK_PCIE1_AUX>;
status = "okay";
};
/*
- * miniPCIe, also usable for cards with USB. Therefore configure the reset as
+ * miniPCIe on X28, also usable for cards with USB. Therefore configure the reset as
* static gpio hog.
*/
&pcie1 {
clocks = <&clk IMX8MQ_CLK_PCIE2_ROOT>,
- <&pcie1_refclk>,
- <&clk IMX8MQ_CLK_PCIE2_PHY>,
+ <&pcieclk 1>,
+ <&pcieclk 0>,
<&clk IMX8MQ_CLK_PCIE2_AUX>;
status = "okay";
};
@@ -171,6 +160,7 @@
};
&usb3_phy1 {
+ vbus-supply = <&reg_hub_vbus>;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-apalis-eval-v1.2.dts b/arch/arm64/boot/dts/freescale/imx8qm-apalis-eval-v1.2.dts
new file mode 100644
index 000000000000..8466a8204ed0
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qm-apalis-eval-v1.2.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2024 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8qm-apalis.dtsi"
+#include "imx8-apalis-eval-v1.2.dtsi"
+
+/ {
+ model = "Toradex Apalis iMX8QM/QP on Apalis Evaluation Board V1.2";
+ compatible = "toradex,apalis-imx8-eval-v1.2",
+ "toradex,apalis-imx8",
+ "fsl,imx8qm";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-apalis-eval.dts b/arch/arm64/boot/dts/freescale/imx8qm-apalis-eval.dts
index 5ab0921eb599..b0ebf6d05450 100644
--- a/arch/arm64/boot/dts/freescale/imx8qm-apalis-eval.dts
+++ b/arch/arm64/boot/dts/freescale/imx8qm-apalis-eval.dts
@@ -6,7 +6,7 @@
/dts-v1/;
#include "imx8qm-apalis.dtsi"
-#include "imx8-apalis-eval.dtsi"
+#include "imx8-apalis-eval-v1.1.dtsi"
/ {
model = "Toradex Apalis iMX8QM/QP on Apalis Evaluation Board";
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-apalis-v1.1-eval-v1.2.dts b/arch/arm64/boot/dts/freescale/imx8qm-apalis-v1.1-eval-v1.2.dts
new file mode 100644
index 000000000000..92c0ae0c0337
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qm-apalis-v1.1-eval-v1.2.dts
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2024 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8qm-apalis-v1.1.dtsi"
+#include "imx8-apalis-eval-v1.2.dtsi"
+
+/ {
+ model = "Toradex Apalis iMX8QM V1.1 on Apalis Evaluation Board V1.2";
+ compatible = "toradex,apalis-imx8-v1.1-eval-v1.2",
+ "toradex,apalis-imx8-v1.1",
+ "fsl,imx8qm";
+};
+
+/* Apalis MMC1 */
+&usdhc2 {
+ /delete-property/ no-1-8-v;
+};
+
+/* Apalis SD1 */
+&usdhc3 {
+ /delete-property/ no-1-8-v;
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-apalis-v1.1-eval.dts b/arch/arm64/boot/dts/freescale/imx8qm-apalis-v1.1-eval.dts
index c8ff75831556..c998e542f93c 100644
--- a/arch/arm64/boot/dts/freescale/imx8qm-apalis-v1.1-eval.dts
+++ b/arch/arm64/boot/dts/freescale/imx8qm-apalis-v1.1-eval.dts
@@ -6,7 +6,7 @@
/dts-v1/;
#include "imx8qm-apalis-v1.1.dtsi"
-#include "imx8-apalis-eval.dtsi"
+#include "imx8-apalis-eval-v1.1.dtsi"
/ {
model = "Toradex Apalis iMX8QM V1.1 on Apalis Evaluation Board";
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-mek.dts b/arch/arm64/boot/dts/freescale/imx8qm-mek.dts
index 6d50838ad17d..77ac0efdfaad 100644
--- a/arch/arm64/boot/dts/freescale/imx8qm-mek.dts
+++ b/arch/arm64/boot/dts/freescale/imx8qm-mek.dts
@@ -41,6 +41,18 @@
};
};
+&i2c1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c1>;
+ pinctrl-1 = <&pinctrl_i2c1_gpio>;
+ scl-gpios = <&lsio_gpio0 14 GPIO_ACTIVE_HIGH>;
+ sda-gpios = <&lsio_gpio0 15 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
&lpuart0 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_lpuart0>;
@@ -104,6 +116,20 @@
};
&iomuxc {
+ pinctrl_i2c1: i2c1grp {
+ fsl,pins = <
+ IMX8QM_GPT0_CLK_DMA_I2C1_SCL 0x0600004c
+ IMX8QM_GPT0_CAPTURE_DMA_I2C1_SDA 0x0600004c
+ >;
+ };
+
+ pinctrl_i2c1_gpio: i2c1gpio-grp {
+ fsl,pins = <
+ IMX8QM_GPT0_CLK_LSIO_GPIO0_IO14 0xc600004c
+ IMX8QM_GPT0_CAPTURE_LSIO_GPIO0_IO15 0xc600004c
+ >;
+ };
+
pinctrl_fec1: fec1grp {
fsl,pins = <
IMX8QM_ENET0_MDC_CONN_ENET0_MDC 0x06000020
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi b/arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi
index ec1639174e2e..545e175c88b3 100644
--- a/arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi
@@ -6,20 +6,25 @@
&fec1 {
compatible = "fsl,imx8qm-fec", "fsl,imx6sx-fec";
+ iommus = <&smmu 0x12 0x7f80>;
};
&fec2 {
compatible = "fsl,imx8qm-fec", "fsl,imx6sx-fec";
+ iommus = <&smmu 0x12 0x7f80>;
};
&usdhc1 {
compatible = "fsl,imx8qm-usdhc", "fsl,imx8qxp-usdhc", "fsl,imx7d-usdhc";
+ iommus = <&smmu 0x11 0x7f80>;
};
&usdhc2 {
compatible = "fsl,imx8qm-usdhc", "fsl,imx8qxp-usdhc", "fsl,imx7d-usdhc";
+ iommus = <&smmu 0x11 0x7f80>;
};
&usdhc3 {
compatible = "fsl,imx8qm-usdhc", "fsl,imx8qxp-usdhc", "fsl,imx7d-usdhc";
+ iommus = <&smmu 0x11 0x7f80>;
};
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-ss-dma.dtsi b/arch/arm64/boot/dts/freescale/imx8qm-ss-dma.dtsi
index 69cb8676732e..11626fae5f97 100644
--- a/arch/arm64/boot/dts/freescale/imx8qm-ss-dma.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qm-ss-dma.dtsi
@@ -17,6 +17,32 @@
power-domains = <&pd IMX_SC_R_UART_4>;
};
+ i2c4: i2c@5a840000 {
+ compatible = "fsl,imx8qm-lpi2c", "fsl,imx7ulp-lpi2c";
+ reg = <0x5a840000 0x4000>;
+ interrupts = <GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-parent = <&gic>;
+ clocks = <&i2c4_lpcg 0>,
+ <&i2c4_lpcg 1>;
+ clock-names = "per", "ipg";
+ assigned-clocks = <&clk IMX_SC_R_I2C_4 IMX_SC_PM_CLK_PER>;
+ assigned-clock-rates = <24000000>;
+ power-domains = <&pd IMX_SC_R_I2C_4>;
+ status = "disabled";
+ };
+
+ i2c4_lpcg: clock-controller@5ac40000 {
+ compatible = "fsl,imx8qxp-lpcg";
+ reg = <0x5ac40000 0x10000>;
+ #clock-cells = <1>;
+ clocks = <&clk IMX_SC_R_I2C_4 IMX_SC_PM_CLK_PER>,
+ <&dma_ipg_clk>;
+ clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_4>;
+ clock-output-names = "i2c4_lpcg_clk",
+ "i2c4_lpcg_ipg_clk";
+ power-domains = <&pd IMX_SC_R_I2C_4>;
+ };
+
can1_lpcg: clock-controller@5ace0000 {
compatible = "fsl,imx8qxp-lpcg";
reg = <0x5ace0000 0x10000>;
@@ -96,15 +122,30 @@
status = "okay";
};
+/* It is eDMA1 in 8QM RM, but 8QXP it is eDMA3 */
&edma3 {
+ reg = <0x5a9f0000 0x210000>;
+ dma-channels = <10>;
+ interrupts = <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 427 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 428 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 429 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 430 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 431 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 432 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 433 IRQ_TYPE_LEVEL_HIGH>;
power-domains = <&pd IMX_SC_R_DMA_1_CH0>,
- <&pd IMX_SC_R_DMA_1_CH1>,
- <&pd IMX_SC_R_DMA_1_CH2>,
- <&pd IMX_SC_R_DMA_1_CH3>,
- <&pd IMX_SC_R_DMA_1_CH4>,
- <&pd IMX_SC_R_DMA_1_CH5>,
- <&pd IMX_SC_R_DMA_1_CH6>,
- <&pd IMX_SC_R_DMA_1_CH7>;
+ <&pd IMX_SC_R_DMA_1_CH1>,
+ <&pd IMX_SC_R_DMA_1_CH2>,
+ <&pd IMX_SC_R_DMA_1_CH3>,
+ <&pd IMX_SC_R_DMA_1_CH4>,
+ <&pd IMX_SC_R_DMA_1_CH5>,
+ <&pd IMX_SC_R_DMA_1_CH6>,
+ <&pd IMX_SC_R_DMA_1_CH7>,
+ <&pd IMX_SC_R_DMA_1_CH8>,
+ <&pd IMX_SC_R_DMA_1_CH9>;
};
&flexcan1 {
diff --git a/arch/arm64/boot/dts/freescale/imx8qm.dtsi b/arch/arm64/boot/dts/freescale/imx8qm.dtsi
index 31744fc1ab08..b3d01677b70c 100644
--- a/arch/arm64/boot/dts/freescale/imx8qm.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qm.dtsi
@@ -265,6 +265,47 @@
<GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>; /* Hypervisor */
};
+ smmu: iommu@51400000 {
+ compatible = "arm,mmu-500";
+ interrupt-parent = <&gic>;
+ reg = <0 0x51400000 0 0x40000>;
+ #global-interrupts = <1>;
+ #iommu-cells = <2>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
system-controller {
compatible = "fsl,imx-scu";
mbox-names = "tx0",
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-tqma8xqp-mba8xx.dts b/arch/arm64/boot/dts/freescale/imx8qxp-tqma8xqp-mba8xx.dts
new file mode 100644
index 000000000000..7d2e98bf8bc5
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-tqma8xqp-mba8xx.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR X11)
+/*
+ * Copyright 2018-2023 TQ-Systems GmbH <linux@ew.tq-group.com>,
+ * D-82229 Seefeld, Germany.
+ * Author: Alexander Stein
+ */
+
+/dts-v1/;
+
+#include "imx8qxp-tqma8xqp.dtsi"
+#include "mba8xx.dtsi"
+
+/ {
+ model = "TQ-Systems i.MX8QXP TQMa8XQP on MBa8Xx";
+ compatible = "tq,imx8qxp-tqma8xqp-mba8xx", "tq,imx8qxp-tqma8xqp", "fsl,imx8qxp";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-tqma8xqp.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp-tqma8xqp.dtsi
new file mode 100644
index 000000000000..b14040bf4ddd
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-tqma8xqp.dtsi
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR X11)
+/*
+ * Copyright 2018-2023 TQ-Systems GmbH <linux@ew.tq-group.com>,
+ * D-82229 Seefeld, Germany.
+ * Author: Alexander Stein
+ */
+
+#include "imx8qxp.dtsi"
+#include "tqma8xx.dtsi"
+
+/ {
+ model = "TQ-Systems i.MX8QXP TQMa8XQP";
+ compatible = "tq,imx8qxp-tqma8xqp", "fsl,imx8qxp";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
index 958267b33340..10e16d84c0c3 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
@@ -260,6 +260,13 @@
<GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>; /* Hypervisor */
};
+ clk_dummy: clock-dummy {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ clock-output-names = "clk_dummy";
+ };
+
xtal32k: clock-xtal32k {
compatible = "fixed-clock";
#clock-cells = <0>;
@@ -310,6 +317,7 @@
/* sorted in register address */
#include "imx8-ss-img.dtsi"
#include "imx8-ss-vpu.dtsi"
+ #include "imx8-ss-gpu0.dtsi"
#include "imx8-ss-adma.dtsi"
#include "imx8-ss-conn.dtsi"
#include "imx8-ss-ddr.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts b/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
index 69dd8e31027c..24bb253b938d 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
@@ -37,7 +37,7 @@
no-map;
};
- rsc_table: rsc-table@1fff8000{
+ rsc_table: rsc-table@1fff8000 {
reg = <0 0x1fff8000 0 0x1000>;
no-map;
};
diff --git a/arch/arm64/boot/dts/freescale/imx93-phyboard-segin.dts b/arch/arm64/boot/dts/freescale/imx93-phyboard-segin.dts
new file mode 100644
index 000000000000..85fb188b057f
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx93-phyboard-segin.dts
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2023 PHYTEC Messtechnik GmbH
+ * Author: Wadim Egorov <w.egorov@phytec.de>, Christoph Stoidner <c.stoidner@phytec.de>
+ * Copyright (C) 2024 Mathieu Othacehe <m.othacehe@gmail.com>
+ *
+ * Product homepage:
+ * phyBOARD-Segin carrier board is reused for the i.MX93 design.
+ * https://www.phytec.eu/en/produkte/single-board-computer/phyboard-segin-imx6ul/
+ */
+/dts-v1/;
+
+#include "imx93-phycore-som.dtsi"
+
+/{
+ model = "PHYTEC phyBOARD-Segin-i.MX93";
+ compatible = "phytec,imx93-phyboard-segin", "phytec,imx93-phycore-som",
+ "fsl,imx93";
+
+ chosen {
+ stdout-path = &lpuart1;
+ };
+
+ reg_usdhc2_vmmc: regulator-usdhc2 {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio3 7 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_usdhc2_vmmc>;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "VCC_SD";
+ };
+};
+
+/* Console */
+&lpuart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+/* eMMC */
+&usdhc1 {
+ no-1-8-v;
+};
+
+/* SD-Card */
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2_default>, <&pinctrl_usdhc2_cd>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_cd>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_cd>;
+ bus-width = <4>;
+ cd-gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+ no-mmc;
+ no-sdio;
+ vmmc-supply = <&reg_usdhc2_vmmc>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl_uart1: uart1grp {
+ fsl,pins = <
+ MX93_PAD_UART1_RXD__LPUART1_RX 0x31e
+ MX93_PAD_UART1_TXD__LPUART1_TX 0x30e
+ >;
+ };
+
+ pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp {
+ fsl,pins = <
+ MX93_PAD_SD2_RESET_B__GPIO3_IO07 0x31e
+ >;
+ };
+
+ pinctrl_usdhc2_cd: usdhc2cdgrp {
+ fsl,pins = <
+ MX93_PAD_SD2_CD_B__GPIO3_IO00 0x31e
+ >;
+ };
+
+ pinctrl_usdhc2_default: usdhc2grp {
+ fsl,pins = <
+ MX93_PAD_SD2_CLK__USDHC2_CLK 0x179e
+ MX93_PAD_SD2_CMD__USDHC2_CMD 0x139e
+ MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x138e
+ MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x138e
+ MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x138e
+ MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x139e
+ MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e
+ >;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2grp {
+ fsl,pins = <
+ MX93_PAD_SD2_CLK__USDHC2_CLK 0x179e
+ MX93_PAD_SD2_CMD__USDHC2_CMD 0x139e
+ MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x138e
+ MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x138e
+ MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x139e
+ MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x139e
+ MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e
+ >;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2grp {
+ fsl,pins = <
+ MX93_PAD_SD2_CLK__USDHC2_CLK 0x178e
+ MX93_PAD_SD2_CMD__USDHC2_CMD 0x139e
+ MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x139e
+ MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x139e
+ MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x139e
+ MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x139e
+ MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e
+ >;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx93-phycore-som.dtsi b/arch/arm64/boot/dts/freescale/imx93-phycore-som.dtsi
new file mode 100644
index 000000000000..88c2657b50e6
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx93-phycore-som.dtsi
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2023 PHYTEC Messtechnik GmbH
+ * Author: Wadim Egorov <w.egorov@phytec.de>, Christoph Stoidner <c.stoidner@phytec.de>
+ * Copyright (C) 2024 Mathieu Othacehe <m.othacehe@gmail.com>
+ *
+ * Product homepage:
+ * https://www.phytec.eu/en/produkte/system-on-modules/phycore-imx-91-93/
+ */
+
+#include <dt-bindings/leds/common.h>
+
+#include "imx93.dtsi"
+
+/{
+ model = "PHYTEC phyCORE-i.MX93";
+ compatible = "phytec,imx93-phycore-som", "fsl,imx93";
+
+ reserved-memory {
+ ranges;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ alloc-ranges = <0 0x80000000 0 0x40000000>;
+ size = <0 0x10000000>;
+ linux,cma-default;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_leds>;
+
+ led-0 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_HEARTBEAT;
+ gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+};
+
+/* Ethernet */
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec>;
+ phy-mode = "rmii";
+ phy-handle = <&ethphy1>;
+ fsl,magic-packet;
+ assigned-clocks = <&clk IMX93_CLK_ENET_TIMER1>,
+ <&clk IMX93_CLK_ENET_REF>,
+ <&clk IMX93_CLK_ENET_REF_PHY>;
+ assigned-clock-parents = <&clk IMX93_CLK_SYS_PLL_PFD1_DIV2>,
+ <&clk IMX93_CLK_SYS_PLL_PFD1_DIV2>,
+ <&clk IMX93_CLK_SYS_PLL_PFD1_DIV2>;
+ assigned-clock-rates = <100000000>, <50000000>, <50000000>;
+ status = "okay";
+
+ mdio: mdio {
+ clock-frequency = <5000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ };
+ };
+};
+
+/* eMMC */
+&usdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ bus-width = <8>;
+ non-removable;
+ status = "okay";
+};
+
+/* Watchdog */
+&wdog3 {
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl_fec: fecgrp {
+ fsl,pins = <
+ MX93_PAD_ENET2_MDC__ENET1_MDC 0x50e
+ MX93_PAD_ENET2_MDIO__ENET1_MDIO 0x502
+ MX93_PAD_ENET2_RD0__ENET1_RGMII_RD0 0x57e
+ MX93_PAD_ENET2_RD1__ENET1_RGMII_RD1 0x57e
+ MX93_PAD_ENET2_RXC__ENET1_RX_ER 0x5fe
+ MX93_PAD_ENET2_RX_CTL__ENET1_RGMII_RX_CTL 0x57e
+ MX93_PAD_ENET2_TD0__ENET1_RGMII_TD0 0x50e
+ MX93_PAD_ENET2_TD1__ENET1_RGMII_TD1 0x50e
+ MX93_PAD_ENET2_TX_CTL__ENET1_RGMII_TX_CTL 0x50e
+ MX93_PAD_ENET2_TD2__ENET1_TX_CLK 0x4000050e
+ >;
+ };
+
+ pinctrl_leds: ledsgrp {
+ fsl,pins = <
+ MX93_PAD_I2C1_SDA__GPIO1_IO01 0x31e
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX93_PAD_SD1_CLK__USDHC1_CLK 0x179e
+ MX93_PAD_SD1_CMD__USDHC1_CMD 0x1386
+ MX93_PAD_SD1_DATA0__USDHC1_DATA0 0x138e
+ MX93_PAD_SD1_DATA1__USDHC1_DATA1 0x1386
+ MX93_PAD_SD1_DATA2__USDHC1_DATA2 0x138e
+ MX93_PAD_SD1_DATA3__USDHC1_DATA3 0x1386
+ MX93_PAD_SD1_DATA4__USDHC1_DATA4 0x1386
+ MX93_PAD_SD1_DATA5__USDHC1_DATA5 0x1386
+ MX93_PAD_SD1_DATA6__USDHC1_DATA6 0x1386
+ MX93_PAD_SD1_DATA7__USDHC1_DATA7 0x1386
+ MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x179e
+ >;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi b/arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi
index f6e422dc2663..9d2328c185c9 100644
--- a/arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi
@@ -122,10 +122,8 @@
/* protectable identification memory (part of M24C64-D @57) */
eeprom@5f {
- compatible = "st,24c64", "atmel,24c64";
+ compatible = "atmel,24c64d-wl";
reg = <0x5f>;
- size = <32>;
- pagesize = <32>;
vcc-supply = <&reg_v3v3>;
};
diff --git a/arch/arm64/boot/dts/freescale/imx93-var-som-symphony.dts b/arch/arm64/boot/dts/freescale/imx93-var-som-symphony.dts
new file mode 100644
index 000000000000..576d6982a4a0
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx93-var-som-symphony.dts
@@ -0,0 +1,351 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2021 NXP
+ * Copyright 2023 Variscite Ltd.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/leds/common.h>
+#include "imx93-var-som.dtsi"
+
+/{
+ model = "Variscite VAR-SOM-MX93 on Symphony evaluation board";
+ compatible = "variscite,var-som-mx93-symphony",
+ "variscite,var-som-mx93", "fsl,imx93";
+
+ aliases {
+ ethernet0 = &eqos;
+ ethernet1 = &fec;
+ };
+
+ chosen {
+ stdout-path = &lpuart1;
+ };
+
+ /*
+ * Needed only for Symphony <= v1.5
+ */
+ reg_fec_phy: regulator-fec-phy {
+ compatible = "regulator-fixed";
+ regulator-name = "fec-phy";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-enable-ramp-delay = <20000>;
+ gpio = <&pca9534 7 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-always-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 18 GPIO_ACTIVE_HIGH>;
+ off-on-delay-us = <20000>;
+ enable-active-high;
+ };
+
+ reg_vref_1v8: regulator-adc-vref {
+ compatible = "regulator-fixed";
+ regulator-name = "vref_1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ ethosu_mem: ethosu-region@88000000 {
+ compatible = "shared-dma-pool";
+ reusable;
+ reg = <0x0 0x88000000 0x0 0x8000000>;
+ };
+
+ vdev0vring0: vdev0vring0@87ee0000 {
+ reg = <0 0x87ee0000 0 0x8000>;
+ no-map;
+ };
+
+ vdev0vring1: vdev0vring1@87ee8000 {
+ reg = <0 0x87ee8000 0 0x8000>;
+ no-map;
+ };
+
+ vdev1vring0: vdev1vring0@87ef0000 {
+ reg = <0 0x87ef0000 0 0x8000>;
+ no-map;
+ };
+
+ vdev1vring1: vdev1vring1@87ef8000 {
+ reg = <0 0x87ef8000 0 0x8000>;
+ no-map;
+ };
+
+ rsc_table: rsc-table@2021f000 {
+ reg = <0 0x2021f000 0 0x1000>;
+ no-map;
+ };
+
+ vdevbuffer: vdevbuffer@87f00000 {
+ compatible = "shared-dma-pool";
+ reg = <0 0x87f00000 0 0x100000>;
+ no-map;
+ };
+
+ ele_reserved: ele-reserved@87de0000 {
+ compatible = "shared-dma-pool";
+ reg = <0 0x87de0000 0 0x100000>;
+ no-map;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ key-back {
+ label = "Back";
+ gpios = <&pca9534 1 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_BACK>;
+ };
+
+ key-home {
+ label = "Home";
+ gpios = <&pca9534 2 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_HOME>;
+ };
+
+ key-menu {
+ label = "Menu";
+ gpios = <&pca9534 3 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_MENU>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&pca9534 0 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+};
+
+/* Use external instead of internal RTC*/
+&bbnsm_rtc {
+ status = "disabled";
+};
+
+&eqos {
+ mdio {
+ ethphy1: ethernet-phy@5 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <5>;
+ qca,disable-smarteee;
+ eee-broken-1000t;
+ reset-gpios = <&pca9534 5 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <10000>;
+ reset-deassert-us = <20000>;
+ vddio-supply = <&vddio1>;
+
+ vddio1: vddio-regulator {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+ };
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec>;
+ phy-mode = "rgmii";
+ phy-handle = <&ethphy1>;
+ phy-supply = <&reg_fec_phy>;
+ status = "okay";
+};
+
+&flexcan1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ status = "okay";
+};
+
+&lpi2c1 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default", "sleep", "gpio";
+ pinctrl-0 = <&pinctrl_lpi2c1>;
+ pinctrl-1 = <&pinctrl_lpi2c1_gpio>;
+ pinctrl-2 = <&pinctrl_lpi2c1_gpio>;
+ scl-gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>;
+ sda-gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+
+ /* DS1337 RTC module */
+ rtc@68 {
+ compatible = "dallas,ds1337";
+ reg = <0x68>;
+ };
+};
+
+&lpi2c5 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default", "sleep", "gpio";
+ pinctrl-0 = <&pinctrl_lpi2c5>;
+ pinctrl-1 = <&pinctrl_lpi2c5_gpio>;
+ pinctrl-2 = <&pinctrl_lpi2c5_gpio>;
+ scl-gpios = <&gpio2 23 GPIO_ACTIVE_HIGH>;
+ sda-gpios = <&gpio2 22 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+
+ pca9534: gpio@20 {
+ compatible = "nxp,pca9534";
+ reg = <0x20>;
+ gpio-controller;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pca9534>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <26 IRQ_TYPE_EDGE_FALLING>;
+ #gpio-cells = <2>;
+ wakeup-source;
+ };
+};
+
+/* Console */
+&lpuart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1>;
+ status = "okay";
+};
+
+/* J18.7, J18.9 */
+&lpuart6 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart6>;
+ status = "okay";
+};
+
+/* SD */
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+ cd-gpios = <&gpio3 00 GPIO_ACTIVE_LOW>;
+ vmmc-supply = <&reg_usdhc2_vmmc>;
+ bus-width = <4>;
+ status = "okay";
+ no-sdio;
+ no-mmc;
+};
+
+/* Watchdog */
+&wdog3 {
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl_fec: fecgrp {
+ fsl,pins = <
+ MX93_PAD_ENET2_RD0__ENET1_RGMII_RD0 0x57e
+ MX93_PAD_ENET2_RD1__ENET1_RGMII_RD1 0x57e
+ MX93_PAD_ENET2_RD2__ENET1_RGMII_RD2 0x57e
+ MX93_PAD_ENET2_RD3__ENET1_RGMII_RD3 0x57e
+ MX93_PAD_ENET2_RXC__ENET1_RGMII_RXC 0x5fe
+ MX93_PAD_ENET2_RX_CTL__ENET1_RGMII_RX_CTL 0x57e
+ MX93_PAD_ENET2_TD0__ENET1_RGMII_TD0 0x57e
+ MX93_PAD_ENET2_TD1__ENET1_RGMII_TD1 0x57e
+ MX93_PAD_ENET2_TD2__ENET1_RGMII_TD2 0x57e
+ MX93_PAD_ENET2_TD3__ENET1_RGMII_TD3 0x57e
+ MX93_PAD_ENET2_TXC__ENET1_RGMII_TXC 0x5fe
+ MX93_PAD_ENET2_TX_CTL__ENET1_RGMII_TX_CTL 0x57e
+ >;
+ };
+
+ pinctrl_flexcan1: flexcan1grp {
+ fsl,pins = <
+ MX93_PAD_PDM_CLK__CAN1_TX 0x139e
+ MX93_PAD_PDM_BIT_STREAM0__CAN1_RX 0x139e
+ >;
+ };
+
+ pinctrl_lpi2c1: lpi2c1grp {
+ fsl,pins = <
+ MX93_PAD_I2C1_SCL__LPI2C1_SCL 0x40000b9e
+ MX93_PAD_I2C1_SDA__LPI2C1_SDA 0x40000b9e
+ >;
+ };
+
+ pinctrl_lpi2c1_gpio: lpi2c1gpiogrp {
+ fsl,pins = <
+ MX93_PAD_I2C1_SCL__GPIO1_IO00 0x31e
+ MX93_PAD_I2C1_SDA__GPIO1_IO01 0x31e
+ >;
+ };
+
+ pinctrl_lpi2c5: lpi2c5grp {
+ fsl,pins = <
+ MX93_PAD_GPIO_IO23__LPI2C5_SCL 0x40000b9e
+ MX93_PAD_GPIO_IO22__LPI2C5_SDA 0x40000b9e
+ >;
+ };
+
+ pinctrl_lpi2c5_gpio: lpi2c5gpiogrp {
+ fsl,pins = <
+ MX93_PAD_GPIO_IO23__GPIO2_IO23 0x31e
+ MX93_PAD_GPIO_IO22__GPIO2_IO22 0x31e
+ >;
+ };
+
+ pinctrl_pca9534: pca9534grp {
+ 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_uart6: uart6grp {
+ fsl,pins = <
+ MX93_PAD_GPIO_IO05__LPUART6_RX 0x31e
+ MX93_PAD_GPIO_IO04__LPUART6_TX 0x31e
+ >;
+ };
+
+ pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp {
+ fsl,pins = <
+ MX93_PAD_GPIO_IO18__GPIO2_IO18 0x31e
+ >;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <
+ MX93_PAD_SD2_CLK__USDHC2_CLK 0x15fe
+ MX93_PAD_SD2_CMD__USDHC2_CMD 0x13fe
+ MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x13fe
+ MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x13fe
+ MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x13fe
+ MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x13fe
+ MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e
+ >;
+ };
+
+ pinctrl_usdhc2_gpio: usdhc2gpiogrp {
+ fsl,pins = <
+ MX93_PAD_SD2_CD_B__GPIO3_IO00 0x31e
+ >;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx93-var-som.dtsi b/arch/arm64/boot/dts/freescale/imx93-var-som.dtsi
new file mode 100644
index 000000000000..783938245e4f
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx93-var-som.dtsi
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2022 NXP
+ * Copyright 2023 Variscite Ltd.
+ */
+
+/dts-v1/;
+
+#include "imx93.dtsi"
+
+/{
+ model = "Variscite VAR-SOM-MX93 module";
+ compatible = "variscite,var-som-mx93", "fsl,imx93";
+
+ mmc_pwrseq: mmc-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ post-power-on-delay-ms = <100>;
+ power-off-delay-us = <10000>;
+ reset-gpios = <&gpio4 14 GPIO_ACTIVE_LOW>, /* WIFI_RESET */
+ <&gpio3 7 GPIO_ACTIVE_LOW>; /* WIFI_PWR_EN */
+ };
+
+ reg_eqos_phy: regulator-eqos-phy {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_eqos_phy>;
+ regulator-name = "eth_phy_pwr";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ startup-delay-us = <100000>;
+ regulator-always-on;
+ };
+};
+
+&eqos {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_eqos>;
+ phy-mode = "rgmii";
+ phy-handle = <&ethphy0>;
+ status = "okay";
+
+ mdio {
+ compatible = "snps,dwmac-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <1000000>;
+
+ ethphy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ eee-broken-1000t;
+ };
+ };
+};
+
+/* eMMC */
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1>;
+ pinctrl-2 = <&pinctrl_usdhc1>;
+ bus-width = <8>;
+ non-removable;
+ 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 0x5fe
+ 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 0x5fe
+ MX93_PAD_ENET1_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x57e
+ >;
+ };
+
+ pinctrl_reg_eqos_phy: regeqosgrp {
+ fsl,pins = <
+ MX93_PAD_UART2_TXD__GPIO1_IO07 0x51e
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ MX93_PAD_SD1_CLK__USDHC1_CLK 0x15fe
+ MX93_PAD_SD1_CMD__USDHC1_CMD 0x13fe
+ MX93_PAD_SD1_DATA0__USDHC1_DATA0 0x13fe
+ MX93_PAD_SD1_DATA1__USDHC1_DATA1 0x13fe
+ MX93_PAD_SD1_DATA2__USDHC1_DATA2 0x13fe
+ MX93_PAD_SD1_DATA3__USDHC1_DATA3 0x13fe
+ MX93_PAD_SD1_DATA4__USDHC1_DATA4 0x13fe
+ MX93_PAD_SD1_DATA5__USDHC1_DATA5 0x13fe
+ MX93_PAD_SD1_DATA6__USDHC1_DATA6 0x13fe
+ MX93_PAD_SD1_DATA7__USDHC1_DATA7 0x13fe
+ MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x15fe
+ >;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx93.dtsi b/arch/arm64/boot/dts/freescale/imx93.dtsi
index 8f2e7c42ad6e..601c94e1fac8 100644
--- a/arch/arm64/boot/dts/freescale/imx93.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx93.dtsi
@@ -294,7 +294,7 @@
status = "disabled";
};
- i3c1: i3c-master@44330000 {
+ i3c1: i3c@44330000 {
compatible = "silvaco,i3c-master-v1";
reg = <0x44330000 0x10000>;
interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
@@ -671,7 +671,7 @@
status = "disabled";
};
- i3c2: i3c-master@42520000 {
+ i3c2: i3c@42520000 {
compatible = "silvaco,i3c-master-v1";
reg = <0x42520000 0x10000>;
interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm64/boot/dts/freescale/mba8mx.dtsi b/arch/arm64/boot/dts/freescale/mba8mx.dtsi
index e2bc53b8d39a..427467df42bf 100644
--- a/arch/arm64/boot/dts/freescale/mba8mx.dtsi
+++ b/arch/arm64/boot/dts/freescale/mba8mx.dtsi
@@ -29,6 +29,12 @@
stdout-path = &uart3;
};
+ clk_xtal25: clk-xtal25 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+
gpio-keys {
compatible = "gpio-keys";
pinctrl-names = "default";
@@ -100,12 +106,6 @@
};
};
- pcie0_refclk: pcie0-refclk {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <100000000>;
- };
-
reg_12v: regulator-12v {
compatible = "regulator-fixed";
regulator-name = "MBA8MX_12V";
@@ -219,7 +219,7 @@
line-name = "BOOT_CFG_OE#";
};
- rst-usb-hub-hog {
+ rst_usb_hub_hog: rst-usb-hub-hog {
gpio-hog;
gpios = <13 0>;
output-high;
@@ -264,6 +264,13 @@
pagesize = <16>;
vcc-supply = <&reg_vcc_3v3>;
};
+
+ pcieclk: clk@68 {
+ compatible = "renesas,9fgv0441";
+ reg = <0x68>;
+ clocks = <&clk_xtal25>;
+ #clock-cells = <1>;
+ };
};
&i2c3 {
diff --git a/arch/arm64/boot/dts/freescale/mba8xx.dtsi b/arch/arm64/boot/dts/freescale/mba8xx.dtsi
new file mode 100644
index 000000000000..276d1683b03b
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/mba8xx.dtsi
@@ -0,0 +1,554 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR X11)
+/*
+ * Copyright 2018-2023 TQ-Systems GmbH <linux@ew.tq-group.com>,
+ * D-82229 Seefeld, Germany.
+ * Author: Alexander Stein
+ */
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/net/ti-dp83867.h>
+
+/ {
+ adc {
+ compatible = "iio-hwmon";
+ io-channels = <&adc0 0>, <&adc0 1>, <&adc0 2>, <&adc0 3>;
+ };
+
+ aliases {
+ rtc0 = &pcf85063;
+ rtc1 = &rtc;
+ };
+
+ backlight_lvds: backlight-lvds {
+ compatible = "pwm-backlight";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_bl_lvds>;
+ pwms = <&adma_pwm 0 5000000 0>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <7>;
+ power-supply = <&reg_12v0>;
+ enable-gpios = <&lsio_gpio1 30 GPIO_ACTIVE_HIGH>;
+ status = "disabled";
+ };
+
+ chosen {
+ stdout-path = &lpuart1;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpiobuttons>;
+ autorepeat;
+
+ switch-a {
+ label = "switcha";
+ linux,code = <BTN_0>;
+ gpios = <&lsio_gpio1 13 GPIO_ACTIVE_LOW>;
+ };
+
+ switch-b {
+ label = "switchb";
+ linux,code = <BTN_1>;
+ gpios = <&lsio_gpio1 14 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ led1 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_STATUS;
+ gpios = <&expander 1 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-on";
+ };
+
+ led2 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_HEARTBEAT;
+ gpios = <&expander 2 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ /* TODO LVDS panels */
+
+ reg_12v0: regulator-12v0 {
+ compatible = "regulator-fixed";
+ regulator-name = "V_12V";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ gpio = <&expander 6 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_pcie_1v5: regulator-pcie-1v5 {
+ compatible = "regulator-fixed";
+ regulator-name = "MBA8XX_PCIE_1V5";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_pcie_1v5>;
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ gpio = <&lsio_gpio0 30 GPIO_ACTIVE_HIGH>;
+ startup-delay-us = <1000>;
+ enable-active-high;
+ };
+
+ reg_pcie_3v3: regulator-pcie-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "MBA8XX_PCIE_3V3";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_pcie_3v3>;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&lsio_gpio0 31 GPIO_ACTIVE_HIGH>;
+ startup-delay-us = <1000>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ reg_3v3_mb: regulator-usdhc2-vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "V_3V3_MB";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ sound {
+ compatible = "fsl,imx-audio-tlv320aic32x4";
+ model = "tqm-tlv320aic32";
+ audio-codec = <&tlv320aic3x04>;
+ ssi-controller = <&sai1>;
+ };
+};
+
+&adc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_adc0>;
+ vref-supply = <&reg_1v8>;
+ #io-channel-cells = <1>;
+ status = "okay";
+};
+
+&adma_pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_admapwm>;
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec1>;
+ phy-mode = "rgmii-id";
+ phy-handle = <&ethphy0>;
+ 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_ethphy0>;
+ 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>;
+ reset-gpios = <&lsio_gpio3 2 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <500000>;
+ reset-deassert-us = <50000>;
+ enet-phy-lane-no-swap;
+ interrupt-parent = <&lsio_gpio3>;
+ interrupts = <0 IRQ_TYPE_EDGE_FALLING>;
+ };
+
+ ethphy3: ethernet-phy@3 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ethphy3>;
+ 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>;
+ reset-gpios = <&lsio_gpio3 3 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <500000>;
+ reset-deassert-us = <50000>;
+ enet-phy-lane-no-swap;
+ interrupt-parent = <&lsio_gpio3>;
+ interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
+ };
+ };
+};
+
+&fec2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec2>;
+ phy-mode = "rgmii-id";
+ phy-handle = <&ethphy3>;
+ status = "okay";
+};
+
+&flexcan1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can0>;
+ xceiver-supply = <&reg_3v3>;
+ status = "okay";
+};
+
+&flexcan2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can1>;
+ xceiver-supply = <&reg_3v3>;
+ status = "okay";
+};
+
+&i2c1 {
+ tlv320aic3x04: audio-codec@18 {
+ compatible = "ti,tlv320aic32x4";
+ reg = <0x18>;
+ clocks = <&mclkout0_lpcg 0>;
+ clock-names = "mclk";
+ iov-supply = <&reg_1v8>;
+ ldoin-supply = <&reg_3v3>;
+ };
+
+ se97b_1c: temperature-sensor@1c {
+ compatible = "nxp,se97b", "jedec,jc-42.4-temp";
+ reg = <0x1c>;
+ };
+
+ at24c02_54: eeprom@54 {
+ compatible = "nxp,se97b", "atmel,24c02";
+ reg = <0x54>;
+ pagesize = <16>;
+ vcc-supply = <&reg_3v3>;
+ };
+
+ expander: gpio@70 {
+ compatible = "nxp,pca9538";
+ reg = <0x70>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pca9538>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&lsio_gpio4>;
+ interrupts = <19 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ vcc-supply = <&reg_1v8>;
+
+ gpio-line-names = "", "LED_A",
+ "LED_B", "",
+ "DSI_EN", "USB_RESET#",
+ "V_12V_EN", "PCIE_DIS#";
+ };
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_lpi2c2>;
+ pinctrl-1 = <&pinctrl_lpi2c2gpio>;
+ scl-gpios = <&lsio_gpio1 31 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&lsio_gpio2 0 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "okay";
+};
+
+/* TODO LDB */
+
+&lpspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi1>;
+ cs-gpios = <&lsio_gpio0 27 GPIO_ACTIVE_LOW>, <&lsio_gpio0 29 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&lpspi2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi2>;
+ cs-gpios = <&lsio_gpio1 0 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&lpspi3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi3>;
+ num-cs = <2>;
+ cs-gpios = <&lsio_gpio0 16 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&lpuart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart1>;
+ status = "okay";
+};
+
+&lpuart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart3>;
+ status = "okay";
+};
+
+&lsio_gpio3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lsgpio3>;
+ gpio-line-names = "", "", "", "",
+ "", "", "", "",
+ "", "", "", "",
+ "", "", "", "X4_15",
+ "", "", "", "",
+ "", "", "", "",
+ "", "", "", "",
+ "", "", "", "";
+};
+
+/* TODO: Mini-PCIe */
+
+&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 0>;
+ assigned-clock-rates = <786432000>, <49152000>, <12288000>, <49152000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai1>;
+ status = "okay";
+};
+
+&usbotg1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg1>;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ power-active-high;
+ over-current-active-low;
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&usbotg3 {
+ status = "okay";
+};
+
+&usbotg3_cdns3 {
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usbphy1 {
+ status = "okay";
+};
+
+&usb3_phy {
+ 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>;
+ bus-width = <4>;
+ cd-gpios = <&lsio_gpio4 22 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&lsio_gpio4 21 GPIO_ACTIVE_HIGH>;
+ vmmc-supply = <&reg_3v3_mb>;
+ no-1-8-v;
+ no-sdio;
+ no-mmc;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl_adc0: adc0grp {
+ fsl,pins = <IMX8QXP_ADC_IN0_ADMA_ADC_IN0 0x02000060>,
+ <IMX8QXP_ADC_IN1_ADMA_ADC_IN1 0x02000060>,
+ <IMX8QXP_ADC_IN2_ADMA_ADC_IN2 0x02000060>,
+ <IMX8QXP_ADC_IN3_ADMA_ADC_IN3 0x02000060>;
+ };
+
+ pinctrl_admapwm: admapwmgrp {
+ fsl,pins = <IMX8QXP_SPI0_CS1_ADMA_LCD_PWM0_OUT 0x00000021>;
+ };
+
+ pinctrl_bl_lvds: bllvdsgrp {
+ fsl,pins = <IMX8QXP_MIPI_DSI1_I2C0_SDA_LSIO_GPIO1_IO30 0x00000021>;
+ };
+
+ pinctrl_can0: can0grp {
+ fsl,pins = <IMX8QXP_UART0_RX_ADMA_FLEXCAN0_RX 0x00000021>,
+ <IMX8QXP_UART0_TX_ADMA_FLEXCAN0_TX 0x00000021>;
+ };
+
+ pinctrl_can1: can1grp {
+ fsl,pins = <IMX8QXP_UART2_RX_ADMA_FLEXCAN1_RX 0x00000021>,
+ <IMX8QXP_UART2_TX_ADMA_FLEXCAN1_TX 0x00000021>;
+ };
+
+ pinctrl_ethphy0: ethphy0grp {
+ fsl,pins = <IMX8QXP_CSI_EN_LSIO_GPIO3_IO02 0x00000040>,
+ <IMX8QXP_CSI_PCLK_LSIO_GPIO3_IO00 0x00000040>;
+ };
+
+ pinctrl_ethphy3: ethphy3grp {
+ fsl,pins = <IMX8QXP_CSI_RESET_LSIO_GPIO3_IO03 0x00000040>,
+ <IMX8QXP_CSI_MCLK_LSIO_GPIO3_IO01 0x00000040>;
+ };
+
+ pinctrl_fec1: fec1grp {
+ fsl,pins = <IMX8QXP_ENET0_MDC_CONN_ENET0_MDC 0x06000041>,
+ <IMX8QXP_ENET0_MDIO_CONN_ENET0_MDIO 0x06000041>,
+ <IMX8QXP_ENET0_RGMII_TX_CTL_CONN_ENET0_RGMII_TX_CTL 0x00000040>,
+ <IMX8QXP_ENET0_RGMII_TXC_CONN_ENET0_RGMII_TXC 0x00000040>,
+ <IMX8QXP_ENET0_RGMII_TXD0_CONN_ENET0_RGMII_TXD0 0x00000040>,
+ <IMX8QXP_ENET0_RGMII_TXD1_CONN_ENET0_RGMII_TXD1 0x00000040>,
+ <IMX8QXP_ENET0_RGMII_TXD2_CONN_ENET0_RGMII_TXD2 0x00000040>,
+ <IMX8QXP_ENET0_RGMII_TXD3_CONN_ENET0_RGMII_TXD3 0x00000040>,
+ <IMX8QXP_ENET0_RGMII_RX_CTL_CONN_ENET0_RGMII_RX_CTL 0x00000040>,
+ <IMX8QXP_ENET0_RGMII_RXC_CONN_ENET0_RGMII_RXC 0x00000040>,
+ <IMX8QXP_ENET0_RGMII_RXD0_CONN_ENET0_RGMII_RXD0 0x00000040>,
+ <IMX8QXP_ENET0_RGMII_RXD1_CONN_ENET0_RGMII_RXD1 0x00000040>,
+ <IMX8QXP_ENET0_RGMII_RXD2_CONN_ENET0_RGMII_RXD2 0x00000040>,
+ <IMX8QXP_ENET0_RGMII_RXD3_CONN_ENET0_RGMII_RXD3 0x00000040>;
+ };
+
+ pinctrl_fec2: fec2grp {
+ fsl,pins = <IMX8QXP_ESAI0_SCKR_CONN_ENET1_RGMII_TX_CTL 0x00000040>,
+ <IMX8QXP_ESAI0_FSR_CONN_ENET1_RGMII_TXC 0x00000040>,
+ <IMX8QXP_ESAI0_TX4_RX1_CONN_ENET1_RGMII_TXD0 0x00000040>,
+ <IMX8QXP_ESAI0_TX5_RX0_CONN_ENET1_RGMII_TXD1 0x00000040>,
+ <IMX8QXP_ESAI0_FST_CONN_ENET1_RGMII_TXD2 0x00000040>,
+ <IMX8QXP_ESAI0_SCKT_CONN_ENET1_RGMII_TXD3 0x00000040>,
+ <IMX8QXP_ESAI0_TX0_CONN_ENET1_RGMII_RXC 0x00000040>,
+ <IMX8QXP_SPDIF0_TX_CONN_ENET1_RGMII_RX_CTL 0x00000040>,
+ <IMX8QXP_SPDIF0_RX_CONN_ENET1_RGMII_RXD0 0x00000040>,
+ <IMX8QXP_ESAI0_TX3_RX2_CONN_ENET1_RGMII_RXD1 0x00000040>,
+ <IMX8QXP_ESAI0_TX2_RX3_CONN_ENET1_RGMII_RXD2 0x00000040>,
+ <IMX8QXP_ESAI0_TX1_CONN_ENET1_RGMII_RXD3 0x00000040>;
+ };
+
+ pinctrl_gpiobuttons: gpiobuttonsgrp {
+ fsl,pins = <IMX8QXP_ADC_IN5_LSIO_GPIO1_IO13 0x00000020>,
+ <IMX8QXP_ADC_IN4_LSIO_GPIO1_IO14 0x00000020>;
+ };
+
+ pinctrl_lpi2c2: lpi2c2grp {
+ fsl,pins = <IMX8QXP_MIPI_DSI1_GPIO0_00_ADMA_I2C2_SCL 0x06000021>,
+ <IMX8QXP_MIPI_DSI1_GPIO0_01_ADMA_I2C2_SDA 0x06000021>;
+ };
+
+ pinctrl_lpi2c2gpio: lpi2c2gpiogrp {
+ fsl,pins = <IMX8QXP_MIPI_DSI1_GPIO0_00_LSIO_GPIO1_IO31 0x06000021>,
+ <IMX8QXP_MIPI_DSI1_GPIO0_01_LSIO_GPIO2_IO00 0x06000021>;
+ };
+
+ pinctrl_lpuart1: lpuart1grp {
+ fsl,pins = <IMX8QXP_UART1_RX_ADMA_UART1_RX 0x06000020>,
+ <IMX8QXP_UART1_TX_ADMA_UART1_TX 0x06000020>;
+ };
+
+ pinctrl_lpuart3: lpuart3grp {
+ fsl,pins = <IMX8QXP_FLEXCAN2_RX_ADMA_UART3_RX 0x06000020>,
+ <IMX8QXP_FLEXCAN2_TX_ADMA_UART3_TX 0x06000020>;
+ };
+
+ pinctrl_lsgpio3: lsgpio3grp {
+ fsl,pins = <IMX8QXP_QSPI0A_SS1_B_LSIO_GPIO3_IO15 0x00000021>;
+ };
+
+ pinctrl_pca9538: pca9538grp {
+ fsl,pins = <IMX8QXP_USDHC1_RESET_B_LSIO_GPIO4_IO19 0x00000020>;
+ };
+
+ pinctrl_pcieb: pcieagrp {
+ fsl,pins = <IMX8QXP_PCIE_CTRL0_PERST_B_LSIO_GPIO4_IO00 0x06000041>,
+ <IMX8QXP_PCIE_CTRL0_CLKREQ_B_LSIO_GPIO4_IO01 0x06000041>,
+ <IMX8QXP_PCIE_CTRL0_WAKE_B_LSIO_GPIO4_IO02 0x04000041>;
+ };
+
+ pinctrl_reg_pcie_1v5: regpcie1v5grp {
+ fsl,pins = <IMX8QXP_SAI1_RXC_LSIO_GPIO0_IO30 0x00000021>;
+ };
+
+ pinctrl_reg_pcie_3v3: regpcie3v3grp {
+ fsl,pins = <IMX8QXP_SAI1_RXFS_LSIO_GPIO0_IO31 0x00000021>;
+ };
+
+ pinctrl_sai1: sai1grp {
+ fsl,pins = <IMX8QXP_MCLK_OUT0_ADMA_ACM_MCLK_OUT0 0x06000041>,
+ <IMX8QXP_FLEXCAN0_RX_ADMA_SAI1_TXC 0x06000041>,
+ <IMX8QXP_FLEXCAN0_TX_ADMA_SAI1_TXFS 0x06000041>,
+ <IMX8QXP_FLEXCAN1_RX_ADMA_SAI1_TXD 0x06000041>,
+ <IMX8QXP_FLEXCAN1_TX_ADMA_SAI1_RXD 0x06000041>;
+ };
+
+ pinctrl_spi1: spi1grp {
+ fsl,pins = <IMX8QXP_SAI0_TXC_ADMA_SPI1_SDI 0x00000041>,
+ <IMX8QXP_SAI0_TXD_ADMA_SPI1_SDO 0x00000041>,
+ <IMX8QXP_SAI0_TXFS_ADMA_SPI1_SCK 0x00000041>,
+ <IMX8QXP_SAI0_RXD_LSIO_GPIO0_IO27 0x00000021>,
+ <IMX8QXP_SAI1_RXD_LSIO_GPIO0_IO29 0x00000021>;
+ };
+
+ pinctrl_spi2: spi2grp {
+ fsl,pins = <IMX8QXP_SPI2_SCK_ADMA_SPI2_SCK 0x00000041>,
+ <IMX8QXP_SPI2_SDI_ADMA_SPI2_SDI 0x00000041>,
+ <IMX8QXP_SPI2_SDO_ADMA_SPI2_SDO 0x00000041>,
+ <IMX8QXP_SPI2_CS0_LSIO_GPIO1_IO00 0x00000021>;
+ };
+
+ pinctrl_spi3: spi3grp {
+ fsl,pins = <IMX8QXP_SPI3_SCK_ADMA_SPI3_SCK 0x00000041>,
+ <IMX8QXP_SPI3_SDI_ADMA_SPI3_SDI 0x00000041>,
+ <IMX8QXP_SPI3_SDO_ADMA_SPI3_SDO 0x00000041>,
+ <IMX8QXP_SPI3_CS0_LSIO_GPIO0_IO16 0x00000021>,
+ <IMX8QXP_SPI3_CS1_ADMA_SPI3_CS1 0x00000021>;
+ };
+
+ pinctrl_usbotg1: usbotg1grp {
+ fsl,pins = <IMX8QXP_USB_SS3_TC0_CONN_USB_OTG1_PWR 0x00000021>,
+ <IMX8QXP_USB_SS3_TC2_CONN_USB_OTG1_OC 0x00000021>;
+ };
+
+ pinctrl_usdhc2_gpio: usdhc2gpiogrp {
+ fsl,pins = <IMX8QXP_USDHC1_WP_LSIO_GPIO4_IO21 0x00000021>,
+ <IMX8QXP_USDHC1_CD_B_LSIO_GPIO4_IO22 0x00000021>;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <IMX8QXP_USDHC1_CLK_CONN_USDHC1_CLK 0x06000041>,
+ <IMX8QXP_USDHC1_CMD_CONN_USDHC1_CMD 0x00000021>,
+ <IMX8QXP_USDHC1_DATA0_CONN_USDHC1_DATA0 0x00000021>,
+ <IMX8QXP_USDHC1_DATA1_CONN_USDHC1_DATA1 0x00000021>,
+ <IMX8QXP_USDHC1_DATA2_CONN_USDHC1_DATA2 0x00000021>,
+ <IMX8QXP_USDHC1_DATA3_CONN_USDHC1_DATA3 0x00000021>,
+ <IMX8QXP_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x00000021>;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
+ fsl,pins = <IMX8QXP_USDHC1_CLK_CONN_USDHC1_CLK 0x06000040>,
+ <IMX8QXP_USDHC1_CMD_CONN_USDHC1_CMD 0x00000020>,
+ <IMX8QXP_USDHC1_DATA0_CONN_USDHC1_DATA0 0x00000020>,
+ <IMX8QXP_USDHC1_DATA1_CONN_USDHC1_DATA1 0x00000020>,
+ <IMX8QXP_USDHC1_DATA2_CONN_USDHC1_DATA2 0x00000020>,
+ <IMX8QXP_USDHC1_DATA3_CONN_USDHC1_DATA3 0x00000020>,
+ <IMX8QXP_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x00000020>;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
+ fsl,pins = <IMX8QXP_USDHC1_CLK_CONN_USDHC1_CLK 0x06000040>,
+ <IMX8QXP_USDHC1_CMD_CONN_USDHC1_CMD 0x00000020>,
+ <IMX8QXP_USDHC1_DATA0_CONN_USDHC1_DATA0 0x00000020>,
+ <IMX8QXP_USDHC1_DATA1_CONN_USDHC1_DATA1 0x00000020>,
+ <IMX8QXP_USDHC1_DATA2_CONN_USDHC1_DATA2 0x00000020>,
+ <IMX8QXP_USDHC1_DATA3_CONN_USDHC1_DATA3 0x00000020>,
+ <IMX8QXP_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x00000020>;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/tqma8xx.dtsi b/arch/arm64/boot/dts/freescale/tqma8xx.dtsi
new file mode 100644
index 000000000000..d98469a7c47c
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/tqma8xx.dtsi
@@ -0,0 +1,265 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR X11)
+/*
+ * Copyright 2018-2023 TQ-Systems GmbH <linux@ew.tq-group.com>,
+ * D-82229 Seefeld, Germany.
+ * Author: Alexander Stein
+ */
+
+/ {
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x00000000 0x80000000 0 0x40000000>;
+ };
+
+ reg_1v8: regulator-1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "V_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ reg_3v3: regulator-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "V_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ /*
+ * global autoconfigured region for contiguous allocations
+ * must not exceed memory size and region
+ */
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0 0x20000000>;
+ alloc-ranges = <0 0x96000000 0 0x30000000>;
+ linux,cma-default;
+ };
+ };
+};
+
+/* TQMa8Xx only uses industrial grade, reduce trip points accordingly */
+&cpu_alert0 {
+ temperature = <95000>;
+};
+
+&cpu_crit0 {
+ temperature = <100000>;
+};
+/* end of temperature grade adjustments */
+
+&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 = <66000000>;
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <4>;
+ };
+};
+
+/* TODO GPU */
+
+&i2c1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clock-frequency = <100000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_lpi2c1>;
+ pinctrl-1 = <&pinctrl_lpi2c1gpio>;
+ scl-gpios = <&lsio_gpio1 27 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&lsio_gpio1 28 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "okay";
+
+ se97: temperature-sensor@1b {
+ compatible = "nxp,se97b", "jedec,jc-42.4-temp";
+ reg = <0x1b>;
+ };
+
+ pcf85063: rtc@51 {
+ compatible = "nxp,pcf85063a";
+ reg = <0x51>;
+ quartz-load-femtofarads = <7000>;
+ };
+
+ at24c02: eeprom@53 {
+ compatible = "nxp,se97b", "atmel,24c02";
+ reg = <0x53>;
+ pagesize = <16>;
+ read-only;
+ vcc-supply = <&reg_3v3>;
+ };
+
+ m24c64: eeprom@57 {
+ compatible = "atmel,24c64";
+ reg = <0x57>;
+ pagesize = <32>;
+ vcc-supply = <&reg_3v3>;
+ };
+};
+
+&mu_m0 {
+ status = "okay";
+};
+
+&mu1_m0 {
+ status = "okay";
+};
+
+&thermal_zones {
+ pmic_thermal: pmic-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <2000>;
+ thermal-sensors = <&tsens IMX_SC_R_PMIC_0>;
+
+ trips {
+ pmic_alert0: trip0 {
+ temperature = <110000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ pmic_crit0: trip1 {
+ temperature = <125000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&pmic_alert0>;
+ cooling-device =
+ <&A35_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A35_1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A35_2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A35_3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ vqmmc-supply = <&reg_1v8>;
+ vmmc-supply = <&reg_3v3>;
+ bus-width = <8>;
+ non-removable;
+ no-sdio;
+ no-sd;
+ status = "okay";
+};
+
+&vpu {
+ compatible = "nxp,imx8qxp-vpu";
+ status = "okay";
+};
+
+&vpu_core0 {
+ memory-region = <&decoder_boot>, <&decoder_rpc>;
+ status = "okay";
+};
+
+&vpu_core1 {
+ memory-region = <&encoder_boot>, <&encoder_rpc>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl_flexspi0: flexspi0grp {
+ fsl,pins = <
+ IMX8QXP_QSPI0A_DATA0_LSIO_QSPI0A_DATA0 0x0600004d
+ IMX8QXP_QSPI0A_DATA1_LSIO_QSPI0A_DATA1 0x0600004d
+ IMX8QXP_QSPI0A_DATA2_LSIO_QSPI0A_DATA2 0x0600004d
+ IMX8QXP_QSPI0A_DATA3_LSIO_QSPI0A_DATA3 0x0600004d
+ IMX8QXP_QSPI0A_DQS_LSIO_QSPI0A_DQS 0x0600004d
+ IMX8QXP_QSPI0A_SS0_B_LSIO_QSPI0A_SS0_B 0x0600004d
+ IMX8QXP_QSPI0A_SCLK_LSIO_QSPI0A_SCLK 0x0600004d
+ IMX8QXP_QSPI0B_SCLK_LSIO_QSPI0B_SCLK 0x0600004d
+ IMX8QXP_QSPI0B_DATA0_LSIO_QSPI0B_DATA0 0x0600004d
+ IMX8QXP_QSPI0B_DATA1_LSIO_QSPI0B_DATA1 0x0600004d
+ IMX8QXP_QSPI0B_DATA2_LSIO_QSPI0B_DATA2 0x0600004d
+ IMX8QXP_QSPI0B_DATA3_LSIO_QSPI0B_DATA3 0x0600004d
+ IMX8QXP_QSPI0B_DQS_LSIO_QSPI0B_DQS 0x0600004d
+ IMX8QXP_QSPI0B_SS0_B_LSIO_QSPI0B_SS0_B 0x0600004d
+ IMX8QXP_QSPI0B_SS1_B_LSIO_QSPI0B_SS1_B 0x0600004d
+ >;
+ };
+
+ pinctrl_lpi2c1: lpi2c1grp {
+ fsl,pins = <
+ IMX8QXP_MIPI_DSI0_GPIO0_00_ADMA_I2C1_SCL 0x06000021
+ IMX8QXP_MIPI_DSI0_GPIO0_01_ADMA_I2C1_SDA 0x06000021
+ >;
+ };
+
+ pinctrl_lpi2c1gpio: lpi2c1gpiogrp {
+ fsl,pins = <
+ IMX8QXP_MIPI_DSI0_GPIO0_00_LSIO_GPIO1_IO27 0x06000021
+ IMX8QXP_MIPI_DSI0_GPIO0_01_LSIO_GPIO1_IO28 0x06000021
+ >;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <
+ IMX8QXP_EMMC0_CLK_CONN_EMMC0_CLK 0x06000041
+ IMX8QXP_EMMC0_CMD_CONN_EMMC0_CMD 0x00000021
+ IMX8QXP_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000021
+ IMX8QXP_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000021
+ IMX8QXP_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000021
+ IMX8QXP_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000021
+ IMX8QXP_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000021
+ IMX8QXP_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000021
+ IMX8QXP_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000021
+ IMX8QXP_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000021
+ IMX8QXP_EMMC0_STROBE_CONN_EMMC0_STROBE 0x00000041
+ >;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp {
+ fsl,pins = <
+ IMX8QXP_EMMC0_CLK_CONN_EMMC0_CLK 0x06000040
+ IMX8QXP_EMMC0_CMD_CONN_EMMC0_CMD 0x00000020
+ IMX8QXP_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000020
+ IMX8QXP_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000020
+ IMX8QXP_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000020
+ IMX8QXP_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000020
+ IMX8QXP_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000020
+ IMX8QXP_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000020
+ IMX8QXP_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000020
+ IMX8QXP_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000020
+ IMX8QXP_EMMC0_STROBE_CONN_EMMC0_STROBE 0x00000040
+ >;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp {
+ fsl,pins = <
+ IMX8QXP_EMMC0_CLK_CONN_EMMC0_CLK 0x06000040
+ IMX8QXP_EMMC0_CMD_CONN_EMMC0_CMD 0x00000020
+ IMX8QXP_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000020
+ IMX8QXP_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000020
+ IMX8QXP_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000020
+ IMX8QXP_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000020
+ IMX8QXP_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000020
+ IMX8QXP_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000020
+ IMX8QXP_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000020
+ IMX8QXP_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000020
+ IMX8QXP_EMMC0_STROBE_CONN_EMMC0_STROBE 0x00000040
+ >;
+ };
+};
diff --git a/arch/arm64/boot/dts/intel/socfpga_agilex5.dtsi b/arch/arm64/boot/dts/intel/socfpga_agilex5.dtsi
index d66d425e45b7..1162978329c1 100644
--- a/arch/arm64/boot/dts/intel/socfpga_agilex5.dtsi
+++ b/arch/arm64/boot/dts/intel/socfpga_agilex5.dtsi
@@ -202,7 +202,7 @@
status = "disabled";
};
- i3c0: i3c-master@10da0000 {
+ i3c0: i3c@10da0000 {
compatible = "snps,dw-i3c-master-1.00a";
reg = <0x10da0000 0x1000>;
#address-cells = <3>;
@@ -212,7 +212,7 @@
status = "disabled";
};
- i3c1: i3c-master@10da1000 {
+ i3c1: i3c@10da1000 {
compatible = "snps,dw-i3c-master-1.00a";
reg = <0x10da1000 0x1000>;
#address-cells = <3>;
diff --git a/arch/arm64/boot/dts/marvell/ac5-98dx25xx.dtsi b/arch/arm64/boot/dts/marvell/ac5-98dx25xx.dtsi
index b5e042b8e929..5591939e057b 100644
--- a/arch/arm64/boot/dts/marvell/ac5-98dx25xx.dtsi
+++ b/arch/arm64/boot/dts/marvell/ac5-98dx25xx.dtsi
@@ -77,7 +77,6 @@
#address-cells = <2>;
#size-cells = <2>;
ranges;
- dma-ranges;
internal-regs@7f000000 {
#address-cells = <1>;
@@ -204,6 +203,30 @@
};
};
+ mmc_dma: bus@80500000 {
+ compatible = "simple-bus";
+ ranges;
+ #address-cells = <0x2>;
+ #size-cells = <0x2>;
+ reg = <0x0 0x80500000 0x0 0x100000>;
+ dma-ranges = <0x0 0x0 0x2 0x0 0x0 0x80000000>;
+ dma-coherent;
+
+ sdhci: mmc@805c0000 {
+ compatible = "marvell,ac5-sdhci",
+ "marvell,armada-ap806-sdhci";
+ reg = <0x0 0x805c0000 0x0 0x1000>;
+ interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&emmc_clock>, <&cnm_clock>;
+ clock-names = "core", "axi";
+ bus-width = <8>;
+ non-removable;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+ mmc-hs400-1_8v;
+ };
+ };
+
/*
* Dedicated section for devices behind 32bit controllers so we
* can configure specific DMA mapping for them
@@ -335,5 +358,11 @@
#clock-cells = <0>;
clock-frequency = <400000000>;
};
+
+ emmc_clock: emmc-clock {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <400000000>;
+ };
};
};
diff --git a/arch/arm64/boot/dts/marvell/ac5-98dx35xx-rd.dts b/arch/arm64/boot/dts/marvell/ac5-98dx35xx-rd.dts
index f0ebdb84eec9..0c973d7a215a 100644
--- a/arch/arm64/boot/dts/marvell/ac5-98dx35xx-rd.dts
+++ b/arch/arm64/boot/dts/marvell/ac5-98dx35xx-rd.dts
@@ -99,3 +99,7 @@
};
};
};
+
+&sdhci {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
index e300145ad1a6..1cc3fa1c354d 100644
--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
@@ -431,14 +431,14 @@
crypto: crypto@90000 {
compatible = "inside-secure,safexcel-eip97ies";
reg = <0x90000 0x20000>;
- interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+ interrupts = <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>,
- <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "mem", "ring0", "ring1",
- "ring2", "ring3", "eip";
+ <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "ring0", "ring1", "ring2",
+ "ring3", "eip", "mem";
clocks = <&nb_periph_clk 15>;
};
diff --git a/arch/arm64/boot/dts/marvell/armada-ap807.dtsi b/arch/arm64/boot/dts/marvell/armada-ap807.dtsi
index 4a23f65d475f..a3328d05fc94 100644
--- a/arch/arm64/boot/dts/marvell/armada-ap807.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-ap807.dtsi
@@ -33,3 +33,6 @@
"marvell,armada-ap806-sdhci"; /* Backward compatibility */
};
+&ap_thermal {
+ compatible = "marvell,armada-ap807-thermal";
+};
diff --git a/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi b/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi
index 4ec1aae0a3a9..7e595ac80043 100644
--- a/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi
@@ -511,14 +511,14 @@
CP11X_LABEL(crypto): crypto@800000 {
compatible = "inside-secure,safexcel-eip197b";
reg = <0x800000 0x200000>;
- interrupts = <87 IRQ_TYPE_LEVEL_HIGH>,
- <88 IRQ_TYPE_LEVEL_HIGH>,
+ interrupts = <88 IRQ_TYPE_LEVEL_HIGH>,
<89 IRQ_TYPE_LEVEL_HIGH>,
<90 IRQ_TYPE_LEVEL_HIGH>,
<91 IRQ_TYPE_LEVEL_HIGH>,
- <92 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "mem", "ring0", "ring1",
- "ring2", "ring3", "eip";
+ <92 IRQ_TYPE_LEVEL_HIGH>,
+ <87 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "ring0", "ring1", "ring2", "ring3",
+ "eip", "mem";
clock-names = "core", "reg";
clocks = <&CP11X_LABEL(clk) 1 26>,
<&CP11X_LABEL(clk) 1 17>;
diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
index 1e6f91731e92..37b4ca3a87c9 100644
--- a/arch/arm64/boot/dts/mediatek/Makefile
+++ b/arch/arm64/boot/dts/mediatek/Makefile
@@ -8,6 +8,8 @@ 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-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-emmc.dtbo
dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-nand.dtbo
@@ -15,6 +17,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-nor.dtbo
dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-bananapi-bpi-r3-sd.dtbo
dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986a-rfb.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt7986b-rfb.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt7988a-bananapi-bpi-r4.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8167-pumpkin.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-elm-hana.dtb
@@ -49,6 +52,16 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku32.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku0.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku176.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-pumpkin.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393216.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393217.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393218.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-rusty-sku196608.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-steelix-sku131072.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-steelix-sku131073.dtb
+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-evb.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8188-evb.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8192-asurada-hayato-r1.dtb
@@ -63,4 +76,5 @@ 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) += mt8395-radxa-nio-12l.dtb
dtb-$(CONFIG_ARCH_MEDIATEK) += mt8516-pumpkin.dtb
diff --git a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
index fffdb7bbf889..0c38f7b51763 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
@@ -43,12 +43,12 @@
extcon_usb: extcon_iddig {
compatible = "linux,extcon-usb-gpio";
- id-gpio = <&pio 12 GPIO_ACTIVE_HIGH>;
+ id-gpios = <&pio 12 GPIO_ACTIVE_HIGH>;
};
extcon_usb1: extcon_iddig1 {
compatible = "linux,extcon-usb-gpio";
- id-gpio = <&pio 14 GPIO_ACTIVE_HIGH>;
+ id-gpios = <&pio 14 GPIO_ACTIVE_HIGH>;
};
usb_p0_vbus: regulator-usb-p0-vbus {
diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
index ed1a9d319415..6d218caa198c 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -261,7 +261,7 @@
#clock-cells = <1>;
};
- syscfg_pctl_a: syscfg_pctl_a@10005000 {
+ syscfg_pctl_a: syscon@10005000 {
compatible = "mediatek,mt2712-pctl-a-syscfg", "syscon";
reg = <0 0x10005000 0 0x1000>;
};
diff --git a/arch/arm64/boot/dts/mediatek/mt6797.dtsi b/arch/arm64/boot/dts/mediatek/mt6797.dtsi
index c3677d77e0a4..0e9d11b4585b 100644
--- a/arch/arm64/boot/dts/mediatek/mt6797.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt6797.dtsi
@@ -117,7 +117,7 @@
#clock-cells = <1>;
};
- infrasys: infracfg_ao@10001000 {
+ infrasys: syscon@10001000 {
compatible = "mediatek,mt6797-infracfg", "syscon";
reg = <0 0x10001000 0 0x1000>;
#clock-cells = <1>;
@@ -452,19 +452,19 @@
#clock-cells = <1>;
};
- imgsys: imgsys_config@15000000 {
+ imgsys: syscon@15000000 {
compatible = "mediatek,mt6797-imgsys", "syscon";
reg = <0 0x15000000 0 0x1000>;
#clock-cells = <1>;
};
- vdecsys: vdec_gcon@16000000 {
+ vdecsys: syscon@16000000 {
compatible = "mediatek,mt6797-vdecsys", "syscon";
reg = <0 0x16000000 0 0x10000>;
#clock-cells = <1>;
};
- vencsys: venc_gcon@17000000 {
+ vencsys: syscon@17000000 {
compatible = "mediatek,mt6797-vencsys", "syscon";
reg = <0 0x17000000 0 0x1000>;
#clock-cells = <1>;
diff --git a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
index a1f42048dcc7..224bb289660c 100644
--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
@@ -75,6 +75,7 @@
memory@40000000 {
reg = <0 0x40000000 0 0x40000000>;
+ device_type = "memory";
};
reg_1p8v: regulator-1p8v {
@@ -185,6 +186,18 @@
label = "lan3";
};
+ port@5 {
+ reg = <5>;
+ ethernet = <&gmac1>;
+ phy-mode = "rgmii";
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ pause;
+ };
+ };
+
port@6 {
reg = <6>;
label = "cpu";
diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
index 2dc1bdc74e21..41629769bdc8 100644
--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
@@ -57,6 +57,7 @@
memory@40000000 {
reg = <0 0x40000000 0 0x20000000>;
+ device_type = "memory";
};
reg_1p8v: regulator-1p8v {
@@ -117,6 +118,18 @@
};
};
+ gmac1: mac@1 {
+ compatible = "mediatek,eth-mac";
+ reg = <1>;
+ phy-mode = "rgmii";
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ pause;
+ };
+ };
+
mdio-bus {
#address-cells = <1>;
#size-cells = <0>;
@@ -155,6 +168,18 @@
label = "wan";
};
+ port@5 {
+ reg = <5>;
+ ethernet = <&gmac1>;
+ phy-mode = "rgmii";
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ pause;
+ };
+ };
+
port@6 {
reg = <6>;
label = "cpu";
diff --git a/arch/arm64/boot/dts/mediatek/mt7981b-xiaomi-ax3000t.dts b/arch/arm64/boot/dts/mediatek/mt7981b-xiaomi-ax3000t.dts
new file mode 100644
index 000000000000..a314c3e05e50
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt7981b-xiaomi-ax3000t.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+
+/dts-v1/;
+
+#include "mt7981b.dtsi"
+
+/ {
+ compatible = "xiaomi,ax3000t", "mediatek,mt7981b";
+ model = "Xiaomi AX3000T";
+
+ memory@40000000 {
+ reg = <0 0x40000000 0 0x10000000>;
+ device_type = "memory";
+ };
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt7981b.dtsi b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi
new file mode 100644
index 000000000000..4feff3d1c5f4
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt7981b.dtsi
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+
+#include <dt-bindings/clock/mediatek,mt7981-clk.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ compatible = "mediatek,mt7981b";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "arm,cortex-a53";
+ reg = <0x0>;
+ device_type = "cpu";
+ enable-method = "psci";
+ };
+
+ cpu@1 {
+ compatible = "arm,cortex-a53";
+ reg = <0x1>;
+ device_type = "cpu";
+ enable-method = "psci";
+ };
+ };
+
+ oscillator-40m {
+ compatible = "fixed-clock";
+ clock-frequency = <40000000>;
+ clock-output-names = "clkxtal";
+ #clock-cells = <0>;
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ };
+
+ soc {
+ compatible = "simple-bus";
+ ranges;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ gic: interrupt-controller@c000000 {
+ compatible = "arm,gic-v3";
+ reg = <0 0x0c000000 0 0x40000>, /* GICD */
+ <0 0x0c080000 0 0x200000>; /* GICR */
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ };
+
+ infracfg: clock-controller@10001000 {
+ compatible = "mediatek,mt7981-infracfg", "syscon";
+ reg = <0 0x10001000 0 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ clock-controller@1001b000 {
+ compatible = "mediatek,mt7981-topckgen", "syscon";
+ reg = <0 0x1001b000 0 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ clock-controller@1001e000 {
+ compatible = "mediatek,mt7981-apmixedsys";
+ reg = <0 0x1001e000 0 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ pwm@10048000 {
+ 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>;
+ clock-names = "top", "main", "pwm1", "pwm2", "pwm3";
+ #pwm-cells = <2>;
+ };
+
+ clock-controller@15000000 {
+ compatible = "mediatek,mt7981-ethsys", "syscon";
+ reg = <0 0x15000000 0 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+ };
+
+ 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>;
+ };
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-acelink-ew-7886cax.dts b/arch/arm64/boot/dts/mediatek/mt7986a-acelink-ew-7886cax.dts
new file mode 100644
index 000000000000..08b3b0827436
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt7986a-acelink-ew-7886cax.dts
@@ -0,0 +1,173 @@
+// 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 "mt7986a.dtsi"
+
+/ {
+ compatible = "acelink,ew-7886cax", "mediatek,mt7986a";
+ model = "Acelink EW-7886CAX";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@40000000 {
+ reg = <0 0x40000000 0 0x20000000>;
+ device_type = "memory";
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ key-restart {
+ label = "Reset";
+ gpios = <&pio 7 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&pio 18 GPIO_ACTIVE_HIGH>;
+ };
+
+ led-1 {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&pio 19 GPIO_ACTIVE_HIGH>;
+ };
+
+ led-2 {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_BLUE>;
+ gpios = <&pio 20 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&crypto {
+ status = "okay";
+};
+
+&eth {
+ status = "okay";
+
+ mac@1 {
+ compatible = "mediatek,eth-mac";
+ reg = <1>;
+ phy-mode = "2500base-x";
+ phy-handle = <&phy6>;
+ nvmem-cells = <&macaddr>;
+ nvmem-cell-names = "mac-address";
+ };
+
+ mdio-bus {
+ reset-gpios = <&pio 6 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <50000>;
+ reset-post-delay-us = <20000>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ phy6: phy@6 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <6>;
+ };
+ };
+};
+
+&pcie_phy {
+ status = "okay";
+};
+
+&spi0 {
+ status = "okay";
+
+ flash@0 {
+ compatible = "spi-nand";
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ spi-max-frequency = <52000000>;
+ spi-rx-bus-width = <4>;
+ spi-tx-bus-width = <4>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ reg = <0x0 0x100000>;
+ label = "bootloader";
+ read-only;
+ };
+
+ partition@100000 {
+ reg = <0x100000 0x80000>;
+ label = "u-boot-env";
+ };
+
+ partition@180000 {
+ compatible = "nvmem-cells";
+ reg = <0x180000 0x200000>;
+ label = "factory";
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ eeprom: eeprom@0 {
+ reg = <0x0 0x1000>;
+ };
+
+ macaddr: macaddr@4 {
+ reg = <0x4 0x6>;
+ };
+ };
+ };
+
+ partition@380000 {
+ reg = <0x380000 0x200000>;
+ label = "fip";
+ };
+
+ partition@580000 {
+ reg = <0x580000 0x4000000>;
+ label = "ubi";
+ };
+ };
+ };
+};
+
+&trng {
+ status = "okay";
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&watchdog {
+ status = "okay";
+};
+
+&wifi {
+ nvmem-cells = <&eeprom>;
+ nvmem-cell-names = "eeprom";
+ status = "okay";
+};
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 543c13385d6e..7b97c5c91bd0 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
@@ -15,7 +15,7 @@
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
- spi_nand: spi_nand@0 {
+ spi_nand: flash@0 {
compatible = "spi-nand";
reg = <0>;
spi-max-frequency = <10000000>;
diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
index d06d4af43cbf..e04b1c0c0ebb 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
@@ -43,7 +43,7 @@
#cooling-cells = <2>;
/* cooling level (0, 1, 2) - pwm inverted */
cooling-levels = <255 96 0>;
- pwms = <&pwm 0 10000 0>;
+ pwms = <&pwm 0 10000>;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts b/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
index 3ef371ca254e..5d8e3d3f6c20 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
@@ -65,6 +65,18 @@
};
};
+ gmac1: mac@1 {
+ compatible = "mediatek,eth-mac";
+ reg = <1>;
+ phy-mode = "rgmii";
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ pause;
+ };
+ };
+
mdio: mdio-bus {
#address-cells = <1>;
#size-cells = <0>;
@@ -237,12 +249,13 @@
pinctrl-0 = <&spi_flash_pins>;
cs-gpios = <0>, <0>;
status = "okay";
- spi_nand: spi_nand@0 {
+
+ spi_nand: flash@0 {
compatible = "spi-nand";
reg = <0>;
spi-max-frequency = <10000000>;
- spi-tx-buswidth = <4>;
- spi-rx-buswidth = <4>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
};
};
@@ -287,6 +300,18 @@
label = "lan4";
};
+ port@5 {
+ reg = <5>;
+ ethernet = <&gmac1>;
+ phy-mode = "rgmii";
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ pause;
+ };
+ };
+
port@6 {
reg = <6>;
label = "cpu";
diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
index fc751e049953..b3f416b9a7a4 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
@@ -16,49 +16,49 @@
#address-cells = <2>;
#size-cells = <2>;
- clk40m: oscillator-40m {
- compatible = "fixed-clock";
- clock-frequency = <40000000>;
- #clock-cells = <0>;
- clock-output-names = "clkxtal";
- };
-
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu0: cpu@0 {
- device_type = "cpu";
compatible = "arm,cortex-a53";
- enable-method = "psci";
reg = <0x0>;
+ device_type = "cpu";
+ enable-method = "psci";
#cooling-cells = <2>;
};
cpu1: cpu@1 {
- device_type = "cpu";
compatible = "arm,cortex-a53";
- enable-method = "psci";
reg = <0x1>;
+ device_type = "cpu";
+ enable-method = "psci";
#cooling-cells = <2>;
};
cpu2: cpu@2 {
- device_type = "cpu";
compatible = "arm,cortex-a53";
- enable-method = "psci";
reg = <0x2>;
+ device_type = "cpu";
+ enable-method = "psci";
#cooling-cells = <2>;
};
cpu3: cpu@3 {
- device_type = "cpu";
- enable-method = "psci";
compatible = "arm,cortex-a53";
reg = <0x3>;
+ device_type = "cpu";
+ enable-method = "psci";
#cooling-cells = <2>;
};
};
+ clk40m: oscillator-40m {
+ compatible = "fixed-clock";
+ clock-frequency = <40000000>;
+ #clock-cells = <0>;
+ clock-output-names = "clkxtal";
+ };
+
psci {
compatible = "arm,psci-0.2";
method = "smc";
@@ -121,38 +121,30 @@
};
- 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 {
- #address-cells = <2>;
- #size-cells = <2>;
compatible = "simple-bus";
ranges;
+ #address-cells = <2>;
+ #size-cells = <2>;
gic: interrupt-controller@c000000 {
compatible = "arm,gic-v3";
- #interrupt-cells = <3>;
- interrupt-parent = <&gic>;
- interrupt-controller;
reg = <0 0x0c000000 0 0x10000>, /* GICD */
<0 0x0c080000 0 0x80000>, /* GICR */
<0 0x0c400000 0 0x2000>, /* GICC */
<0 0x0c410000 0 0x1000>, /* GICH */
<0 0x0c420000 0 0x2000>; /* GICV */
+ interrupt-parent = <&gic>;
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
};
infracfg: infracfg@10001000 {
compatible = "mediatek,mt7986-infracfg", "syscon";
reg = <0 0x10001000 0 0x1000>;
#clock-cells = <1>;
+ #reset-cells = <1>;
};
wed_pcie: wed-pcie@10003000 {
@@ -202,6 +194,19 @@
#interrupt-cells = <2>;
};
+ pwm: pwm@10048000 {
+ compatible = "mediatek,mt7986-pwm";
+ reg = <0 0x10048000 0 0x1000>;
+ #pwm-cells = <2>;
+ interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&topckgen CLK_TOP_PWM_SEL>,
+ <&infracfg CLK_INFRA_PWM_STA>,
+ <&infracfg CLK_INFRA_PWM1_CK>,
+ <&infracfg CLK_INFRA_PWM2_CK>;
+ clock-names = "top", "main", "pwm1", "pwm2";
+ status = "disabled";
+ };
+
sgmiisys0: syscon@10060000 {
compatible = "mediatek,mt7986-sgmiisys_0",
"syscon";
@@ -234,26 +239,11 @@
<GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "ring0", "ring1", "ring2", "ring3";
clocks = <&infracfg CLK_INFRA_EIP97_CK>;
- clock-names = "infra_eip97_ck";
assigned-clocks = <&topckgen CLK_TOP_EIP_B_SEL>;
assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>;
status = "disabled";
};
- pwm: pwm@10048000 {
- compatible = "mediatek,mt7986-pwm";
- reg = <0 0x10048000 0 0x1000>;
- #clock-cells = <1>;
- #pwm-cells = <2>;
- interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&topckgen CLK_TOP_PWM_SEL>,
- <&infracfg CLK_INFRA_PWM_STA>,
- <&infracfg CLK_INFRA_PWM1_CK>,
- <&infracfg CLK_INFRA_PWM2_CK>;
- clock-names = "top", "main", "pwm1", "pwm2";
- status = "disabled";
- };
-
uart0: serial@11002000 {
compatible = "mediatek,mt7986-uart",
"mediatek,mt6577-uart";
@@ -311,9 +301,9 @@
spi0: spi@1100a000 {
compatible = "mediatek,mt7986-spi-ipm", "mediatek,spi-ipm";
+ reg = <0 0x1100a000 0 0x100>;
#address-cells = <1>;
#size-cells = <0>;
- reg = <0 0x1100a000 0 0x100>;
interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&topckgen CLK_TOP_MPLL_D2>,
<&topckgen CLK_TOP_SPI_SEL>,
@@ -325,9 +315,9 @@
spi1: spi@1100b000 {
compatible = "mediatek,mt7986-spi-ipm", "mediatek,spi-ipm";
+ reg = <0 0x1100b000 0 0x100>;
#address-cells = <1>;
#size-cells = <0>;
- reg = <0 0x1100b000 0 0x100>;
interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&topckgen CLK_TOP_MPLL_D2>,
<&topckgen CLK_TOP_SPIM_MST_SEL>,
@@ -337,6 +327,21 @@
status = "disabled";
};
+ thermal: thermal@1100c800 {
+ compatible = "mediatek,mt7986-thermal";
+ reg = <0 0x1100c800 0 0x800>;
+ interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&infracfg CLK_INFRA_THERM_CK>,
+ <&infracfg CLK_INFRA_ADC_26M_CK>,
+ <&infracfg CLK_INFRA_ADC_FRC_CK>;
+ clock-names = "therm", "auxadc", "adc_32k";
+ nvmem-cells = <&thermal_calibration>;
+ nvmem-cell-names = "calibration-data";
+ #thermal-sensor-cells = <1>;
+ mediatek,auxadc = <&auxadc>;
+ mediatek,apmixedsys = <&apmixedsys>;
+ };
+
auxadc: adc@1100d000 {
compatible = "mediatek,mt7986-auxadc";
reg = <0 0x1100d000 0 0x1000>;
@@ -388,39 +393,23 @@
status = "disabled";
};
- thermal: thermal@1100c800 {
- #thermal-sensor-cells = <1>;
- compatible = "mediatek,mt7986-thermal";
- reg = <0 0x1100c800 0 0x800>;
- interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&infracfg CLK_INFRA_THERM_CK>,
- <&infracfg CLK_INFRA_ADC_26M_CK>,
- <&infracfg CLK_INFRA_ADC_FRC_CK>;
- clock-names = "therm", "auxadc", "adc_32k";
- mediatek,auxadc = <&auxadc>;
- mediatek,apmixedsys = <&apmixedsys>;
- nvmem-cells = <&thermal_calibration>;
- nvmem-cell-names = "calibration-data";
- };
-
pcie: pcie@11280000 {
compatible = "mediatek,mt7986-pcie",
"mediatek,mt8192-pcie";
+ reg = <0x00 0x11280000 0x00 0x4000>;
+ reg-names = "pcie-mac";
+ ranges = <0x82000000 0x00 0x20000000 0x00
+ 0x20000000 0x00 0x10000000>;
device_type = "pci";
#address-cells = <3>;
#size-cells = <2>;
- reg = <0x00 0x11280000 0x00 0x4000>;
- reg-names = "pcie-mac";
interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
bus-range = <0x00 0xff>;
- ranges = <0x82000000 0x00 0x20000000 0x00
- 0x20000000 0x00 0x10000000>;
clocks = <&infracfg CLK_INFRA_IPCIE_PIPE_CK>,
<&infracfg CLK_INFRA_IPCIE_CK>,
<&infracfg CLK_INFRA_IPCIER_CK>,
<&infracfg CLK_INFRA_IPCIEB_CK>;
clock-names = "pl_250m", "tl_26m", "peri_26m", "top_133m";
- status = "disabled";
phys = <&pcie_port PHY_TYPE_PCIE>;
phy-names = "pcie-phy";
@@ -431,6 +420,8 @@
<0 0 0 2 &pcie_intc 1>,
<0 0 0 3 &pcie_intc 2>,
<0 0 0 4 &pcie_intc 3>;
+ status = "disabled";
+
pcie_intc: interrupt-controller {
#address-cells = <0>;
#interrupt-cells = <1>;
@@ -441,9 +432,9 @@
pcie_phy: t-phy {
compatible = "mediatek,mt7986-tphy",
"mediatek,generic-tphy-v2";
+ ranges;
#address-cells = <2>;
#size-cells = <2>;
- ranges;
status = "disabled";
pcie_port: pcie-phy@11c00000 {
@@ -468,9 +459,9 @@
usb_phy: t-phy@11e10000 {
compatible = "mediatek,mt7986-tphy",
"mediatek,generic-tphy-v2";
+ ranges = <0 0 0x11e10000 0x1700>;
#address-cells = <1>;
#size-cells = <1>;
- ranges = <0 0 0x11e10000 0x1700>;
status = "disabled";
u2port0: usb-phy@0 {
@@ -498,11 +489,11 @@
};
ethsys: syscon@15000000 {
- #address-cells = <1>;
- #size-cells = <1>;
compatible = "mediatek,mt7986-ethsys",
"syscon";
reg = <0 0x15000000 0 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
#clock-cells = <1>;
#reset-cells = <1>;
};
@@ -533,20 +524,6 @@
mediatek,wo-ccif = <&wo_ccif1>;
};
- wo_ccif0: syscon@151a5000 {
- compatible = "mediatek,mt7986-wo-ccif", "syscon";
- reg = <0 0x151a5000 0 0x1000>;
- interrupt-parent = <&gic>;
- interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>;
- };
-
- wo_ccif1: syscon@151ad000 {
- compatible = "mediatek,mt7986-wo-ccif", "syscon";
- reg = <0 0x151ad000 0 0x1000>;
- interrupt-parent = <&gic>;
- interrupts = <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>;
- };
-
eth: ethernet@15100000 {
compatible = "mediatek,mt7986-eth";
reg = <0 0x15100000 0 0x80000>;
@@ -579,26 +556,40 @@
<&topckgen CLK_TOP_SGM_325M_SEL>;
assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>,
<&apmixedsys CLK_APMIXED_SGMPLL>;
+ #reset-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
mediatek,ethsys = <&ethsys>;
mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>;
mediatek,wed-pcie = <&wed_pcie>;
mediatek,wed = <&wed0>, <&wed1>;
- #reset-cells = <1>;
- #address-cells = <1>;
- #size-cells = <0>;
status = "disabled";
};
+ wo_ccif0: syscon@151a5000 {
+ compatible = "mediatek,mt7986-wo-ccif", "syscon";
+ reg = <0 0x151a5000 0 0x1000>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ wo_ccif1: syscon@151ad000 {
+ compatible = "mediatek,mt7986-wo-ccif", "syscon";
+ reg = <0 0x151ad000 0 0x1000>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
wifi: wifi@18000000 {
compatible = "mediatek,mt7986-wmac";
+ reg = <0 0x18000000 0 0x1000000>,
+ <0 0x10003000 0 0x1000>,
+ <0 0x11d10000 0 0x1000>;
resets = <&watchdog MT7986_TOPRGU_CONSYS_SW_RST>;
reset-names = "consys";
clocks = <&topckgen CLK_TOP_CONN_MCUSYS_SEL>,
<&topckgen CLK_TOP_AP2CNN_HOST_SEL>;
clock-names = "mcu", "ap2conn";
- 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>,
@@ -646,4 +637,13 @@
};
};
};
+
+ 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>;
+ };
};
diff --git a/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts b/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
index dde190442e38..58f77d932429 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
@@ -45,6 +45,18 @@
};
};
+ gmac1: mac@1 {
+ compatible = "mediatek,eth-mac";
+ reg = <1>;
+ phy-mode = "rgmii";
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ pause;
+ };
+ };
+
mdio: mdio-bus {
#address-cells = <1>;
#size-cells = <0>;
@@ -83,6 +95,18 @@
label = "lan4";
};
+ port@5 {
+ reg = <5>;
+ ethernet = <&gmac1>;
+ phy-mode = "rgmii";
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ pause;
+ };
+ };
+
port@6 {
reg = <6>;
label = "cpu";
@@ -152,12 +176,13 @@
pinctrl-0 = <&spi_flash_pins>;
cs-gpios = <0>, <0>;
status = "okay";
- spi_nand: spi_nand@0 {
+
+ spi_nand: flash@0 {
compatible = "spi-nand";
reg = <0>;
spi-max-frequency = <10000000>;
- spi-tx-buswidth = <4>;
- spi-rx-buswidth = <4>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
};
};
diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
new file mode 100644
index 000000000000..efc4ad0b08b8
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dts
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+
+/dts-v1/;
+
+#include "mt7988a.dtsi"
+
+/ {
+ compatible = "bananapi,bpi-r4", "mediatek,mt7988a";
+ model = "Banana Pi BPI-R4";
+ chassis-type = "embedded";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt7988a.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
new file mode 100644
index 000000000000..bba97de4fb44
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt7988a.dtsi
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ compatible = "mediatek,mt7988a";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "arm,cortex-a73";
+ reg = <0x0>;
+ device_type = "cpu";
+ enable-method = "psci";
+ };
+
+ cpu@1 {
+ compatible = "arm,cortex-a73";
+ reg = <0x1>;
+ device_type = "cpu";
+ enable-method = "psci";
+ };
+
+ cpu@2 {
+ compatible = "arm,cortex-a73";
+ reg = <0x2>;
+ device_type = "cpu";
+ enable-method = "psci";
+ };
+
+ cpu@3 {
+ compatible = "arm,cortex-a73";
+ reg = <0x3>;
+ device_type = "cpu";
+ enable-method = "psci";
+ };
+ };
+
+ oscillator-40m {
+ compatible = "fixed-clock";
+ clock-frequency = <40000000>;
+ #clock-cells = <0>;
+ clock-output-names = "clkxtal";
+ };
+
+ pmu {
+ compatible = "arm,cortex-a73-pmu";
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ psci {
+ compatible = "arm,psci-0.2";
+ method = "smc";
+ };
+
+ soc {
+ compatible = "simple-bus";
+ ranges;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ gic: interrupt-controller@c000000 {
+ compatible = "arm,gic-v3";
+ reg = <0 0x0c000000 0 0x40000>, /* GICD */
+ <0 0x0c080000 0 0x200000>, /* GICR */
+ <0 0x0c400000 0 0x2000>, /* GICC */
+ <0 0x0c410000 0 0x1000>, /* GICH */
+ <0 0x0c420000 0 0x2000>; /* GICV */
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ };
+
+ clock-controller@10001000 {
+ compatible = "mediatek,mt7988-infracfg", "syscon";
+ reg = <0 0x10001000 0 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ clock-controller@1001b000 {
+ compatible = "mediatek,mt7988-topckgen", "syscon";
+ reg = <0 0x1001b000 0 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ watchdog: watchdog@1001c000 {
+ compatible = "mediatek,mt7988-wdt";
+ reg = <0 0x1001c000 0 0x1000>;
+ interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+ #reset-cells = <1>;
+ };
+
+ clock-controller@1001e000 {
+ compatible = "mediatek,mt7988-apmixedsys";
+ reg = <0 0x1001e000 0 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ clock-controller@11f40000 {
+ compatible = "mediatek,mt7988-xfi-pll";
+ reg = <0 0x11f40000 0 0x1000>;
+ resets = <&watchdog 16>;
+ #clock-cells = <1>;
+ };
+
+ clock-controller@15000000 {
+ compatible = "mediatek,mt7988-ethsys", "syscon";
+ reg = <0 0x15000000 0 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ clock-controller@15031000 {
+ compatible = "mediatek,mt7988-ethwarp";
+ reg = <0 0x15031000 0 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+ };
+
+ 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>;
+ };
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dts b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dts
index 256f245ac01d..1c9fc791bdfc 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana-rev7.dts
@@ -14,7 +14,7 @@
&cpu_thermal {
trips {
- cpu_crit: cpu_crit0 {
+ cpu_crit: cpu-crit0 {
temperature = <100000>;
type = "critical";
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
index 8d614ac2c58e..6d962d437e02 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
@@ -1135,7 +1135,7 @@
compatible = "mediatek,mt6397-rtc";
};
- syscfg_pctl_pmic: syscfg_pctl_pmic@c000 {
+ syscfg_pctl_pmic: syscon@c000 {
compatible = "mediatek,mt6397-pctl-pmic-syscfg",
"syscon";
reg = <0 0x0000c000 0 0x0108>;
@@ -1155,6 +1155,7 @@
spi-max-frequency = <12000000>;
interrupts-extended = <&pio 0 IRQ_TYPE_LEVEL_LOW>;
google,cros-ec-spi-msg-delay = <500>;
+ wakeup-source;
i2c_tunnel: i2c-tunnel0 {
compatible = "google,cros-ec-i2c-tunnel";
diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index 0e5c628d1ec3..3fab21f59d18 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -41,7 +41,7 @@
extcon_usb: extcon_iddig {
compatible = "linux,extcon-usb-gpio";
- id-gpio = <&pio 16 GPIO_ACTIVE_HIGH>;
+ id-gpios = <&pio 16 GPIO_ACTIVE_HIGH>;
};
usb_p1_vbus: regulator-usb-p1 {
diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index cac4cd0a0320..3458be7f7f61 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -222,14 +222,14 @@
};
};
- pmu_a53 {
+ pmu-a53 {
compatible = "arm,cortex-a53-pmu";
interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_LOW>,
<GIC_SPI 9 IRQ_TYPE_LEVEL_LOW>;
interrupt-affinity = <&cpu0>, <&cpu1>;
};
- pmu_a72 {
+ pmu-a72 {
compatible = "arm,cortex-a72-pmu";
interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_LOW>,
<GIC_SPI 13 IRQ_TYPE_LEVEL_LOW>;
@@ -286,7 +286,7 @@
type = "passive";
};
- cpu_crit: cpu_crit0 {
+ cpu_crit: cpu-crit0 {
temperature = <115000>;
hysteresis = <2000>;
type = "critical";
@@ -318,7 +318,7 @@
#address-cells = <2>;
#size-cells = <2>;
ranges;
- vpu_dma_reserved: vpu_dma_mem_region@b7000000 {
+ vpu_dma_reserved: vpu-dma-mem@b7000000 {
compatible = "shared-dma-pool";
reg = <0 0xb7000000 0 0x500000>;
alignment = <0x1000>;
@@ -366,7 +366,7 @@
#reset-cells = <1>;
};
- syscfg_pctl_a: syscfg_pctl_a@10005000 {
+ syscfg_pctl_a: syscon@10005000 {
compatible = "mediatek,mt8173-pctl-a-syscfg", "syscon";
reg = <0 0x10005000 0 0x1000>;
};
@@ -590,6 +590,15 @@
reg = <0 0x10206000 0 0x1000>;
#address-cells = <1>;
#size-cells = <1>;
+
+ socinfo-data1@40 {
+ reg = <0x040 0x4>;
+ };
+
+ socinfo-data2@44 {
+ reg = <0x044 0x4>;
+ };
+
thermal_calibration: calib@528 {
reg = <0x528 0xc>;
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dtsi
index b6a9830af269..bfb9e42c8aca 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dtsi
@@ -360,6 +360,10 @@
};
&cros_ec {
+ cbas {
+ compatible = "google,cros-cbas";
+ };
+
keyboard-controller {
compatible = "google,cros-ec-keyb-switches";
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi
index 306c95166f3f..5c1bf6a1e475 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi
@@ -339,6 +339,10 @@
};
&cros_ec {
+ cbas {
+ compatible = "google,cros-cbas";
+ };
+
keyboard-controller {
compatible = "google,cros-ec-keyb-switches";
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi
index 382e4c6d7191..0f5fa893a774 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi
@@ -343,6 +343,10 @@
};
&cros_ec {
+ cbas {
+ compatible = "google,cros-cbas";
+ };
+
keyboard-controller {
compatible = "google,cros-ec-keyb-switches";
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
index 1b3396b1cee3..6bd7424ef66c 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
@@ -924,6 +924,7 @@
interrupts-extended = <&pio 151 IRQ_TYPE_LEVEL_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&ec_ap_int_odl>;
+ wakeup-source;
i2c_tunnel: i2c-tunnel {
compatible = "google,cros-ec-i2c-tunnel";
@@ -937,10 +938,6 @@
google,usb-port-id = <0>;
};
- cbas {
- compatible = "google,cros-cbas";
- };
-
typec {
compatible = "google,cros-ec-typec";
#address-cells = <1>;
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts b/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts
index 76449b4cf236..333c516af490 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8183-pumpkin.dts
@@ -33,7 +33,7 @@
#size-cells = <2>;
ranges;
- scp_mem_reserved: scp_mem_region@50000000 {
+ scp_mem_reserved: scp-mem@50000000 {
compatible = "shared-dma-pool";
reg = <0 0x50000000 0 0x2900000>;
no-map;
diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index 920ee415ef5f..93dfbf130231 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -1585,6 +1585,15 @@
reg = <0 0x11f10000 0 0x1000>;
#address-cells = <1>;
#size-cells = <1>;
+
+ socinfo-data1@4c {
+ reg = <0x04c 0x4>;
+ };
+
+ socinfo-data2@60 {
+ reg = <0x060 0x4>;
+ };
+
thermal_calibration: calib@180 {
reg = <0x180 0xc>;
};
@@ -1955,7 +1964,7 @@
power-domains = <&spm MT8183_POWER_DOMAIN_VENC>;
};
- venc_jpg: venc_jpg@17030000 {
+ venc_jpg: jpeg-encoder@17030000 {
compatible = "mediatek,mt8183-jpgenc", "mediatek,mtk-jpgenc";
reg = <0 0x17030000 0 0x1000>;
interrupts = <GIC_SPI 249 IRQ_TYPE_LEVEL_LOW>;
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-krabby.dtsi b/arch/arm64/boot/dts/mediatek/mt8186-corsola-krabby.dtsi
new file mode 100644
index 000000000000..7c971198fa95
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-krabby.dtsi
@@ -0,0 +1,129 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2022 Google LLC
+ */
+
+/dts-v1/;
+#include "mt8186-corsola.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ aliases {
+ i2c4 = &i2c4;
+ };
+};
+
+&dsi_out {
+ remote-endpoint = <&ps8640_in>;
+};
+
+&i2c0 {
+ clock-frequency = <400000>;
+
+ edp-bridge@8 {
+ compatible = "parade,ps8640";
+ reg = <0x8>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ps8640_pins>;
+ powerdown-gpios = <&pio 96 GPIO_ACTIVE_LOW>;
+ reset-gpios = <&pio 98 GPIO_ACTIVE_LOW>;
+ vdd12-supply = <&mt6366_vrf12_reg>;
+ vdd33-supply = <&mt6366_vcn33_reg>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ ps8640_in: endpoint {
+ remote-endpoint = <&dsi_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ ps8640_out: endpoint {
+ remote-endpoint = <&panel_in>;
+ };
+ };
+ };
+
+ aux-bus {
+ panel {
+ compatible = "edp-panel";
+ power-supply = <&pp3300_disp_x>;
+ backlight = <&backlight_lcd0>;
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&ps8640_out>;
+ };
+ };
+ };
+ };
+ };
+};
+
+&i2c1 {
+ i2c-scl-internal-delay-ns = <10000>;
+
+ touchscreen: touchscreen@10 {
+ compatible = "hid-over-i2c";
+ reg = <0x10>;
+ interrupts-extended = <&pio 12 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&touchscreen_pins>;
+ post-power-on-delay-ms = <10>;
+ hid-descr-addr = <0x0001>;
+ vdd-supply = <&pp3300_s3>;
+ };
+};
+
+&i2c4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_pins>;
+ clock-frequency = <400000>;
+ status = "okay";
+
+ proximity@28 {
+ compatible = "semtech,sx9324";
+ reg = <0x28>;
+ #io-channel-cells = <1>;
+ interrupts-extended = <&pio 5 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sar_sensor_pins>;
+ vdd-supply = <&mt6366_vio18_reg>;
+ svdd-supply = <&mt6366_vio18_reg>;
+ };
+};
+
+&pio {
+ i2c4_pins: i2c4-pins {
+ pins-bus {
+ pinmux = <PINMUX_GPIO136__FUNC_SDA4>,
+ <PINMUX_GPIO135__FUNC_SCL4>;
+ bias-disable;
+ drive-strength = <4>;
+ input-enable;
+ };
+ };
+
+ ps8640_pins: ps8640-pins {
+ pins-pwrdn-rst {
+ pinmux = <PINMUX_GPIO96__FUNC_GPIO96>,
+ <PINMUX_GPIO98__FUNC_GPIO98>;
+ output-low;
+ };
+ };
+
+ sar_sensor_pins: sar-sensor-pins {
+ pins-irq {
+ pinmux = <PINMUX_GPIO5__FUNC_GPIO5>;
+ input-enable;
+ bias-pull-up;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-magneton-sku393216.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-magneton-sku393216.dts
new file mode 100644
index 000000000000..c9673381ad3b
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-magneton-sku393216.dts
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2022 Google LLC
+ */
+
+/dts-v1/;
+#include "mt8186-corsola-steelix.dtsi"
+
+/ {
+ model = "Google Magneton board";
+ compatible = "google,steelix-sku393219", "google,steelix-sku393216",
+ "google,steelix", "mediatek,mt8186";
+ chassis-type = "laptop";
+};
+
+&gpio_keys {
+ status = "disabled";
+};
+
+&i2c1 {
+ touchscreen@10 {
+ compatible = "hid-over-i2c";
+ reg = <0x10>;
+ interrupts-extended = <&pio 12 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&touchscreen_pins>;
+ vdd-supply = <&pp3300_s3>;
+ post-power-on-delay-ms = <350>;
+ hid-descr-addr = <0x0001>;
+ };
+};
+
+&touchscreen {
+ status = "disabled";
+};
+
+&usb_c1 {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-magneton-sku393217.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-magneton-sku393217.dts
new file mode 100644
index 000000000000..28e3bbe56421
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-magneton-sku393217.dts
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2022 Google LLC
+ */
+
+/dts-v1/;
+#include "mt8186-corsola-steelix.dtsi"
+
+/ {
+ model = "Google Magneton board";
+ compatible = "google,steelix-sku393220", "google,steelix-sku393217",
+ "google,steelix", "mediatek,mt8186";
+ chassis-type = "laptop";
+};
+
+&gpio_keys {
+ status = "disabled";
+};
+
+&i2c1 {
+ touchscreen@40 {
+ compatible = "hid-over-i2c";
+ reg = <0x40>;
+ interrupts-extended = <&pio 12 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&touchscreen_pins>;
+ vdd-supply = <&pp3300_s3>;
+ post-power-on-delay-ms = <450>;
+ hid-descr-addr = <0x0001>;
+ };
+};
+
+&touchscreen {
+ status = "disabled";
+};
+
+&usb_c1 {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-magneton-sku393218.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-magneton-sku393218.dts
new file mode 100644
index 000000000000..332894218f07
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-magneton-sku393218.dts
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2022 Google LLC
+ */
+
+/dts-v1/;
+#include "mt8186-corsola-steelix.dtsi"
+
+/ {
+ model = "Google Magneton board";
+ compatible = "google,steelix-sku393221", "google,steelix-sku393218",
+ "google,steelix", "mediatek,mt8186";
+ chassis-type = "laptop";
+};
+
+&gpio_keys {
+ status = "disabled";
+};
+
+&touchscreen {
+ status = "disabled";
+};
+
+&usb_c1 {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-rusty-sku196608.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-rusty-sku196608.dts
new file mode 100644
index 000000000000..731b0d60228d
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-rusty-sku196608.dts
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2022 Google LLC
+ */
+
+/dts-v1/;
+#include "mt8186-corsola-steelix.dtsi"
+
+/ {
+ model = "Google Rusty board";
+ compatible = "google,steelix-sku196609", "google,steelix-sku196608",
+ "google,steelix", "mediatek,mt8186";
+ chassis-type = "laptop";
+};
+
+&gpio_keys {
+ status = "disabled";
+};
+
+&i2c1 {
+ status = "disabled";
+};
+
+&touchscreen {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-steelix-sku131072.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-steelix-sku131072.dts
new file mode 100644
index 000000000000..eae17bca8585
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-steelix-sku131072.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2022 Google LLC
+ */
+
+/dts-v1/;
+#include "mt8186-corsola-steelix.dtsi"
+
+/ {
+ model = "Google Steelix board";
+ compatible = "google,steelix-sku131072", "google,steelix",
+ "mediatek,mt8186";
+ chassis-type = "convertible";
+};
+
+&mt6366codec {
+ mediatek,dmic-mode = <0>; /* two-wire */
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-steelix-sku131073.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-steelix-sku131073.dts
new file mode 100644
index 000000000000..a55375b95d0d
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-steelix-sku131073.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2022 Google LLC
+ */
+
+/dts-v1/;
+#include "mt8186-corsola-steelix.dtsi"
+
+/ {
+ model = "Google Steelix board";
+ compatible = "google,steelix-sku131073", "google,steelix",
+ "mediatek,mt8186";
+ chassis-type = "convertible";
+};
+
+&mt6366codec {
+ mediatek,dmic-mode = <1>; /* one-wire */
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-steelix.dtsi b/arch/arm64/boot/dts/mediatek/mt8186-corsola-steelix.dtsi
new file mode 100644
index 000000000000..e74e886a00cb
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-steelix.dtsi
@@ -0,0 +1,199 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2022 Google LLC
+ */
+
+/dts-v1/;
+#include "mt8186-corsola.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/{
+ pp1000_edpbrdg: regulator-pp1000-edpbrdg {
+ compatible = "regulator-fixed";
+ regulator-name = "pp1000_edpbrdg";
+ pinctrl-names = "default";
+ pinctrl-0 = <&en_pp1000_edpbrdg>;
+ enable-active-high;
+ regulator-boot-on;
+ gpio = <&pio 29 GPIO_ACTIVE_HIGH>;
+ vin-supply = <&pp3300_z2>;
+ };
+
+ pp1800_edpbrdg_dx: regulator-pp1800-edpbrdg-dx {
+ compatible = "regulator-fixed";
+ regulator-name = "pp1800_edpbrdg_dx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&en_pp1800_edpbrdg>;
+ enable-active-high;
+ regulator-boot-on;
+ gpio = <&pio 30 GPIO_ACTIVE_HIGH>;
+ vin-supply = <&mt6366_vio18_reg>;
+ };
+
+ pp3300_edp_dx: regulator-pp3300-edp-dx {
+ compatible = "regulator-fixed";
+ regulator-name = "pp3300_edp_dx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&en_pp3300_edpbrdg>;
+ enable-active-high;
+ regulator-boot-on;
+ gpio = <&pio 31 GPIO_ACTIVE_HIGH>;
+ vin-supply = <&pp3300_z2>;
+ };
+};
+
+&dsi_out {
+ remote-endpoint = <&anx7625_in>;
+};
+
+&i2c0 {
+ clock-frequency = <400000>;
+
+ anx_bridge: anx7625@58 {
+ compatible = "analogix,anx7625";
+ reg = <0x58>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&anx7625_pins>;
+ enable-gpios = <&pio 96 GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&pio 98 GPIO_ACTIVE_HIGH>;
+ vdd10-supply = <&pp1000_edpbrdg>;
+ vdd18-supply = <&pp1800_edpbrdg_dx>;
+ vdd33-supply = <&pp3300_edp_dx>;
+ analogix,lane0-swing = /bits/ 8 <0x70 0x30>;
+ analogix,lane1-swing = /bits/ 8 <0x70 0x30>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ anx7625_in: endpoint {
+ remote-endpoint = <&dsi_out>;
+ data-lanes = <0 1 2 3>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ anx7625_out: endpoint {
+ remote-endpoint = <&panel_in>;
+ };
+ };
+ };
+
+ aux-bus {
+ panel: panel {
+ compatible = "edp-panel";
+ power-supply = <&pp3300_disp_x>;
+ backlight = <&backlight_lcd0>;
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&anx7625_out>;
+ };
+ };
+ };
+ };
+ };
+};
+
+&i2c1 {
+ touchscreen: touchscreen@5d {
+ compatible = "goodix,gt7375p";
+ reg = <0x5d>;
+ interrupts-extended = <&pio 12 IRQ_TYPE_EDGE_FALLING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&touchscreen_pins>;
+ reset-gpios = <&pio 60 GPIO_ACTIVE_LOW>;
+ vdd-supply = <&pp3300_s3>;
+ goodix,no-reset-during-suspend;
+ };
+};
+
+&i2c2 {
+ i2c-scl-internal-delay-ns = <22000>;
+
+ /* second source component */
+ trackpad@2c {
+ compatible = "hid-over-i2c";
+ reg = <0x2c>;
+ hid-descr-addr = <0x20>;
+ interrupts-extended = <&pio 11 IRQ_TYPE_LEVEL_LOW>;
+ vdd-supply = <&pp3300_s3>;
+ wakeup-source;
+ };
+};
+
+&keyboard_controller {
+ function-row-physmap = <
+ MATRIX_KEY(0x00, 0x02, 0) /* T1 */
+ MATRIX_KEY(0x03, 0x02, 0) /* T2 */
+ MATRIX_KEY(0x02, 0x02, 0) /* T3 */
+ MATRIX_KEY(0x01, 0x02, 0) /* T4 */
+ MATRIX_KEY(0x03, 0x04, 0) /* T5 */
+ MATRIX_KEY(0x02, 0x04, 0) /* T6 */
+ MATRIX_KEY(0x01, 0x04, 0) /* T7 */
+ MATRIX_KEY(0x02, 0x09, 0) /* T8 */
+ MATRIX_KEY(0x01, 0x09, 0) /* T9 */
+ MATRIX_KEY(0x00, 0x04, 0) /* T10 */
+ >;
+
+ 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_BRIGHTNESSDOWN)
+ MATRIX_KEY(0x02, 0x04, KEY_BRIGHTNESSUP)
+ MATRIX_KEY(0x01, 0x04, KEY_MICMUTE)
+ MATRIX_KEY(0x02, 0x09, KEY_MUTE)
+ MATRIX_KEY(0x01, 0x09, KEY_VOLUMEDOWN)
+ MATRIX_KEY(0x00, 0x04, KEY_VOLUMEUP)
+ CROS_STD_MAIN_KEYMAP
+ >;
+};
+
+&pio {
+ anx7625_pins: anx7625-pins {
+ pins-int {
+ pinmux = <PINMUX_GPIO9__FUNC_GPIO9>;
+ input-enable;
+ bias-disable;
+ };
+
+ pins-reset {
+ pinmux = <PINMUX_GPIO98__FUNC_GPIO98>;
+ output-low;
+ };
+
+ pins-power-en {
+ pinmux = <PINMUX_GPIO96__FUNC_GPIO96>;
+ output-low;
+ };
+ };
+
+ en_pp1000_edpbrdg: pp1000-edpbrdg-en-pins {
+ pins-vreg-en {
+ pinmux = <PINMUX_GPIO29__FUNC_GPIO29>;
+ output-low;
+ };
+ };
+
+ en_pp1800_edpbrdg: pp1800-edpbrdg-en-pins {
+ pins-vreg-en {
+ pinmux = <PINMUX_GPIO30__FUNC_GPIO30>;
+ output-low;
+ };
+ };
+
+ en_pp3300_edpbrdg: pp3300-edpbrdg-en-pins {
+ pins-vreg-en {
+ pinmux = <PINMUX_GPIO31__FUNC_GPIO31>;
+ output-low;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-tentacool-sku327681.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-tentacool-sku327681.dts
new file mode 100644
index 000000000000..9bb64353ca65
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-tentacool-sku327681.dts
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2022 Google LLC
+ */
+
+/dts-v1/;
+#include "mt8186-corsola-krabby.dtsi"
+
+/ {
+ model = "Google Tentacool board";
+ compatible = "google,tentacruel-sku327681", "google,tentacruel", "mediatek,mt8186";
+ chassis-type = "laptop";
+};
+
+/* Tentacool omits the pen. */
+&gpio_keys {
+ status = "disabled";
+};
+
+/* Tentacool omits the touchscreen; nothing else is on i2c1. */
+&i2c1 {
+ status = "disabled";
+};
+
+&keyboard_controller {
+ function-row-physmap = <
+ MATRIX_KEY(0x00, 0x02, 0) /* T1 */
+ MATRIX_KEY(0x03, 0x02, 0) /* T2 */
+ MATRIX_KEY(0x02, 0x02, 0) /* T3 */
+ MATRIX_KEY(0x01, 0x02, 0) /* T4 */
+ MATRIX_KEY(0x03, 0x04, 0) /* T5 */
+ MATRIX_KEY(0x02, 0x04, 0) /* T6 */
+ MATRIX_KEY(0x01, 0x04, 0) /* T7 */
+ MATRIX_KEY(0x02, 0x09, 0) /* T8 */
+ MATRIX_KEY(0x01, 0x09, 0) /* T9 */
+ MATRIX_KEY(0x00, 0x04, 0) /* T10 */
+ >;
+
+ 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
+ >;
+};
+
+/* Tentacool omits the touchscreen. */
+&touchscreen {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-tentacool-sku327683.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-tentacool-sku327683.dts
new file mode 100644
index 000000000000..c3ae6f9616c8
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-tentacool-sku327683.dts
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2023 Google LLC
+ */
+
+#include "mt8186-corsola-tentacool-sku327681.dts"
+
+/ {
+ compatible = "google,tentacruel-sku327683", "google,tentacruel", "mediatek,mt8186";
+};
+
+/* This variant replaces only the trackpad controller. */
+&i2c2 {
+ /delete-node/ trackpad@15;
+
+ trackpad@15 {
+ compatible = "hid-over-i2c";
+ reg = <0x15>;
+ interrupts-extended = <&pio 11 IRQ_TYPE_LEVEL_LOW>;
+ hid-descr-addr = <0x0001>;
+ vdd-supply = <&pp3300_s3>;
+ wakeup-source;
+ };
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-tentacruel-sku262144.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-tentacruel-sku262144.dts
new file mode 100644
index 000000000000..26d3451a5e47
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-tentacruel-sku262144.dts
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2022 Google LLC
+ */
+
+/dts-v1/;
+#include "mt8186-corsola-krabby.dtsi"
+
+/ {
+ model = "Google Tentacruel board";
+ compatible = "google,tentacruel-sku262147", "google,tentacruel-sku262146",
+ "google,tentacruel-sku262145", "google,tentacruel-sku262144",
+ "google,tentacruel", "mediatek,mt8186";
+ chassis-type = "convertible";
+};
+
+&keyboard_controller {
+ function-row-physmap = <
+ MATRIX_KEY(0x00, 0x02, 0) /* T1 */
+ MATRIX_KEY(0x03, 0x02, 0) /* T2 */
+ MATRIX_KEY(0x02, 0x02, 0) /* T3 */
+ MATRIX_KEY(0x01, 0x02, 0) /* T4 */
+ MATRIX_KEY(0x03, 0x04, 0) /* T5 */
+ MATRIX_KEY(0x02, 0x04, 0) /* T6 */
+ MATRIX_KEY(0x01, 0x04, 0) /* T7 */
+ MATRIX_KEY(0x02, 0x09, 0) /* T8 */
+ MATRIX_KEY(0x01, 0x09, 0) /* T9 */
+ MATRIX_KEY(0x00, 0x04, 0) /* T10 */
+ >;
+
+ 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
+ >;
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola-tentacruel-sku262148.dts b/arch/arm64/boot/dts/mediatek/mt8186-corsola-tentacruel-sku262148.dts
new file mode 100644
index 000000000000..447b57b12b41
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola-tentacruel-sku262148.dts
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2023 Google LLC
+ */
+
+#include "mt8186-corsola-tentacruel-sku262144.dts"
+
+/ {
+ compatible = "google,tentacruel-sku262151", "google,tentacruel-sku262150",
+ "google,tentacruel-sku262149", "google,tentacruel-sku262148",
+ "google,tentacruel", "mediatek,mt8186";
+};
+
+/* This variant replaces only the trackpad controller. */
+&i2c2 {
+ /delete-node/ trackpad@15;
+
+ trackpad@15 {
+ compatible = "hid-over-i2c";
+ reg = <0x15>;
+ interrupts-extended = <&pio 11 IRQ_TYPE_LEVEL_LOW>;
+ hid-descr-addr = <0x0001>;
+ vdd-supply = <&pp3300_s3>;
+ wakeup-source;
+ };
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi b/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi
new file mode 100644
index 000000000000..3dea28f1d806
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi
@@ -0,0 +1,1681 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ */
+/dts-v1/;
+#include "mt8186.dtsi"
+#include <dt-bindings/pinctrl/mt8186-pinfunc.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/input/gpio-keys.h>
+#include <dt-bindings/regulator/mediatek,mt6397-regulator.h>
+
+/ {
+ aliases {
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+ i2c3 = &i2c3;
+ i2c5 = &i2c5;
+ mmc0 = &mmc0;
+ mmc1 = &mmc1;
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@40000000 {
+ device_type = "memory";
+ /* The size should be filled in by the bootloader. */
+ reg = <0 0x40000000 0 0>;
+ };
+
+ backlight_lcd0: backlight-lcd0 {
+ compatible = "pwm-backlight";
+ pwms = <&pwm0 0 500000>;
+ power-supply = <&ppvar_sys>;
+ enable-gpios = <&pio 152 0>;
+ brightness-levels = <0 1023>;
+ num-interpolated-steps = <1023>;
+ default-brightness-level = <576>;
+ };
+
+ bt-sco-codec {
+ compatible = "linux,bt-sco";
+ #sound-dai-cells = <0>;
+ };
+
+ dmic-codec {
+ compatible = "dmic-codec";
+ #sound-dai-cells = <0>;
+ num-channels = <2>;
+ wakeup-delay-ms = <50>;
+ };
+
+ gpio_keys: gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pen_eject>;
+
+ pen_insert: pen-insert-switch {
+ label = "Pen Insert";
+ /* Insert = low, eject = high */
+ gpios = <&pio 18 GPIO_ACTIVE_LOW>;
+ wakeup-event-action = <EV_ACT_DEASSERTED>;
+ wakeup-source;
+ linux,code = <SW_PEN_INSERTED>;
+ linux,input-type = <EV_SW>;
+ };
+ };
+
+ pp1800_dpbrdg_dx: regulator-pp1800-dpbrdg-dx {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&en_pp1800_dpbrdg>;
+ gpios = <&pio 39 GPIO_ACTIVE_HIGH>;
+ regulator-name = "pp1800_dpbrdg_dx";
+ enable-active-high;
+ vin-supply = <&mt6366_vio18_reg>;
+ };
+
+ pp3300_disp_x: regulator-pp3300-disp-x {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&edp_panel_fixed_pins>;
+ gpios = <&pio 153 GPIO_ACTIVE_HIGH>;
+ regulator-name = "pp3300_disp_x";
+ enable-active-high;
+ regulator-boot-on;
+ vin-supply = <&pp3300_z2>;
+ };
+
+ /* system wide LDO 3.3V power rail */
+ pp3300_z5: regulator-pp3300-ldo-z5 {
+ compatible = "regulator-fixed";
+ regulator-name = "pp3300_ldo_z5";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&ppvar_sys>;
+ };
+
+ /* separately switched 3.3V power rail */
+ pp3300_s3: regulator-pp3300-s3 {
+ compatible = "regulator-fixed";
+ regulator-name = "pp3300_s3";
+ /* automatically sequenced by PMIC EXT_PMIC_EN2 */
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&pp3300_z2>;
+ };
+
+ /* system wide 3.3V power rail */
+ pp3300_z2: regulator-pp3300-z2 {
+ compatible = "regulator-fixed";
+ regulator-name = "pp3300_z2";
+ /* EN pin tied to pp4200_z2, which is controlled by EC */
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&ppvar_sys>;
+ };
+
+ /* system wide 4.2V power rail */
+ pp4200_z2: regulator-pp4200-z2 {
+ compatible = "regulator-fixed";
+ regulator-name = "pp4200_z2";
+ /* controlled by EC */
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <4200000>;
+ regulator-max-microvolt = <4200000>;
+ vin-supply = <&ppvar_sys>;
+ };
+
+ /* system wide switching 5.0V power rail */
+ pp5000_z2: regulator-pp5000-z2 {
+ compatible = "regulator-fixed";
+ regulator-name = "pp5000_z2";
+ /* controlled by EC */
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&ppvar_sys>;
+ };
+
+ /* system wide semi-regulated power rail from battery or USB */
+ ppvar_sys: regulator-ppvar-sys {
+ compatible = "regulator-fixed";
+ regulator-name = "ppvar_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ reserved_memory: reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ adsp_dma_mem: memory@61000000 {
+ compatible = "shared-dma-pool";
+ reg = <0 0x61000000 0 0x100000>;
+ no-map;
+ };
+
+ adsp_mem: memory@60000000 {
+ compatible = "shared-dma-pool";
+ reg = <0 0x60000000 0 0xA00000>;
+ no-map;
+ };
+
+ scp_mem: memory@50000000 {
+ compatible = "shared-dma-pool";
+ reg = <0 0x50000000 0 0x10a0000>;
+ no-map;
+ };
+ };
+
+ sound: sound {
+ compatible = "mediatek,mt8186-mt6366-rt1019-rt5682s-sound";
+ pinctrl-names = "aud_clk_mosi_off",
+ "aud_clk_mosi_on",
+ "aud_clk_miso_off",
+ "aud_clk_miso_on",
+ "aud_dat_miso_off",
+ "aud_dat_miso_on",
+ "aud_dat_mosi_off",
+ "aud_dat_mosi_on",
+ "aud_gpio_i2s0_off",
+ "aud_gpio_i2s0_on",
+ "aud_gpio_i2s1_off",
+ "aud_gpio_i2s1_on",
+ "aud_gpio_i2s2_off",
+ "aud_gpio_i2s2_on",
+ "aud_gpio_i2s3_off",
+ "aud_gpio_i2s3_on",
+ "aud_gpio_pcm_off",
+ "aud_gpio_pcm_on",
+ "aud_gpio_dmic_sec";
+ pinctrl-0 = <&aud_clk_mosi_off>;
+ pinctrl-1 = <&aud_clk_mosi_on>;
+ pinctrl-2 = <&aud_clk_miso_off>;
+ pinctrl-3 = <&aud_clk_miso_on>;
+ pinctrl-4 = <&aud_dat_miso_off>;
+ pinctrl-5 = <&aud_dat_miso_on>;
+ pinctrl-6 = <&aud_dat_mosi_off>;
+ pinctrl-7 = <&aud_dat_mosi_on>;
+ pinctrl-8 = <&aud_gpio_i2s0_off>;
+ pinctrl-9 = <&aud_gpio_i2s0_on>;
+ pinctrl-10 = <&aud_gpio_i2s1_off>;
+ pinctrl-11 = <&aud_gpio_i2s1_on>;
+ pinctrl-12 = <&aud_gpio_i2s2_off>;
+ pinctrl-13 = <&aud_gpio_i2s2_on>;
+ pinctrl-14 = <&aud_gpio_i2s3_off>;
+ pinctrl-15 = <&aud_gpio_i2s3_on>;
+ pinctrl-16 = <&aud_gpio_pcm_off>;
+ pinctrl-17 = <&aud_gpio_pcm_on>;
+ pinctrl-18 = <&aud_gpio_dmic_sec>;
+ mediatek,adsp = <&adsp>;
+ mediatek,platform = <&afe>;
+
+ playback-codecs {
+ sound-dai = <&it6505dptx>, <&rt1019p>;
+ };
+
+ headset-codec {
+ sound-dai = <&rt5682s 0>;
+ };
+ };
+
+ rt1019p: speaker-codec {
+ compatible = "realtek,rt1019p";
+ pinctrl-names = "default";
+ pinctrl-0 = <&rt1019p_pins_default>;
+ #sound-dai-cells = <0>;
+ sdb-gpios = <&pio 150 GPIO_ACTIVE_HIGH>;
+ };
+
+ usb_p1_vbus: regulator-usb-p1-vbus {
+ compatible = "regulator-fixed";
+ gpio = <&pio 148 GPIO_ACTIVE_HIGH>;
+ regulator-name = "vbus1";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ enable-active-high;
+ vin-supply = <&pp5000_z2>;
+ };
+
+ wifi_pwrseq: wifi-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ pinctrl-names = "default";
+ pinctrl-0 = <&wifi_enable_pin>;
+ post-power-on-delay-ms = <50>;
+ reset-gpios = <&pio 54 GPIO_ACTIVE_LOW>;
+ };
+
+ wifi_wakeup: wifi-wakeup {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&wifi_wakeup_pin>;
+
+ wowlan-event {
+ label = "Wake on WiFi";
+ gpios = <&pio 7 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_WAKEUP>;
+ wakeup-source;
+ };
+ };
+};
+
+&adsp {
+ memory-region = <&adsp_dma_mem>, <&adsp_mem>;
+ status = "okay";
+};
+
+&afe {
+ status = "okay";
+};
+
+&cci {
+ proc-supply = <&mt6366_vproc12_reg>;
+};
+
+&cpu0 {
+ proc-supply = <&mt6366_vproc12_reg>;
+};
+
+&cpu1 {
+ proc-supply = <&mt6366_vproc12_reg>;
+};
+
+&cpu2 {
+ proc-supply = <&mt6366_vproc12_reg>;
+};
+
+&cpu3 {
+ proc-supply = <&mt6366_vproc12_reg>;
+};
+
+&cpu4 {
+ proc-supply = <&mt6366_vproc12_reg>;
+};
+
+&cpu5 {
+ proc-supply = <&mt6366_vproc12_reg>;
+};
+
+&cpu6 {
+ proc-supply = <&mt6366_vproc11_reg>;
+};
+
+&cpu7 {
+ proc-supply = <&mt6366_vproc11_reg>;
+};
+
+&dpi {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&dpi_pins_default>;
+ pinctrl-1 = <&dpi_pins_sleep>;
+ status = "okay";
+};
+
+&dpi_out {
+ remote-endpoint = <&it6505_in>;
+};
+
+&dsi0 {
+ status = "okay";
+};
+
+&gic {
+ mediatek,broken-save-restore-fw;
+};
+
+&gpu {
+ mali-supply = <&mt6366_vgpu_reg>;
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ status = "okay";
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+ clock-frequency = <400000>;
+ i2c-scl-internal-delay-ns = <8000>;
+ status = "okay";
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ /*
+ * Trackpad pin put here to work around second source components
+ * sharing the pinmux in steelix designs.
+ */
+ pinctrl-0 = <&i2c2_pins>, <&trackpad_pin>;
+ clock-frequency = <400000>;
+ i2c-scl-internal-delay-ns = <10000>;
+ status = "okay";
+
+ trackpad@15 {
+ compatible = "elan,ekth3000";
+ reg = <0x15>;
+ interrupts-extended = <&pio 11 IRQ_TYPE_LEVEL_LOW>;
+ vcc-supply = <&pp3300_s3>;
+ wakeup-source;
+ };
+};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_pins>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ it6505dptx: dp-bridge@5c {
+ compatible = "ite,it6505";
+ reg = <0x5c>;
+ interrupts-extended = <&pio 8 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&it6505_pins>;
+ #sound-dai-cells = <0>;
+ ovdd-supply = <&mt6366_vsim2_reg>;
+ pwr18-supply = <&pp1800_dpbrdg_dx>;
+ reset-gpios = <&pio 177 GPIO_ACTIVE_HIGH>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ it6505_in: endpoint {
+ link-frequencies = /bits/ 64 <150000000>;
+ remote-endpoint = <&dpi_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ };
+ };
+ };
+};
+
+&i2c5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c5_pins>;
+ status = "okay";
+
+ rt5682s: codec@1a {
+ compatible = "realtek,rt5682s";
+ reg = <0x1a>;
+ interrupts-extended = <&pio 17 IRQ_TYPE_EDGE_BOTH>;
+ #sound-dai-cells = <1>;
+ AVDD-supply = <&mt6366_vio18_reg>;
+ DBVDD-supply = <&mt6366_vio18_reg>;
+ LDO1-IN-supply = <&mt6366_vio18_reg>;
+ MICVDD-supply = <&pp3300_z2>;
+ realtek,jd-src = <1>;
+ };
+};
+
+&mfg0 {
+ domain-supply = <&mt6366_vsram_gpu_reg>;
+};
+
+&mfg1 {
+ domain-supply = <&mt6366_vgpu_reg>;
+};
+
+&mipi_tx0 {
+ status = "okay";
+};
+
+&mmc0 {
+ pinctrl-names = "default", "state_uhs";
+ pinctrl-0 = <&mmc0_pins_default>;
+ pinctrl-1 = <&mmc0_pins_uhs>;
+ bus-width = <8>;
+ max-frequency = <200000000>;
+ non-removable;
+ cap-mmc-highspeed;
+ mmc-hs200-1_8v;
+ mmc-hs400-1_8v;
+ supports-cqe;
+ no-sd;
+ no-sdio;
+ cap-mmc-hw-reset;
+ hs400-ds-delay = <0x11814>;
+ mediatek,hs400-ds-dly3 = <0x14>;
+ vmmc-supply = <&mt6366_vemc_reg>;
+ vqmmc-supply = <&mt6366_vio18_reg>;
+ status = "okay";
+};
+
+&mmc1 {
+ pinctrl-names = "default", "state_uhs", "state_eint";
+ pinctrl-0 = <&mmc1_pins_default>;
+ pinctrl-1 = <&mmc1_pins_uhs>;
+ pinctrl-2 = <&mmc1_pins_eint>;
+ /delete-property/ interrupts;
+ interrupt-names = "msdc", "sdio_wakeup";
+ interrupts-extended = <&gic GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH 0>,
+ <&pio 87 IRQ_TYPE_LEVEL_LOW>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ bus-width = <4>;
+ max-frequency = <200000000>;
+ cap-sd-highspeed;
+ sd-uhs-sdr104;
+ sd-uhs-sdr50;
+ keep-power-in-suspend;
+ wakeup-source;
+ cap-sdio-irq;
+ no-mmc;
+ no-sd;
+ non-removable;
+ vmmc-supply = <&pp3300_s3>;
+ vqmmc-supply = <&mt6366_vio18_reg>;
+ mmc-pwrseq = <&wifi_pwrseq>;
+ status = "okay";
+
+ bluetooth@2 {
+ compatible = "mediatek,mt7921s-bluetooth";
+ reg = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&bt_pins_reset>;
+ reset-gpios = <&pio 155 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&nor_flash {
+ assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D7_D4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&nor_pins_default>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <39000000>;
+ };
+};
+
+&pio {
+ /* 185 lines */
+ gpio-line-names = "TP",
+ "TP",
+ "TP",
+ "I2S0_HP_DI",
+ "I2S3_DP_SPKR_DO",
+ "SAR_INT_ODL",
+ "BT_WAKE_AP_ODL",
+ "WIFI_INT_ODL",
+ "DPBRDG_INT_ODL",
+ "EDPBRDG_INT_ODL",
+ "EC_AP_HPD_OD",
+ "TCHPAD_INT_ODL",
+ "TCHSCR_INT_1V8_ODL",
+ "EC_AP_INT_ODL",
+ "EC_IN_RW_ODL",
+ "GSC_AP_INT_ODL",
+ /* AP_FLASH_WP_L is crossystem ABI. Rev1 schematics call it AP_WP_ODL. */
+ "AP_FLASH_WP_L",
+ "HP_INT_ODL",
+ "PEN_EJECT_OD",
+ "WCAM_PWDN_L",
+ "WCAM_RST_L",
+ "UCAM_SEN_EN",
+ "UCAM_RST_L",
+ "LTE_RESET_L",
+ "LTE_SAR_DETECT_L",
+ "I2S2_DP_SPK_MCK",
+ "I2S2_DP_SPKR_BCK",
+ "I2S2_DP_SPKR_LRCK",
+ "I2S2_DP_SPKR_DI (TP)",
+ "EN_PP1000_EDPBRDG",
+ "EN_PP1800_EDPBRDG",
+ "EN_PP3300_EDPBRDG",
+ "UART_GSC_TX_AP_RX",
+ "UART_AP_TX_GSC_RX",
+ "UART_DBGCON_TX_ADSP_RX",
+ "UART_ADSP_TX_DBGCON_RX",
+ "EN_PP1000_DPBRDG",
+ "TCHSCR_REPORT_DISABLE",
+ "EN_PP3300_DPBRDG",
+ "EN_PP1800_DPBRDG",
+ "SPI_AP_CLK_EC",
+ "SPI_AP_CS_EC_L",
+ "SPI_AP_DO_EC_DI",
+ "SPI_AP_DI_EC_DO",
+ "SPI_AP_CLK_GSC",
+ "SPI_AP_CS_GSC_L",
+ "SPI_AP_DO_GSC_DI",
+ "SPI_AP_DI_GSC_DO",
+ "UART_DBGCON_TX_SCP_RX",
+ "UART_SCP_TX_DBGCON_RX",
+ "EN_PP1200_CAM_X",
+ "EN_PP2800A_VCM_X",
+ "EN_PP2800A_UCAM_X",
+ "EN_PP2800A_WCAM_X",
+ "WLAN_MODULE_RST_L",
+ "EN_PP1200_UCAM_X",
+ "I2S1_HP_DO",
+ "I2S1_HP_BCK",
+ "I2S1_HP_LRCK",
+ "I2S1_HP_MCK",
+ "TCHSCR_RST_1V8_L",
+ "SPI_AP_CLK_ROM",
+ "SPI_AP_CS_ROM_L",
+ "SPI_AP_DO_ROM_DI",
+ "SPI_AP_DI_ROM_DO",
+ "NC",
+ "NC",
+ "EMMC_STRB",
+ "EMMC_CLK",
+ "EMMC_CMD",
+ "EMMC_RST_L",
+ "EMMC_DATA0",
+ "EMMC_DATA1",
+ "EMMC_DATA2",
+ "EMMC_DATA3",
+ "EMMC_DATA4",
+ "EMMC_DATA5",
+ "EMMC_DATA6",
+ "EMMC_DATA7",
+ "AP_KPCOL0",
+ "NC",
+ "NC",
+ "NC",
+ "TP",
+ "SDIO_CLK",
+ "SDIO_CMD",
+ "SDIO_DATA0",
+ "SDIO_DATA1",
+ "SDIO_DATA2",
+ "SDIO_DATA3",
+ "NC",
+ "NC",
+ "NC",
+ "NC",
+ "NC",
+ "NC",
+ "EDPBRDG_PWREN",
+ "BL_PWM_1V8",
+ "EDPBRDG_RST_L",
+ "MIPI_DPI_CLK",
+ "MIPI_DPI_VSYNC",
+ "MIPI_DPI_HSYNC",
+ "MIPI_DPI_DE",
+ "MIPI_DPI_D0",
+ "MIPI_DPI_D1",
+ "MIPI_DPI_D2",
+ "MIPI_DPI_D3",
+ "MIPI_DPI_D4",
+ "MIPI_DPI_D5",
+ "MIPI_DPI_D6",
+ "MIPI_DPI_DA7",
+ "MIPI_DPI_D8",
+ "MIPI_DPI_D9",
+ "MIPI_DPI_D10",
+ "MIPI_DPI_D11",
+ "PCM_BT_CLK",
+ "PCM_BT_SYNC",
+ "PCM_BT_DI",
+ "PCM_BT_DO",
+ "JTAG_TMS_TP",
+ "JTAG_TCK_TP",
+ "JTAG_TDI_TP",
+ "JTAG_TDO_TP",
+ "JTAG_TRSTN_TP",
+ "CLK_24M_WCAM",
+ "CLK_24M_UCAM",
+ "UCAM_DET_ODL",
+ "AP_I2C_EDPBRDG_SCL_1V8",
+ "AP_I2C_EDPBRDG_SDA_1V8",
+ "AP_I2C_TCHSCR_SCL_1V8",
+ "AP_I2C_TCHSCR_SDA_1V8",
+ "AP_I2C_TCHPAD_SCL_1V8",
+ "AP_I2C_TCHPAD_SDA_1V8",
+ "AP_I2C_DPBRDG_SCL_1V8",
+ "AP_I2C_DPBRDG_SDA_1V8",
+ "AP_I2C_WLAN_SCL_1V8",
+ "AP_I2C_WLAN_SDA_1V8",
+ "AP_I2C_AUD_SCL_1V8",
+ "AP_I2C_AUD_SDA_1V8",
+ "AP_I2C_TPM_SCL_1V8",
+ "AP_I2C_UCAM_SDA_1V8",
+ "AP_I2C_UCAM_SCL_1V8",
+ "AP_I2C_UCAM_SDA_1V8",
+ "AP_I2C_WCAM_SCL_1V8",
+ "AP_I2C_WCAM_SDA_1V8",
+ "SCP_I2C_SENSOR_SCL_1V8",
+ "SCP_I2C_SENSOR_SDA_1V8",
+ "AP_EC_WARM_RST_REQ",
+ "AP_XHCI_INIT_DONE",
+ "USB3_HUB_RST_L",
+ "EN_SPKR",
+ "BEEP_ON",
+ "AP_EDP_BKLTEN",
+ "EN_PP3300_DISP_X",
+ "EN_PP3300_SDBRDG_X",
+ "BT_KILL_1V8_L",
+ "WIFI_KILL_1V8_L",
+ "PWRAP_SPI0_CSN",
+ "PWRAP_SPI0_CK",
+ "PWRAP_SPI0_MO",
+ "PWRAP_SPI0_MI",
+ "SRCLKENA0",
+ "SRCLKENA1",
+ "SCP_VREQ_VAO",
+ "AP_RTC_CLK32K",
+ "AP_PMIC_WDTRST_L",
+ "AUD_CLK_MOSI",
+ "AUD_SYNC_MOSI",
+ "AUD_DAT_MOSI0",
+ "AUD_DAT_MOSI1",
+ "AUD_CLK_MISO",
+ "AUD_SYNC_MISO",
+ "AUD_DAT_MISO0",
+ "AUD_DAT_MISO1",
+ "NC",
+ "NC",
+ "DPBRDG_PWREN",
+ "DPBRDG_RST_L",
+ "LTE_W_DISABLE_L",
+ "LTE_SAR_DETECT_L",
+ "EN_PP3300_LTE_X",
+ "LTE_PWR_OFF_L",
+ "LTE_RESET_L",
+ "TP",
+ "TP";
+
+ aud_clk_mosi_off: aud-clk-mosi-off-pins {
+ pins-clk-sync {
+ pinmux = <PINMUX_GPIO166__FUNC_GPIO166>,
+ <PINMUX_GPIO167__FUNC_GPIO167>;
+ input-enable;
+ bias-pull-down;
+ };
+ };
+
+ aud_clk_mosi_on: aud-clk-mosi-on-pins {
+ pins-clk-sync {
+ pinmux = <PINMUX_GPIO166__FUNC_AUD_CLK_MOSI>,
+ <PINMUX_GPIO167__FUNC_AUD_SYNC_MOSI>;
+ };
+ };
+
+ aud_clk_miso_off: aud-clk-miso-off-pins {
+ pins-clk-sync {
+ pinmux = <PINMUX_GPIO170__FUNC_GPIO170>,
+ <PINMUX_GPIO171__FUNC_GPIO171>;
+ input-enable;
+ bias-pull-down;
+ };
+ };
+
+ aud_clk_miso_on: aud-clk-miso-on-pins {
+ pins-clk-sync {
+ pinmux = <PINMUX_GPIO170__FUNC_AUD_CLK_MISO>,
+ <PINMUX_GPIO171__FUNC_AUD_SYNC_MISO>;
+ };
+ };
+
+ aud_dat_mosi_off: aud-dat-mosi-off-pins {
+ pins-dat {
+ pinmux = <PINMUX_GPIO168__FUNC_GPIO168>,
+ <PINMUX_GPIO169__FUNC_GPIO169>;
+ input-enable;
+ bias-pull-down;
+ };
+ };
+
+ aud_dat_mosi_on: aud-dat-mosi-on-pins {
+ pins-dat {
+ pinmux = <PINMUX_GPIO168__FUNC_AUD_DAT_MOSI0>,
+ <PINMUX_GPIO169__FUNC_AUD_DAT_MOSI1>;
+ };
+ };
+
+ aud_dat_miso_off: aud-dat-miso-off-pins {
+ pins-dat {
+ pinmux = <PINMUX_GPIO172__FUNC_GPIO172>,
+ <PINMUX_GPIO173__FUNC_GPIO173>;
+ input-enable;
+ bias-pull-down;
+ };
+ };
+
+ aud_dat_miso_on: aud-dat-miso-on-pins {
+ pins-dat {
+ pinmux = <PINMUX_GPIO172__FUNC_AUD_DAT_MISO0>,
+ <PINMUX_GPIO173__FUNC_AUD_DAT_MISO1>;
+ input-schmitt-enable;
+ bias-disable;
+ };
+ };
+
+ aud_gpio_i2s0_off: aud-gpio-i2s0-off-pins {
+ pins-sdata {
+ pinmux = <PINMUX_GPIO3__FUNC_GPIO3>;
+ };
+ };
+
+ aud_gpio_i2s0_on: aud-gpio-i2s0-on-pins {
+ pins-sdata {
+ pinmux = <PINMUX_GPIO3__FUNC_I2S0_DI>;
+ };
+ };
+
+ aud_gpio_i2s1_off: aud-gpio-i2s-off-pins {
+ pins-clk-sdata {
+ pinmux = <PINMUX_GPIO56__FUNC_GPIO56>,
+ <PINMUX_GPIO57__FUNC_GPIO57>,
+ <PINMUX_GPIO58__FUNC_GPIO58>,
+ <PINMUX_GPIO59__FUNC_GPIO59>;
+ output-low;
+ };
+ };
+
+ aud_gpio_i2s1_on: aud-gpio-i2s1-on-pins {
+ pins-clk-sdata {
+ pinmux = <PINMUX_GPIO56__FUNC_I2S1_DO>,
+ <PINMUX_GPIO57__FUNC_I2S1_BCK>,
+ <PINMUX_GPIO58__FUNC_I2S1_LRCK>,
+ <PINMUX_GPIO59__FUNC_I2S1_MCK>;
+ };
+ };
+
+ aud_gpio_i2s2_off: aud-gpio-i2s2-off-pins {
+ pins-cmd-dat {
+ pinmux = <PINMUX_GPIO26__FUNC_GPIO26>,
+ <PINMUX_GPIO27__FUNC_GPIO27>;
+ output-low;
+ };
+ };
+
+ aud_gpio_i2s2_on: aud-gpio-i2s2-on-pins {
+ pins-clk {
+ pinmux = <PINMUX_GPIO26__FUNC_I2S2_BCK>,
+ <PINMUX_GPIO27__FUNC_I2S2_LRCK>;
+ drive-strength = <4>;
+ };
+ };
+
+ aud_gpio_i2s3_off: aud-gpio-i2s3-off-pins {
+ pins-sdata {
+ pinmux = <PINMUX_GPIO4__FUNC_GPIO4>;
+ output-low;
+ };
+ };
+
+ aud_gpio_i2s3_on: aud-gpio-i2s3-on-pins {
+ pins-sdata {
+ pinmux = <PINMUX_GPIO4__FUNC_I2S3_DO>;
+ drive-strength = <4>;
+ };
+ };
+
+ aud_gpio_pcm_off: aud-gpio-pcm-off-pins {
+ pins-clk-sdata {
+ pinmux = <PINMUX_GPIO115__FUNC_GPIO115>,
+ <PINMUX_GPIO116__FUNC_GPIO116>,
+ <PINMUX_GPIO117__FUNC_GPIO117>,
+ <PINMUX_GPIO118__FUNC_GPIO118>;
+ output-low;
+ };
+ };
+
+ aud_gpio_pcm_on: aud-gpio-pcm-on-pins {
+ pins-clk-sdata {
+ pinmux = <PINMUX_GPIO115__FUNC_PCM_CLK>,
+ <PINMUX_GPIO116__FUNC_PCM_SYNC>,
+ <PINMUX_GPIO117__FUNC_PCM_DI>,
+ <PINMUX_GPIO118__FUNC_PCM_DO>;
+ };
+ };
+
+ aud_gpio_dmic_sec: aud-gpio-dmic-sec-pins {
+ pins {
+ pinmux = <PINMUX_GPIO23__FUNC_GPIO23>;
+ output-low;
+ };
+ };
+
+ bt_pins_reset: bt-reset-pins {
+ pins-bt-reset {
+ pinmux = <PINMUX_GPIO155__FUNC_GPIO155>;
+ output-high;
+ };
+ };
+
+ dpi_pins_sleep: dpi-sleep-pins {
+ pins-cmd-dat {
+ pinmux = <PINMUX_GPIO103__FUNC_GPIO103>,
+ <PINMUX_GPIO104__FUNC_GPIO104>,
+ <PINMUX_GPIO105__FUNC_GPIO105>,
+ <PINMUX_GPIO106__FUNC_GPIO106>,
+ <PINMUX_GPIO107__FUNC_GPIO107>,
+ <PINMUX_GPIO108__FUNC_GPIO108>,
+ <PINMUX_GPIO109__FUNC_GPIO109>,
+ <PINMUX_GPIO110__FUNC_GPIO110>,
+ <PINMUX_GPIO111__FUNC_GPIO111>,
+ <PINMUX_GPIO112__FUNC_GPIO112>,
+ <PINMUX_GPIO113__FUNC_GPIO113>,
+ <PINMUX_GPIO114__FUNC_GPIO114>,
+ <PINMUX_GPIO101__FUNC_GPIO101>,
+ <PINMUX_GPIO100__FUNC_GPIO100>,
+ <PINMUX_GPIO102__FUNC_GPIO102>,
+ <PINMUX_GPIO99__FUNC_GPIO99>;
+ drive-strength = <10>;
+ output-low;
+ };
+ };
+
+ dpi_pins_default: dpi-default-pins {
+ pins-cmd-dat {
+ pinmux = <PINMUX_GPIO103__FUNC_DPI_DATA0>,
+ <PINMUX_GPIO104__FUNC_DPI_DATA1>,
+ <PINMUX_GPIO105__FUNC_DPI_DATA2>,
+ <PINMUX_GPIO106__FUNC_DPI_DATA3>,
+ <PINMUX_GPIO107__FUNC_DPI_DATA4>,
+ <PINMUX_GPIO108__FUNC_DPI_DATA5>,
+ <PINMUX_GPIO109__FUNC_DPI_DATA6>,
+ <PINMUX_GPIO110__FUNC_DPI_DATA7>,
+ <PINMUX_GPIO111__FUNC_DPI_DATA8>,
+ <PINMUX_GPIO112__FUNC_DPI_DATA9>,
+ <PINMUX_GPIO113__FUNC_DPI_DATA10>,
+ <PINMUX_GPIO114__FUNC_DPI_DATA11>,
+ <PINMUX_GPIO101__FUNC_DPI_HSYNC>,
+ <PINMUX_GPIO100__FUNC_DPI_VSYNC>,
+ <PINMUX_GPIO102__FUNC_DPI_DE>,
+ <PINMUX_GPIO99__FUNC_DPI_PCLK>;
+ drive-strength = <10>;
+ };
+ };
+
+ ec_ap_int: cros-ec-int-pins {
+ pins-ec-ap-int-odl {
+ pinmux = <PINMUX_GPIO13__FUNC_GPIO13>;
+ input-enable;
+ };
+ };
+
+ edp_panel_fixed_pins: edp-panel-fixed-pins {
+ pins-vreg-en {
+ pinmux = <PINMUX_GPIO153__FUNC_GPIO153>;
+ output-high;
+ };
+ };
+
+ en_pp1800_dpbrdg: en-pp1800-dpbrdg-pins {
+ pins-vreg-en {
+ pinmux = <PINMUX_GPIO39__FUNC_GPIO39>;
+ output-low;
+ };
+ };
+
+ gsc_int: gsc-int-pins {
+ pins-gsc-ap-int-odl {
+ pinmux = <PINMUX_GPIO15__FUNC_GPIO15>;
+ input-enable;
+ };
+ };
+
+ i2c0_pins: i2c0-pins {
+ pins-bus {
+ pinmux = <PINMUX_GPIO128__FUNC_SDA0>,
+ <PINMUX_GPIO127__FUNC_SCL0>;
+ bias-disable;
+ drive-strength = <4>;
+ input-enable;
+ };
+ };
+
+ i2c1_pins: i2c1-pins {
+ pins-bus {
+ pinmux = <PINMUX_GPIO130__FUNC_SDA1>,
+ <PINMUX_GPIO129__FUNC_SCL1>;
+ bias-disable;
+ drive-strength = <4>;
+ input-enable;
+ };
+ };
+
+ i2c2_pins: i2c2-pins {
+ pins-bus {
+ pinmux = <PINMUX_GPIO132__FUNC_SDA2>,
+ <PINMUX_GPIO131__FUNC_SCL2>;
+ bias-disable;
+ drive-strength = <4>;
+ input-enable;
+ };
+ };
+
+ i2c3_pins: i2c3-pins {
+ pins-bus {
+ pinmux = <PINMUX_GPIO134__FUNC_SDA3>,
+ <PINMUX_GPIO133__FUNC_SCL3>;
+ bias-disable;
+ drive-strength = <4>;
+ input-enable;
+ };
+ };
+
+ i2c5_pins: i2c5-pins {
+ pins-bus {
+ pinmux = <PINMUX_GPIO138__FUNC_SDA5>,
+ <PINMUX_GPIO137__FUNC_SCL5>;
+ bias-disable;
+ drive-strength = <4>;
+ input-enable;
+ };
+ };
+
+ it6505_pins: it6505-pins {
+ pins-hpd {
+ pinmux = <PINMUX_GPIO10__FUNC_GPIO10>;
+ input-enable;
+ bias-pull-up;
+ };
+
+ pins-int {
+ pinmux = <PINMUX_GPIO8__FUNC_GPIO8>;
+ input-enable;
+ bias-pull-up;
+ };
+
+ pins-reset {
+ pinmux = <PINMUX_GPIO177__FUNC_GPIO177>;
+ output-low;
+ bias-pull-up;
+ };
+ };
+
+ mmc0_pins_default: mmc0-default-pins {
+ pins-clk {
+ pinmux = <PINMUX_GPIO68__FUNC_MSDC0_CLK>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ };
+
+ pins-cmd-dat {
+ pinmux = <PINMUX_GPIO71__FUNC_MSDC0_DAT0>,
+ <PINMUX_GPIO72__FUNC_MSDC0_DAT1>,
+ <PINMUX_GPIO73__FUNC_MSDC0_DAT2>,
+ <PINMUX_GPIO74__FUNC_MSDC0_DAT3>,
+ <PINMUX_GPIO75__FUNC_MSDC0_DAT4>,
+ <PINMUX_GPIO76__FUNC_MSDC0_DAT5>,
+ <PINMUX_GPIO77__FUNC_MSDC0_DAT6>,
+ <PINMUX_GPIO78__FUNC_MSDC0_DAT7>,
+ <PINMUX_GPIO69__FUNC_MSDC0_CMD>;
+ input-enable;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+
+ pins-rst {
+ pinmux = <PINMUX_GPIO70__FUNC_MSDC0_RSTB>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+ };
+
+ mmc0_pins_uhs: mmc0-uhs-pins {
+ pins-clk {
+ pinmux = <PINMUX_GPIO68__FUNC_MSDC0_CLK>;
+ drive-strength = <6>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ };
+
+ pins-cmd-dat {
+ pinmux = <PINMUX_GPIO71__FUNC_MSDC0_DAT0>,
+ <PINMUX_GPIO72__FUNC_MSDC0_DAT1>,
+ <PINMUX_GPIO73__FUNC_MSDC0_DAT2>,
+ <PINMUX_GPIO74__FUNC_MSDC0_DAT3>,
+ <PINMUX_GPIO75__FUNC_MSDC0_DAT4>,
+ <PINMUX_GPIO76__FUNC_MSDC0_DAT5>,
+ <PINMUX_GPIO77__FUNC_MSDC0_DAT6>,
+ <PINMUX_GPIO78__FUNC_MSDC0_DAT7>,
+ <PINMUX_GPIO69__FUNC_MSDC0_CMD>;
+ input-enable;
+ drive-strength = <6>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+
+ pins-ds {
+ pinmux = <PINMUX_GPIO67__FUNC_MSDC0_DSL>;
+ drive-strength = <6>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ };
+
+ pins-rst {
+ pinmux = <PINMUX_GPIO70__FUNC_MSDC0_RSTB>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+ };
+
+ mmc1_pins_default: mmc1-default-pins {
+ pins-clk {
+ pinmux = <PINMUX_GPIO84__FUNC_MSDC1_CLK>;
+ drive-strength = <6>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ };
+
+ pins-cmd-dat {
+ pinmux = <PINMUX_GPIO86__FUNC_MSDC1_DAT0>,
+ <PINMUX_GPIO87__FUNC_MSDC1_DAT1>,
+ <PINMUX_GPIO88__FUNC_MSDC1_DAT2>,
+ <PINMUX_GPIO89__FUNC_MSDC1_DAT3>,
+ <PINMUX_GPIO85__FUNC_MSDC1_CMD>;
+ input-enable;
+ drive-strength = <6>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+ };
+
+ mmc1_pins_uhs: mmc1-uhs-pins {
+ pins-clk {
+ pinmux = <PINMUX_GPIO84__FUNC_MSDC1_CLK>;
+ drive-strength = <6>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ };
+
+ pins-cmd-dat {
+ pinmux = <PINMUX_GPIO86__FUNC_MSDC1_DAT0>,
+ <PINMUX_GPIO87__FUNC_MSDC1_DAT1>,
+ <PINMUX_GPIO88__FUNC_MSDC1_DAT2>,
+ <PINMUX_GPIO89__FUNC_MSDC1_DAT3>,
+ <PINMUX_GPIO85__FUNC_MSDC1_CMD>;
+ input-enable;
+ drive-strength = <8>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+ };
+
+ mmc1_pins_eint: mmc1-eint-pins {
+ pins-dat1 {
+ pinmux = <PINMUX_GPIO87__FUNC_GPIO87>;
+ input-enable;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ };
+ };
+
+ nor_pins_default: nor-default-pins {
+ pins-clk-dat {
+ pinmux = <PINMUX_GPIO63__FUNC_SPINOR_IO0>,
+ <PINMUX_GPIO61__FUNC_SPINOR_CK>,
+ <PINMUX_GPIO64__FUNC_SPINOR_IO1>;
+ drive-strength = <6>;
+ bias-pull-down;
+ };
+
+ pins-cs-dat {
+ pinmux = <PINMUX_GPIO62__FUNC_SPINOR_CS>,
+ <PINMUX_GPIO65__FUNC_SPINOR_IO2>,
+ <PINMUX_GPIO66__FUNC_SPINOR_IO3>;
+ drive-strength = <6>;
+ bias-pull-up;
+ };
+ };
+
+ pen_eject: pen-eject-pins {
+ pins {
+ pinmux = <PINMUX_GPIO18__FUNC_GPIO18>;
+ input-enable;
+ /* External pull-up. */
+ bias-disable;
+ };
+ };
+
+ pwm0_pin: disp-pwm-pins {
+ pins {
+ pinmux = <PINMUX_GPIO97__FUNC_DISP_PWM>;
+ output-high;
+ };
+ };
+
+ rt1019p_pins_default: rt1019p-default-pins {
+ pins-sdb {
+ pinmux = <PINMUX_GPIO150__FUNC_GPIO150>;
+ output-low;
+ };
+ };
+
+ scp_pins: scp-default-pins {
+ pins-scp-uart {
+ pinmux = <PINMUX_GPIO48__FUNC_TP_URXD2_AO>,
+ <PINMUX_GPIO49__FUNC_TP_UTXD2_AO>;
+ };
+ };
+
+ spi1_pins: spi1-pins {
+ pins-bus {
+ pinmux = <PINMUX_GPIO40__FUNC_SPI1_CLK_A>,
+ <PINMUX_GPIO41__FUNC_SPI1_CSB_A>,
+ <PINMUX_GPIO42__FUNC_SPI1_MO_A>,
+ <PINMUX_GPIO43__FUNC_SPI1_MI_A>;
+ bias-disable;
+ input-enable;
+ };
+ };
+
+ spi2_pins: spi2-pins {
+ pins-bus {
+ pinmux = <PINMUX_GPIO44__FUNC_SPI2_CLK_A>,
+ <PINMUX_GPIO45__FUNC_GPIO45>,
+ <PINMUX_GPIO46__FUNC_SPI2_MO_A>,
+ <PINMUX_GPIO47__FUNC_SPI2_MI_A>;
+ bias-disable;
+ input-enable;
+ };
+ };
+
+ spmi_pins: spmi-pins {
+ pins-bus {
+ pinmux = <PINMUX_GPIO183__FUNC_SPMI_SCL>,
+ <PINMUX_GPIO184__FUNC_SPMI_SDA>;
+ };
+ };
+
+ touchscreen_pins: touchscreen-pins {
+ pins-irq {
+ pinmux = <PINMUX_GPIO12__FUNC_GPIO12>;
+ input-enable;
+ bias-pull-up;
+ };
+
+ pins-reset {
+ pinmux = <PINMUX_GPIO60__FUNC_GPIO60>;
+ output-high;
+ };
+
+ pins-report-sw {
+ pinmux = <PINMUX_GPIO37__FUNC_GPIO37>;
+ output-low;
+ };
+ };
+
+ trackpad_pin: trackpad-default-pins {
+ pins-int-n {
+ pinmux = <PINMUX_GPIO11__FUNC_GPIO11>;
+ input-enable;
+ bias-disable; /* pulled externally */
+ };
+ };
+
+ wifi_enable_pin: wifi-enable-pins {
+ pins-wifi-enable {
+ pinmux = <PINMUX_GPIO54__FUNC_GPIO54>;
+ };
+ };
+
+ wifi_wakeup_pin: wifi-wakeup-pins {
+ pins-wifi-wakeup {
+ pinmux = <PINMUX_GPIO7__FUNC_GPIO7>;
+ input-enable;
+ };
+ };
+};
+
+&pwm0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm0_pin>;
+ status = "okay";
+};
+
+&pwrap {
+ pmic {
+ compatible = "mediatek,mt6366", "mediatek,mt6358";
+ interrupt-controller;
+ interrupts-extended = <&pio 201 IRQ_TYPE_LEVEL_HIGH>;
+ #interrupt-cells = <2>;
+
+ mt6366codec: codec {
+ compatible = "mediatek,mt6366-sound", "mediatek,mt6358-sound";
+ Avdd-supply = <&mt6366_vaud28_reg>;
+ mediatek,dmic-mode = <1>; /* one-wire */
+ };
+
+ mt6366_regulators: regulators {
+ compatible = "mediatek,mt6366-regulator", "mediatek,mt6358-regulator";
+ vsys-ldo1-supply = <&pp4200_z2>;
+ vsys-ldo2-supply = <&pp4200_z2>;
+ vsys-ldo3-supply = <&pp4200_z2>;
+ vsys-vcore-supply = <&pp4200_z2>;
+ vsys-vdram1-supply = <&pp4200_z2>;
+ vsys-vgpu-supply = <&pp4200_z2>;
+ vsys-vmodem-supply = <&pp4200_z2>;
+ vsys-vpa-supply = <&pp4200_z2>;
+ vsys-vproc11-supply = <&pp4200_z2>;
+ vsys-vproc12-supply = <&pp4200_z2>;
+ vsys-vs1-supply = <&pp4200_z2>;
+ vsys-vs2-supply = <&pp4200_z2>;
+ vs1-ldo1-supply = <&mt6366_vs1_reg>;
+ vs2-ldo1-supply = <&mt6366_vdram1_reg>;
+ vs2-ldo2-supply = <&mt6366_vs2_reg>;
+ vs2-ldo3-supply = <&mt6366_vs2_reg>;
+
+ vcore {
+ regulator-name = "pp0750_dvdd_core";
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <800000>;
+ regulator-ramp-delay = <6250>;
+ regulator-enable-ramp-delay = <200>;
+ regulator-allowed-modes = <MT6397_BUCK_MODE_AUTO
+ MT6397_BUCK_MODE_FORCE_PWM>;
+ regulator-always-on;
+ };
+
+ mt6366_vdram1_reg: vdram1 {
+ regulator-name = "pp1125_emi_vdd2";
+ regulator-min-microvolt = <1125000>;
+ regulator-max-microvolt = <1125000>;
+ regulator-ramp-delay = <12500>;
+ regulator-enable-ramp-delay = <0>;
+ regulator-allowed-modes = <MT6397_BUCK_MODE_AUTO
+ MT6397_BUCK_MODE_FORCE_PWM>;
+ regulator-always-on;
+ };
+
+ mt6366_vgpu_reg: vgpu {
+ /*
+ * Called "ppvar_dvdd_gpu" in the schematic.
+ * Called "ppvar_dvdd_vgpu" here to match
+ * regulator coupling requirements.
+ */
+ regulator-name = "ppvar_dvdd_vgpu";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <6250>;
+ regulator-enable-ramp-delay = <200>;
+ regulator-allowed-modes = <MT6397_BUCK_MODE_AUTO
+ MT6397_BUCK_MODE_FORCE_PWM>;
+ regulator-coupled-with = <&mt6366_vsram_gpu_reg>;
+ regulator-coupled-max-spread = <10000>;
+ };
+
+ mt6366_vproc11_reg: vproc11 {
+ regulator-name = "ppvar_dvdd_proc_bc_mt6366";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-ramp-delay = <6250>;
+ regulator-enable-ramp-delay = <200>;
+ regulator-allowed-modes = <MT6397_BUCK_MODE_AUTO
+ MT6397_BUCK_MODE_FORCE_PWM>;
+ regulator-always-on;
+ };
+
+ mt6366_vproc12_reg: vproc12 {
+ regulator-name = "ppvar_dvdd_proc_lc";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-ramp-delay = <6250>;
+ regulator-enable-ramp-delay = <200>;
+ regulator-allowed-modes = <MT6397_BUCK_MODE_AUTO
+ MT6397_BUCK_MODE_FORCE_PWM>;
+ regulator-always-on;
+ };
+
+ mt6366_vs1_reg: vs1 {
+ regulator-name = "pp2000_vs1";
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-ramp-delay = <12500>;
+ regulator-enable-ramp-delay = <0>;
+ regulator-always-on;
+ };
+
+ mt6366_vs2_reg: vs2 {
+ regulator-name = "pp1350_vs2";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-ramp-delay = <12500>;
+ regulator-enable-ramp-delay = <0>;
+ regulator-always-on;
+ };
+
+ va12 {
+ regulator-name = "pp1200_va12";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-enable-ramp-delay = <270>;
+ regulator-always-on;
+ };
+
+ mt6366_vaud28_reg: vaud28 {
+ regulator-name = "pp2800_vaud28";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+
+ mt6366_vaux18_reg: vaux18 {
+ regulator-name = "pp1840_vaux18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1840000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+
+ mt6366_vbif28_reg: vbif28 {
+ regulator-name = "pp2800_vbif28";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+
+ mt6366_vcn18_reg: vcn18 {
+ regulator-name = "pp1800_vcn18_x";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+
+ mt6366_vcn28_reg: vcn28 {
+ regulator-name = "pp2800_vcn28_x";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+
+ mt6366_vefuse_reg: vefuse {
+ regulator-name = "pp1800_vefuse";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+
+ mt6366_vfe28_reg: vfe28 {
+ regulator-name = "pp2800_vfe28_x";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+
+ mt6366_vemc_reg: vemc {
+ regulator-name = "pp3000_vemc";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-enable-ramp-delay = <60>;
+ };
+
+ mt6366_vibr_reg: vibr {
+ regulator-name = "pp2800_vibr_x";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-enable-ramp-delay = <60>;
+ };
+
+ mt6366_vio18_reg: vio18 {
+ regulator-name = "pp1800_vio18_s3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-enable-ramp-delay = <2700>;
+ regulator-always-on;
+ };
+
+ mt6366_vio28_reg: vio28 {
+ regulator-name = "pp2800_vio28_x";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+
+ mt6366_vm18_reg: vm18 {
+ regulator-name = "pp1800_emi_vdd1";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1840000>;
+ regulator-enable-ramp-delay = <325>;
+ regulator-always-on;
+ };
+
+ mt6366_vmc_reg: vmc {
+ regulator-name = "pp3000_vmc";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-enable-ramp-delay = <60>;
+ };
+
+ mt6366_vmddr_reg: vmddr {
+ regulator-name = "pm0750_emi_vmddr";
+ regulator-min-microvolt = <700000>;
+ regulator-max-microvolt = <750000>;
+ regulator-enable-ramp-delay = <325>;
+ regulator-always-on;
+ };
+
+ mt6366_vmch_reg: vmch {
+ regulator-name = "pp3000_vmch";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-enable-ramp-delay = <60>;
+ };
+
+ mt6366_vcn33_reg: vcn33 {
+ regulator-name = "pp3300_vcn33_x";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+
+ vdram2 {
+ regulator-name = "pp0600_emi_vddq";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <600000>;
+ regulator-enable-ramp-delay = <3300>;
+ regulator-always-on;
+ };
+
+ mt6366_vrf12_reg: vrf12 {
+ regulator-name = "pp1200_vrf12_x";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-enable-ramp-delay = <120>;
+ };
+
+ mt6366_vrf18_reg: vrf18 {
+ regulator-name = "pp1800_vrf18_x";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-enable-ramp-delay = <120>;
+ };
+
+ vsim1 {
+ regulator-name = "pp1860_vsim1_x";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1860000>;
+ regulator-enable-ramp-delay = <540>;
+ };
+
+ mt6366_vsim2_reg: vsim2 {
+ regulator-name = "pp2760_vsim2_x";
+ regulator-min-microvolt = <2700000>;
+ regulator-max-microvolt = <2760000>;
+ regulator-enable-ramp-delay = <540>;
+ };
+
+ mt6366_vsram_gpu_reg: vsram-gpu {
+ regulator-name = "pp0900_dvdd_sram_gpu";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <6250>;
+ regulator-enable-ramp-delay = <240>;
+ regulator-coupled-with = <&mt6366_vgpu_reg>;
+ regulator-coupled-max-spread = <10000>;
+ };
+
+ mt6366_vsram_others_reg: vsram-others {
+ regulator-name = "pp0900_dvdd_sram_core";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+ regulator-ramp-delay = <6250>;
+ regulator-enable-ramp-delay = <240>;
+ regulator-always-on;
+ };
+
+ mt6366_vsram_proc11_reg: vsram-proc11 {
+ regulator-name = "pp0900_dvdd_sram_bc";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1120000>;
+ regulator-ramp-delay = <6250>;
+ regulator-enable-ramp-delay = <240>;
+ regulator-always-on;
+ };
+
+ mt6366_vsram_proc12_reg: vsram-proc12 {
+ regulator-name = "pp0900_dvdd_sram_lc";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <1120000>;
+ regulator-ramp-delay = <6250>;
+ regulator-enable-ramp-delay = <240>;
+ regulator-always-on;
+ };
+
+ vusb {
+ regulator-name = "pp3070_vusb";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3070000>;
+ regulator-enable-ramp-delay = <270>;
+ regulator-always-on;
+ };
+
+ vxo22 {
+ regulator-name = "pp2240_vxo22";
+ regulator-min-microvolt = <2200000>;
+ regulator-max-microvolt = <2240000>;
+ regulator-enable-ramp-delay = <120>;
+ /* Feeds DCXO internally */
+ regulator-always-on;
+ };
+ };
+
+ rtc {
+ compatible = "mediatek,mt6366-rtc", "mediatek,mt6358-rtc";
+ };
+ };
+};
+
+&scp {
+ pinctrl-names = "default";
+ pinctrl-0 = <&scp_pins>;
+ firmware-name = "mediatek/mt8186/scp.img";
+ memory-region = <&scp_mem>;
+ status = "okay";
+
+ cros-ec-rpmsg {
+ compatible = "google,cros-ec-rpmsg";
+ mediatek,rpmsg-name = "cros-ec-rpmsg";
+ };
+};
+
+&spi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_pins>;
+ mediatek,pad-select = <0>;
+ status = "okay";
+
+ cros_ec: ec@0 {
+ compatible = "google,cros-ec-spi";
+ reg = <0>;
+ interrupts-extended = <&pio 13 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ec_ap_int>;
+ spi-max-frequency = <1000000>;
+
+ i2c_tunnel: i2c-tunnel {
+ compatible = "google,cros-ec-i2c-tunnel";
+ google,remote-bus = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ typec {
+ compatible = "google,cros-ec-typec";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ usb_c0: connector@0 {
+ compatible = "usb-c-connector";
+ reg = <0>;
+ label = "left";
+ power-role = "dual";
+ data-role = "host";
+ try-power-role = "source";
+ };
+
+ usb_c1: connector@1 {
+ compatible = "usb-c-connector";
+ reg = <1>;
+ label = "right";
+ power-role = "dual";
+ data-role = "host";
+ try-power-role = "source";
+ };
+ };
+ };
+};
+
+&spi2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2_pins>;
+ cs-gpios = <&pio 45 GPIO_ACTIVE_LOW>;
+ mediatek,pad-select = <0>;
+ status = "okay";
+
+ tpm@0 {
+ compatible = "google,cr50";
+ reg = <0>;
+ interrupts-extended = <&pio 15 IRQ_TYPE_EDGE_RISING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&gsc_int>;
+ spi-max-frequency = <1000000>;
+ };
+};
+
+&ssusb0 {
+ status = "okay";
+};
+
+&ssusb1 {
+ status = "okay";
+};
+
+&u3phy0 {
+ status = "okay";
+};
+
+&u3phy1 {
+ status = "okay";
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&usb_host0 {
+ vbus-supply = <&pp3300_s3>;
+ status = "okay";
+};
+
+&usb_host1 {
+ vbus-supply = <&usb_p1_vbus>;
+ status = "okay";
+};
+
+&watchdog {
+ mediatek,reset-by-toprgu;
+};
+
+#include <arm/cros-ec-keyboard.dtsi>
+#include <arm/cros-ec-sbs.dtsi>
diff --git a/arch/arm64/boot/dts/mediatek/mt8186.dtsi b/arch/arm64/boot/dts/mediatek/mt8186.dtsi
index 2fec6fd1c1a7..4763ed5dc86c 100644
--- a/arch/arm64/boot/dts/mediatek/mt8186.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8186.dtsi
@@ -931,11 +931,17 @@
power-domain@MT8186_POWER_DOMAIN_SSUSB {
reg = <MT8186_POWER_DOMAIN_SSUSB>;
+ clocks = <&topckgen CLK_TOP_USB_TOP>,
+ <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_REF>;
+ clock-names = "sys_ck", "ref_ck";
#power-domain-cells = <0>;
};
power-domain@MT8186_POWER_DOMAIN_SSUSB_P1 {
reg = <MT8186_POWER_DOMAIN_SSUSB_P1>;
+ clocks = <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_SYS>,
+ <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_REF>;
+ clock-names = "sys_ck", "ref_ck";
#power-domain-cells = <0>;
};
@@ -1061,7 +1067,7 @@
reg = <MT8186_POWER_DOMAIN_VENC>;
clocks = <&topckgen CLK_TOP_VENC>,
<&vencsys CLK_VENC_CKE1_VENC>;
- clock-names = "venc0", "larb";
+ clock-names = "venc0", "subsys-larb";
mediatek,infracfg = <&infracfg_ao>;
#power-domain-cells = <0>;
};
@@ -1530,8 +1536,9 @@
clocks = <&topckgen CLK_TOP_USB_TOP>,
<&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_REF>,
<&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_HCLK>,
- <&infracfg_ao CLK_INFRA_AO_ICUSB>;
- clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck";
+ <&infracfg_ao CLK_INFRA_AO_ICUSB>,
+ <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_XHCI>;
+ clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck";
interrupts = <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH 0>;
phys = <&u2port0 PHY_TYPE_USB2>;
power-domains = <&spm MT8186_POWER_DOMAIN_SSUSB>;
@@ -1595,8 +1602,9 @@
clocks = <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_SYS>,
<&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_REF>,
<&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_HCLK>,
- <&clk26m>;
- clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck";
+ <&clk26m>,
+ <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_XHCI>;
+ clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck";
interrupts = <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH 0>;
phys = <&u2port1 PHY_TYPE_USB2>, <&u3port1 PHY_TYPE_USB3>;
power-domains = <&spm MT8186_POWER_DOMAIN_SSUSB_P1>;
@@ -1672,6 +1680,10 @@
reg = <0x59c 0x4>;
bits = <0 3>;
};
+
+ socinfo-data1@7a0 {
+ reg = <0x7a0 0x4>;
+ };
};
mipi_tx0: dsi-phy@11cc0000 {
@@ -1959,6 +1971,43 @@
power-domains = <&spm MT8186_POWER_DOMAIN_IMG2>;
};
+ video_decoder: video-decoder@16000000 {
+ compatible = "mediatek,mt8186-vcodec-dec";
+ reg = <0 0x16000000 0 0x1000>;
+ ranges;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
+ iommus = <&iommu_mm IOMMU_PORT_L4_HW_VDEC_MC_EXT>;
+ mediatek,scp = <&scp>;
+
+ vcodec_core: video-codec@16025000 {
+ compatible = "mediatek,mtk-vcodec-core";
+ reg = <0 0x16025000 0 0x1000>;
+ interrupts = <GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH 0>;
+ iommus = <&iommu_mm IOMMU_PORT_L4_HW_VDEC_MC_EXT>,
+ <&iommu_mm IOMMU_PORT_L4_HW_VDEC_UFO_EXT>,
+ <&iommu_mm IOMMU_PORT_L4_HW_VDEC_PP_EXT>,
+ <&iommu_mm IOMMU_PORT_L4_HW_VDEC_PRED_RD_EXT>,
+ <&iommu_mm IOMMU_PORT_L4_HW_VDEC_PRED_WR_EXT>,
+ <&iommu_mm IOMMU_PORT_L4_HW_VDEC_PPWRAP_EXT>,
+ <&iommu_mm IOMMU_PORT_L4_HW_VDEC_TILE_EXT>,
+ <&iommu_mm IOMMU_PORT_L4_HW_VDEC_VLD_EXT>,
+ <&iommu_mm IOMMU_PORT_L4_HW_VDEC_VLD2_EXT>,
+ <&iommu_mm IOMMU_PORT_L4_HW_VDEC_AVC_MV_EXT>,
+ <&iommu_mm IOMMU_PORT_L4_HW_VDEC_UFO_ENC_EXT>,
+ <&iommu_mm IOMMU_PORT_L4_HW_VDEC_RG_CTRL_DMA_EXT>;
+ clocks = <&topckgen CLK_TOP_VDEC>,
+ <&vdecsys CLK_VDEC_CKEN>,
+ <&vdecsys CLK_VDEC_LARB1_CKEN>,
+ <&topckgen CLK_TOP_UNIVPLL_D3>;
+ clock-names = "vdec-sel", "vdec-soc-vdec", "vdec", "vdec-top";
+ assigned-clocks = <&topckgen CLK_TOP_VDEC>;
+ assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D3>;
+ power-domains = <&spm MT8186_POWER_DOMAIN_VDEC>;
+ };
+ };
+
larb4: smi@1602e000 {
compatible = "mediatek,mt8186-smi-larb";
reg = <0 0x1602e000 0 0x1000>;
@@ -1993,6 +2042,40 @@
power-domains = <&spm MT8186_POWER_DOMAIN_VENC>;
};
+ venc: video-encoder@17020000 {
+ compatible = "mediatek,mt8186-vcodec-enc", "mediatek,mt8183-vcodec-enc";
+ reg = <0 0x17020000 0 0x2000>;
+ interrupts = <GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH 0>;
+ iommus = <&iommu_mm IOMMU_PORT_L7_VENC_RCPU>,
+ <&iommu_mm IOMMU_PORT_L7_VENC_REC>,
+ <&iommu_mm IOMMU_PORT_L7_VENC_BSDMA>,
+ <&iommu_mm IOMMU_PORT_L7_VENC_SV_COMV>,
+ <&iommu_mm IOMMU_PORT_L7_VENC_RD_COMV>,
+ <&iommu_mm IOMMU_PORT_L7_VENC_CUR_LUMA>,
+ <&iommu_mm IOMMU_PORT_L7_VENC_CUR_CHROMA>,
+ <&iommu_mm IOMMU_PORT_L7_VENC_REF_LUMA>,
+ <&iommu_mm IOMMU_PORT_L7_VENC_REF_CHROMA>;
+ clocks = <&vencsys CLK_VENC_CKE1_VENC>;
+ clock-names = "venc_sel";
+ assigned-clocks = <&topckgen CLK_TOP_VENC>;
+ assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D3>;
+ power-domains = <&spm MT8186_POWER_DOMAIN_VENC>;
+ mediatek,scp = <&scp>;
+ };
+
+ jpgenc: jpeg-encoder@17030000 {
+ compatible = "mediatek,mt8186-jpgenc", "mediatek,mtk-jpgenc";
+ reg = <0 0x17030000 0 0x10000>;
+ interrupts = <GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&vencsys CLK_VENC_CKE2_JPGENC>;
+ clock-names = "jpgenc";
+ iommus = <&iommu_mm IOMMU_PORT_L7_JPGENC_Y_RDMA>,
+ <&iommu_mm IOMMU_PORT_L7_JPGENC_C_RDMA>,
+ <&iommu_mm IOMMU_PORT_L7_JPGENC_Q_TABLE>,
+ <&iommu_mm IOMMU_PORT_L7_JPGENC_BSDMA>;
+ power-domains = <&spm MT8186_POWER_DOMAIN_VENC>;
+ };
+
camsys: clock-controller@1a000000 {
compatible = "mediatek,mt8186-camsys";
reg = <0 0x1a000000 0 0x1000>;
diff --git a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
index d87aab8d7a79..9b738f6a5d21 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
@@ -1332,14 +1332,11 @@
spi-max-frequency = <3000000>;
pinctrl-names = "default";
pinctrl-0 = <&cros_ec_int>;
+ wakeup-source;
#address-cells = <1>;
#size-cells = <0>;
- base_detection: cbas {
- compatible = "google,cros-cbas";
- };
-
cros_ec_pwm: pwm {
compatible = "google,cros-ec-pwm";
#pwm-cells = <1>;
diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index 6dd32dbfb832..05e401670bce 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -1164,6 +1164,14 @@
#address-cells = <1>;
#size-cells = <1>;
+ socinfo-data1@44 {
+ reg = <0x044 0x4>;
+ };
+
+ socinfo-data2@50 {
+ reg = <0x050 0x4>;
+ };
+
lvts_e_data1: data1@1c0 {
reg = <0x1c0 0x58>;
};
@@ -1814,7 +1822,7 @@
mediatek,scp = <&scp>;
power-domains = <&spm MT8192_POWER_DOMAIN_VENC>;
clocks = <&vencsys CLK_VENC_SET1_VENC>;
- clock-names = "venc-set1";
+ clock-names = "venc_sel";
assigned-clocks = <&topckgen CLK_TOP_VENC_SEL>;
assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D4>;
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r1.dts b/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r1.dts
index 2d5e8f371b6d..a82d716f10d4 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r1.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r1.dts
@@ -23,3 +23,7 @@
&ts_10 {
status = "okay";
};
+
+&watchdog {
+ /delete-property/ mediatek,disable-extrst;
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r2.dts b/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r2.dts
index 2586c32ce6e6..2fe20e0dad83 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r2.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r2.dts
@@ -43,3 +43,7 @@
&ts_10 {
status = "okay";
};
+
+&watchdog {
+ /delete-property/ mediatek,disable-extrst;
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r3.dts b/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r3.dts
index f54f9477b99d..dd294ca98194 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r3.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r3.dts
@@ -44,3 +44,7 @@
&ts_10 {
status = "okay";
};
+
+&watchdog {
+ /delete-property/ mediatek,disable-extrst;
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
index 3c6079edda19..f94c07f8b933 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
@@ -1149,6 +1149,7 @@
pinctrl-names = "default";
pinctrl-0 = <&cros_ec_int>;
spi-max-frequency = <3000000>;
+ wakeup-source;
keyboard-backlight {
compatible = "google,cros-kbd-led-backlight";
@@ -1291,11 +1292,32 @@
status = "okay";
};
+/*
+ * For the USB Type-C ports the role and alternate modes switching is
+ * done by the EC so we set dr_mode to host to avoid interfering.
+ */
+&ssusb0 {
+ dr_mode = "host";
+ vusb33-supply = <&mt6359_vusb_ldo_reg>;
+ status = "okay";
+};
+
+&ssusb2 {
+ dr_mode = "host";
+ vusb33-supply = <&mt6359_vusb_ldo_reg>;
+ status = "okay";
+};
+
+&ssusb3 {
+ dr_mode = "host";
+ vusb33-supply = <&mt6359_vusb_ldo_reg>;
+ status = "okay";
+};
+
&xhci0 {
status = "okay";
rx-fifo-depth = <3072>;
- vusb33-supply = <&mt6359_vusb_ldo_reg>;
vbus-supply = <&usb_vbus>;
};
@@ -1309,8 +1331,6 @@
&xhci2 {
status = "okay";
-
- vusb33-supply = <&mt6359_vusb_ldo_reg>;
vbus-supply = <&usb_vbus>;
};
@@ -1319,7 +1339,6 @@
/* MT7921's USB Bluetooth has issues with USB2 LPM */
usb2-lpm-disable;
- vusb33-supply = <&mt6359_vusb_ldo_reg>;
vbus-supply = <&usb_vbus>;
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8195-demo.dts b/arch/arm64/boot/dts/mediatek/mt8195-demo.dts
index 4127cb84eba4..b82f7176b4a1 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195-demo.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8195-demo.dts
@@ -529,8 +529,22 @@
status = "okay";
};
-&xhci0 {
+&ssusb0 {
+ vusb33-supply = <&mt6359_vusb_ldo_reg>;
+ status = "okay";
+};
+
+&ssusb2 {
vusb33-supply = <&mt6359_vusb_ldo_reg>;
+ status = "okay";
+};
+
+&ssusb3 {
+ vusb33-supply = <&mt6359_vusb_ldo_reg>;
+ status = "okay";
+};
+
+&xhci0 {
vbus-supply = <&otg_vbus_regulator>;
status = "okay";
};
@@ -541,11 +555,9 @@
};
&xhci2 {
- vusb33-supply = <&mt6359_vusb_ldo_reg>;
status = "okay";
};
&xhci3 {
- vusb33-supply = <&mt6359_vusb_ldo_reg>;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8195-evb.dts b/arch/arm64/boot/dts/mediatek/mt8195-evb.dts
index 690dc7717f2c..341b6e074139 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8195-evb.dts
@@ -160,6 +160,18 @@
status = "okay";
};
+&ssusb0 {
+ status = "okay";
+};
+
+&ssusb2 {
+ status = "okay";
+};
+
+&ssusb3 {
+ status = "okay";
+};
+
&xhci0 {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index b9101662ce40..ea6dc220e1cc 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -1347,29 +1347,40 @@
};
};
- xhci0: usb@11200000 {
- compatible = "mediatek,mt8195-xhci",
- "mediatek,mtk-xhci";
- reg = <0 0x11200000 0 0x1000>,
- <0 0x11203e00 0 0x0100>;
+ ssusb0: usb@11201000 {
+ compatible = "mediatek,mt8195-mtu3", "mediatek,mtu3";
+ reg = <0 0x11201000 0 0x2dff>, <0 0x11203e00 0 0x0100>;
reg-names = "mac", "ippc";
- interrupts = <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH 0>;
- phys = <&u2port0 PHY_TYPE_USB2>,
- <&u3port0 PHY_TYPE_USB3>;
- assigned-clocks = <&topckgen CLK_TOP_USB_TOP>,
- <&topckgen CLK_TOP_SSUSB_XHCI>;
- assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D5_D4>,
- <&topckgen CLK_TOP_UNIVPLL_D5_D4>;
+ ranges = <0 0 0 0x11200000 0 0x3f00>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH 0>;
clocks = <&infracfg_ao CLK_INFRA_AO_SSUSB>,
<&topckgen CLK_TOP_SSUSB_REF>,
- <&apmixedsys CLK_APMIXED_USB1PLL>,
- <&clk26m>,
<&infracfg_ao CLK_INFRA_AO_SSUSB_XHCI>;
- clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck",
- "xhci_ck";
- mediatek,syscon-wakeup = <&pericfg 0x400 103>;
+ clock-names = "sys_ck", "ref_ck", "mcu_ck";
+ phys = <&u2port0 PHY_TYPE_USB2>, <&u3port0 PHY_TYPE_USB3>;
wakeup-source;
+ mediatek,syscon-wakeup = <&pericfg 0x400 103>;
status = "disabled";
+
+ xhci0: usb@0 {
+ compatible = "mediatek,mt8195-xhci", "mediatek,mtk-xhci";
+ reg = <0 0 0 0x1000>;
+ reg-names = "mac";
+ interrupts = <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH 0>;
+ assigned-clocks = <&topckgen CLK_TOP_USB_TOP>,
+ <&topckgen CLK_TOP_SSUSB_XHCI>;
+ assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D5_D4>,
+ <&topckgen CLK_TOP_UNIVPLL_D5_D4>;
+ clocks = <&infracfg_ao CLK_INFRA_AO_SSUSB>,
+ <&topckgen CLK_TOP_SSUSB_REF>,
+ <&apmixedsys CLK_APMIXED_USB1PLL>,
+ <&clk26m>,
+ <&infracfg_ao CLK_INFRA_AO_SSUSB_XHCI>;
+ clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck";
+ status = "disabled";
+ };
};
mmc0: mmc@11230000 {
@@ -1450,52 +1461,68 @@
status = "disabled";
};
- xhci2: usb@112a0000 {
- compatible = "mediatek,mt8195-xhci",
- "mediatek,mtk-xhci";
- reg = <0 0x112a0000 0 0x1000>,
- <0 0x112a3e00 0 0x0100>;
+ ssusb2: usb@112a1000 {
+ compatible = "mediatek,mt8195-mtu3", "mediatek,mtu3";
+ reg = <0 0x112a1000 0 0x2dff>, <0 0x112a3e00 0 0x0100>;
reg-names = "mac", "ippc";
- interrupts = <GIC_SPI 533 IRQ_TYPE_LEVEL_HIGH 0>;
- phys = <&u2port2 PHY_TYPE_USB2>;
- assigned-clocks = <&topckgen CLK_TOP_USB_TOP_2P>,
- <&topckgen CLK_TOP_SSUSB_XHCI_2P>;
- assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D5_D4>,
- <&topckgen CLK_TOP_UNIVPLL_D5_D4>;
+ ranges = <0 0 0 0x112a0000 0 0x3f00>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupts = <GIC_SPI 532 IRQ_TYPE_LEVEL_HIGH 0>;
+ assigned-clocks = <&topckgen CLK_TOP_USB_TOP_2P>;
+ assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D5_D4>;
clocks = <&pericfg_ao CLK_PERI_AO_SSUSB_2P_BUS>,
<&topckgen CLK_TOP_SSUSB_P2_REF>,
- <&clk26m>,
- <&clk26m>,
<&pericfg_ao CLK_PERI_AO_SSUSB_2P_XHCI>;
- clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck",
- "xhci_ck";
- mediatek,syscon-wakeup = <&pericfg 0x400 105>;
+ clock-names = "sys_ck", "ref_ck", "mcu_ck";
+ phys = <&u2port2 PHY_TYPE_USB2>;
wakeup-source;
+ mediatek,syscon-wakeup = <&pericfg 0x400 105>;
status = "disabled";
+
+ xhci2: usb@0 {
+ compatible = "mediatek,mt8195-xhci", "mediatek,mtk-xhci";
+ reg = <0 0 0 0x1000>;
+ reg-names = "mac";
+ interrupts = <GIC_SPI 533 IRQ_TYPE_LEVEL_HIGH 0>;
+ assigned-clocks = <&topckgen CLK_TOP_SSUSB_XHCI_2P>;
+ assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D5_D4>;
+ clocks = <&pericfg_ao CLK_PERI_AO_SSUSB_2P_XHCI>;
+ clock-names = "sys_ck";
+ status = "disabled";
+ };
};
- xhci3: usb@112b0000 {
- compatible = "mediatek,mt8195-xhci",
- "mediatek,mtk-xhci";
- reg = <0 0x112b0000 0 0x1000>,
- <0 0x112b3e00 0 0x0100>;
+ ssusb3: usb@112b1000 {
+ compatible = "mediatek,mt8195-mtu3", "mediatek,mtu3";
+ reg = <0 0x112b1000 0 0x2dff>, <0 0x112b3e00 0 0x0100>;
reg-names = "mac", "ippc";
- interrupts = <GIC_SPI 536 IRQ_TYPE_LEVEL_HIGH 0>;
- phys = <&u2port3 PHY_TYPE_USB2>;
- assigned-clocks = <&topckgen CLK_TOP_USB_TOP_3P>,
- <&topckgen CLK_TOP_SSUSB_XHCI_3P>;
- assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D5_D4>,
- <&topckgen CLK_TOP_UNIVPLL_D5_D4>;
+ ranges = <0 0 0 0x112b0000 0 0x3f00>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupts = <GIC_SPI 535 IRQ_TYPE_LEVEL_HIGH 0>;
+ assigned-clocks = <&topckgen CLK_TOP_USB_TOP_3P>;
+ assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D5_D4>;
clocks = <&pericfg_ao CLK_PERI_AO_SSUSB_3P_BUS>,
<&topckgen CLK_TOP_SSUSB_P3_REF>,
- <&clk26m>,
- <&clk26m>,
<&pericfg_ao CLK_PERI_AO_SSUSB_3P_XHCI>;
- clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck",
- "xhci_ck";
- mediatek,syscon-wakeup = <&pericfg 0x400 106>;
+ clock-names = "sys_ck", "ref_ck", "mcu_ck";
+ phys = <&u2port3 PHY_TYPE_USB2>;
wakeup-source;
+ mediatek,syscon-wakeup = <&pericfg 0x400 106>;
status = "disabled";
+
+ xhci3: usb@0 {
+ compatible = "mediatek,mt8195-xhci", "mediatek,mtk-xhci";
+ reg = <0 0 0 0x1000>;
+ reg-names = "mac";
+ interrupts = <GIC_SPI 536 IRQ_TYPE_LEVEL_HIGH 0>;
+ assigned-clocks = <&topckgen CLK_TOP_SSUSB_XHCI_3P>;
+ assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D5_D4>;
+ clocks = <&pericfg_ao CLK_PERI_AO_SSUSB_3P_XHCI>;
+ clock-names = "sys_ck";
+ status = "disabled";
+ };
};
pcie0: pcie@112f0000 {
@@ -1701,6 +1728,9 @@
svs_calib_data: svs-calib@580 {
reg = <0x580 0x64>;
};
+ socinfo-data1@7a0 {
+ reg = <0x7a0 0x4>;
+ };
};
u3phy2: t-phy@11c40000 {
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 7fc515a07c65..1558649f633c 100644
--- a/arch/arm64/boot/dts/mediatek/mt8395-genio-1200-evk.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8395-genio-1200-evk.dts
@@ -880,6 +880,21 @@
status = "disabled";
};
+&ssusb0 {
+ vusb33-supply = <&mt6359_vusb_ldo_reg>;
+ status = "okay";
+};
+
+&ssusb2 {
+ vusb33-supply = <&mt6359_vusb_ldo_reg>;
+ status = "okay";
+};
+
+&ssusb3 {
+ vusb33-supply = <&mt6359_vusb_ldo_reg>;
+ status = "okay";
+};
+
&xhci0 {
status = "okay";
};
@@ -890,11 +905,9 @@
};
&xhci2 {
- vusb33-supply = <&mt6359_vusb_ldo_reg>;
status = "okay";
};
&xhci3 {
- vusb33-supply = <&mt6359_vusb_ldo_reg>;
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
new file mode 100644
index 000000000000..e5d9b671a405
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8395-radxa-nio-12l.dts
@@ -0,0 +1,825 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2023 Radxa Limited
+ * Copyright (C) 2024 Collabora Ltd.
+ * AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+ */
+
+#include "mt8195.dtsi"
+#include "mt6359.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/mt8195-pinfunc.h>
+#include <dt-bindings/regulator/mediatek,mt6360-regulator.h>
+#include <dt-bindings/spmi/spmi.h>
+#include <dt-bindings/usb/pd.h>
+
+/ {
+ model = "Radxa NIO 12L";
+ chassis-type = "embedded";
+ compatible = "radxa,nio-12l", "mediatek,mt8395", "mediatek,mt8195";
+
+ aliases {
+ i2c0 = &i2c2;
+ i2c1 = &i2c3;
+ i2c2 = &i2c4;
+ i2c3 = &i2c0;
+ i2c4 = &i2c1;
+ ethernet0 = &eth;
+ serial0 = &uart0;
+ serial1 = &uart1;
+ spi0 = &spi1;
+ spi1 = &spi2;
+ };
+
+ chosen {
+ stdout-path = "serial0:921600n8";
+ };
+
+ firmware {
+ optee {
+ compatible = "linaro,optee-tz";
+ method = "smc";
+ };
+ };
+
+ memory@40000000 {
+ device_type = "memory";
+ reg = <0 0x40000000 0x1 0x0>;
+ };
+
+ wifi_vreg: regulator-wifi-3v3-en {
+ compatible = "regulator-fixed";
+ regulator-name = "wifi_3v3_en";
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&pio 67 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&wifi_vreg_pins>;
+ vin-supply = <&vsys>;
+ };
+
+ /* system wide switching 5.0V power rail */
+ vsys: regulator-vsys {
+ compatible = "regulator-fixed";
+ regulator-name = "vsys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_vsys>;
+ };
+
+ vsys_buck: regulator-vsys-buck {
+ compatible = "regulator-fixed";
+ regulator-name = "vsys_buck";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_vsys>;
+ };
+
+ /* Rail from power-only "TYPE C DC" port */
+ vcc5v0_vsys: regulator-vcc5v0-sys {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ 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 {
+ reg = <0 0x43200000 0 0xc00000>;
+ no-map;
+ };
+
+ 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 {
+ reg = <0 0x54600000 0x0 0x200000>;
+ no-map;
+ };
+
+ afe_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 */
+ };
+ };
+};
+
+&eth {
+ phy-mode = "rgmii-rxid";
+ phy-handle = <&rgmii_phy>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&eth_default_pins>;
+ pinctrl-1 = <&eth_sleep_pins>;
+ mediatek,tx-delay-ps = <2030>;
+ mediatek,mac-wol;
+ snps,reset-gpio = <&pio 93 GPIO_ACTIVE_HIGH>;
+ snps,reset-delays-us = <0 20000 100000>;
+ status = "okay";
+
+ mdio {
+ rgmii_phy: ethernet-phy@1 {
+ compatible = "ethernet-phy-id001c.c916";
+ reg = <0x1>;
+ };
+ };
+};
+
+&gpu {
+ mali-supply = <&mt6315_7_vbuck1>;
+ status = "okay";
+};
+
+&i2c2 {
+ clock-frequency = <400000>;
+ pinctrl-0 = <&i2c2_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ typec-mux@48 {
+ compatible = "ite,it5205";
+ reg = <0x48>;
+
+ mode-switch;
+ orientation-switch;
+
+ vcc-supply = <&mt6359_vibr_ldo_reg>;
+
+ port {
+ it5205_sbu_mux: endpoint {
+ remote-endpoint = <&typec_con_mux>;
+ };
+ };
+ };
+};
+
+&i2c4 {
+ clock-frequency = <400000>;
+ pinctrl-0 = <&i2c4_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ /* I2C4 exposed at 39-pins MIPI-LCD connector */
+};
+
+&i2c6 {
+ clock-frequency = <400000>;
+ pinctrl-0 = <&i2c6_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ mt6360: pmic@34 {
+ compatible = "mediatek,mt6360";
+ reg = <0x34>;
+ interrupts-extended = <&pio 101 IRQ_TYPE_EDGE_FALLING>;
+ interrupt-names = "IRQB";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ pinctrl-0 = <&mt6360_pins>;
+
+ charger {
+ compatible = "mediatek,mt6360-chg";
+ richtek,vinovp-microvolt = <14500000>;
+
+ otg_vbus_regulator: usb-otg-vbus-regulator {
+ regulator-name = "usb-otg-vbus";
+ regulator-min-microvolt = <4425000>;
+ regulator-max-microvolt = <5825000>;
+ };
+ };
+
+ regulator {
+ compatible = "mediatek,mt6360-regulator";
+ LDO_VIN1-supply = <&vsys_buck>;
+ LDO_VIN3-supply = <&mt6360_buck2>;
+
+ mt6360_buck1: buck1 {
+ regulator-name = "emi_vdd2";
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1300000>;
+ 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 = "ext_lcd_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+ MT6360_OPMODE_LP>;
+ regulator-always-on;
+ };
+
+ 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 = <1200000>;
+ regulator-max-microvolt = <3600000>;
+ 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>;
+ regulator-always-on;
+ };
+
+ 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 = <500000>;
+ regulator-max-microvolt = <2100000>;
+ regulator-allowed-modes = <MT6360_OPMODE_NORMAL
+ MT6360_OPMODE_LP>;
+ regulator-always-on;
+ };
+ };
+
+ typec {
+ compatible = "mediatek,mt6360-tcpc";
+ interrupts-extended = <&pio 100 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-names = "PD_IRQB";
+
+ connector {
+ compatible = "usb-c-connector";
+ label = "USB-C";
+ data-role = "dual";
+ op-sink-microwatt = <10000000>;
+ power-role = "dual";
+ try-power-role = "sink";
+
+ source-pdos = <PDO_FIXED(5000, 1000,
+ PDO_FIXED_DUAL_ROLE |
+ PDO_FIXED_DATA_SWAP)>;
+ sink-pdos = <PDO_FIXED(5000, 3000,
+ PDO_FIXED_DUAL_ROLE |
+ PDO_FIXED_DATA_SWAP)>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ typec_con_hs: endpoint {
+ remote-endpoint = <&mtu3_hs0_role_sw>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+ typec_con_mux: endpoint {
+ remote-endpoint = <&it5205_sbu_mux>;
+ };
+ };
+ };
+ };
+ };
+ };
+};
+
+/* MMC0 Controller: eMMC (HS400). Power lines are shared with UFS! */
+&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 Controller: MicroSD card slot */
+&mmc1 {
+ pinctrl-names = "default", "state_uhs";
+ pinctrl-0 = <&mmc1_default_pins>, <&mmc1_pins_detect>;
+ pinctrl-1 = <&mmc1_default_pins>;
+ bus-width = <4>;
+ max-frequency = <200000000>;
+ cap-sd-highspeed;
+ cd-gpios = <&pio 129 GPIO_ACTIVE_LOW>;
+ no-mmc;
+ no-sdio;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+ vmmc-supply = <&mt6360_ldo5>;
+ vqmmc-supply = <&mt6360_ldo3>;
+ status = "okay";
+};
+
+&mt6359_vaud18_ldo_reg {
+ regulator-always-on;
+};
+
+&mt6359_vbbck_ldo_reg {
+ regulator-always-on;
+};
+
+/* For USB Hub */
+&mt6359_vcamio_ldo_reg {
+ regulator-always-on;
+};
+
+&mt6359_vcn33_2_bt_ldo_reg {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+};
+
+&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;
+};
+
+/* for GPU SRAM */
+&mt6359_vsram_others_ldo_reg {
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+};
+
+&pio {
+ eth_default_pins: eth-default-pins {
+ 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-rst {
+ pinmux = <PINMUX_GPIO93__FUNC_GPIO93>;
+ };
+
+ pins-rxd {
+ pinmux = <PINMUX_GPIO81__FUNC_GBE_RXD3>,
+ <PINMUX_GPIO82__FUNC_GBE_RXD2>,
+ <PINMUX_GPIO83__FUNC_GBE_RXD1>,
+ <PINMUX_GPIO84__FUNC_GBE_RXD0>;
+ };
+
+ 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>;
+ };
+ };
+
+ eth_sleep_pins: eth-sleep-pins {
+ pins-cc {
+ pinmux = <PINMUX_GPIO85__FUNC_GPIO85>,
+ <PINMUX_GPIO86__FUNC_GPIO86>,
+ <PINMUX_GPIO87__FUNC_GPIO87>,
+ <PINMUX_GPIO88__FUNC_GPIO88>;
+ };
+
+ pins-mdio {
+ pinmux = <PINMUX_GPIO89__FUNC_GPIO89>,
+ <PINMUX_GPIO90__FUNC_GPIO90>;
+ bias-disable;
+ input-disable;
+ };
+
+ pins-rxd {
+ pinmux = <PINMUX_GPIO81__FUNC_GPIO81>,
+ <PINMUX_GPIO82__FUNC_GPIO82>,
+ <PINMUX_GPIO83__FUNC_GPIO83>,
+ <PINMUX_GPIO84__FUNC_GPIO84>;
+ };
+
+ pins-txd {
+ pinmux = <PINMUX_GPIO77__FUNC_GPIO77>,
+ <PINMUX_GPIO78__FUNC_GPIO78>,
+ <PINMUX_GPIO79__FUNC_GPIO79>,
+ <PINMUX_GPIO80__FUNC_GPIO80>;
+ };
+ };
+
+ i2c2_pins: i2c2-pins {
+ pins-bus {
+ pinmux = <PINMUX_GPIO12__FUNC_SDA2>,
+ <PINMUX_GPIO13__FUNC_SCL2>;
+ bias-pull-up = <MTK_PULL_SET_RSEL_111>;
+ drive-strength = <6>;
+ drive-strength-microamp = <1000>;
+ };
+ };
+
+ i2c4_pins: i2c4-pins {
+ pins-bus {
+ 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 = <MTK_PULL_SET_RSEL_111>;
+ };
+ };
+
+ mmc0_default_pins: mmc0-default-pins {
+ pins-clk {
+ pinmux = <PINMUX_GPIO122__FUNC_MSDC0_CLK>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ drive-strength = <6>;
+ };
+
+ 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>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ drive-strength = <6>;
+ input-enable;
+ };
+
+ pins-rst {
+ pinmux = <PINMUX_GPIO120__FUNC_MSDC0_RSTB>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ drive-strength = <6>;
+ };
+ };
+
+ mmc0_uhs_pins: mmc0-uhs-pins {
+ pins-clk {
+ pinmux = <PINMUX_GPIO122__FUNC_MSDC0_CLK>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ drive-strength = <8>;
+ };
+
+ 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>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ drive-strength = <8>;
+ input-enable;
+ };
+
+ pins-ds {
+ pinmux = <PINMUX_GPIO127__FUNC_MSDC0_DSL>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ drive-strength = <8>;
+ };
+
+ pins-rst {
+ pinmux = <PINMUX_GPIO120__FUNC_MSDC0_RSTB>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ drive-strength = <8>;
+ };
+ };
+
+ mmc1_default_pins: mmc1-default-pins {
+ pins-clk {
+ pinmux = <PINMUX_GPIO111__FUNC_MSDC1_CLK>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ drive-strength = <8>;
+ };
+
+ 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>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+ drive-strength = <8>;
+ input-enable;
+ };
+ };
+
+ mmc1_pins_detect: mmc1-detect-pins {
+ pins-insert {
+ pinmux = <PINMUX_GPIO129__FUNC_GPIO129>;
+ bias-pull-up;
+ };
+ };
+
+ mt6360_pins: mt6360-pins {
+ pins-irq {
+ pinmux = <PINMUX_GPIO100__FUNC_GPIO100>,
+ <PINMUX_GPIO101__FUNC_GPIO101>;
+ input-enable;
+ bias-pull-up;
+ };
+ };
+
+ pcie0_default_pins: pcie0-default-pins {
+ pins-bus {
+ pinmux = <PINMUX_GPIO19__FUNC_WAKEN>,
+ <PINMUX_GPIO20__FUNC_PERSTN>,
+ <PINMUX_GPIO21__FUNC_CLKREQN>;
+ bias-pull-up;
+ };
+ };
+
+ pcie1_default_pins: pcie1-default-pins {
+ pins-bus {
+ pinmux = <PINMUX_GPIO0__FUNC_PERSTN_1>,
+ <PINMUX_GPIO1__FUNC_CLKREQN_1>,
+ <PINMUX_GPIO2__FUNC_WAKEN_1>;
+ bias-disable;
+ };
+ };
+
+ spi1_pins: spi1-default-pins {
+ pins-bus {
+ pinmux = <PINMUX_GPIO136__FUNC_SPIM1_CSB>,
+ <PINMUX_GPIO137__FUNC_SPIM1_CLK>,
+ <PINMUX_GPIO138__FUNC_SPIM1_MO>,
+ <PINMUX_GPIO139__FUNC_SPIM1_MI>;
+ bias-disable;
+ };
+ };
+
+ spi2_pins: spi2-default-pins {
+ pins-bus {
+ pinmux = <PINMUX_GPIO140__FUNC_SPIM2_CSB>,
+ <PINMUX_GPIO141__FUNC_SPIM2_CLK>,
+ <PINMUX_GPIO142__FUNC_SPIM2_MO>,
+ <PINMUX_GPIO143__FUNC_SPIM2_MI>;
+ bias-disable;
+ };
+ };
+
+ uart0_pins: uart0-pins {
+ pins-bus {
+ pinmux = <PINMUX_GPIO98__FUNC_UTXD0>,
+ <PINMUX_GPIO99__FUNC_URXD0>;
+ };
+ };
+
+ uart1_pins: uart1-pins {
+ pins-bus {
+ pinmux = <PINMUX_GPIO102__FUNC_UTXD1>,
+ <PINMUX_GPIO103__FUNC_URXD1>;
+ };
+ };
+
+ wifi_vreg_pins: wifi-vreg-pins {
+ pins-wifi-pmu-en {
+ pinmux = <PINMUX_GPIO65__FUNC_GPIO65>;
+ output-high;
+ };
+
+ pins-wifi-vreg-en {
+ pinmux = <PINMUX_GPIO67__FUNC_GPIO67>;
+ };
+ };
+};
+
+&pcie0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie0_default_pins>;
+ status = "okay";
+};
+
+&pcie1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie1_default_pins>;
+ status = "okay";
+};
+
+&pmic {
+ interrupts-extended = <&pio 222 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&scp {
+ memory-region = <&scp_mem>;
+ status = "okay";
+};
+
+&spi1 {
+ /* Exposed at 40 pin connector */
+ pinctrl-0 = <&spi1_pins>;
+ pinctrl-names = "default";
+ mediatek,pad-select = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+};
+
+&spi2 {
+ /* Exposed at 40 pin connector */
+ pinctrl-0 = <&spi2_pins>;
+ pinctrl-names = "default";
+ mediatek,pad-select = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+};
+
+&spmi {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ mt6315_6: pmic@6 {
+ compatible = "mediatek,mt6315-regulator";
+ reg = <0x6 SPMI_USID>;
+
+ regulators {
+ mt6315_6_vbuck1: vbuck1 {
+ regulator-compatible = "vbuck1";
+ regulator-name = "Vbcpu";
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1193750>;
+ regulator-enable-ramp-delay = <256>;
+ regulator-allowed-modes = <0 1 2>;
+ regulator-always-on;
+ };
+ };
+ };
+
+ mt6315_7: pmic@7 {
+ compatible = "mediatek,mt6315-regulator";
+ reg = <0x7 SPMI_USID>;
+
+ regulators {
+ mt6315_7_vbuck1: vbuck1 {
+ regulator-compatible = "vbuck1";
+ regulator-name = "Vgpu";
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1193750>;
+ regulator-enable-ramp-delay = <256>;
+ regulator-allowed-modes = <0 1 2>;
+ };
+ };
+ };
+};
+
+&uart0 {
+ /* Exposed at 40 pin connector */
+ pinctrl-0 = <&uart0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&uart1 {
+ /* Exposed at 40 pin connector */
+ pinctrl-0 = <&uart1_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&ssusb0 {
+ role-switch-default-mode = "host";
+ usb-role-switch;
+ vusb33-supply = <&mt6359_vusb_ldo_reg>;
+ status = "okay";
+
+ port {
+ mtu3_hs0_role_sw: endpoint {
+ remote-endpoint = <&typec_con_hs>;
+ };
+ };
+};
+
+&ssusb2 {
+ vusb33-supply = <&mt6359_vusb_ldo_reg>;
+ status = "okay";
+};
+
+&xhci0 {
+ vbus-supply = <&otg_vbus_regulator>;
+ status = "okay";
+};
+
+&xhci1 {
+ /* MT7921's USB Bluetooth has issues with USB2 LPM */
+ usb2-lpm-disable;
+ vusb33-supply = <&mt6359_vusb_ldo_reg>;
+ vbus-supply = <&vsys>;
+ status = "okay";
+};
+
+&xhci2 {
+ vbus-supply = <&vsys>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts b/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts
index bbc2e9bef08d..14d58859bb55 100644
--- a/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts
@@ -762,6 +762,7 @@
interrupt-parent = <&gpio>;
interrupts = <TEGRA_GPIO(C, 7) IRQ_TYPE_LEVEL_LOW>;
reg = <0>;
+ wakeup-source;
google,cros-ec-spi-msg-delay = <2000>;
diff --git a/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi b/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi
index 5b59c1986e9b..e8b296d9e0d3 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi
@@ -53,6 +53,56 @@
status = "okay";
};
+ i2c@c240000 {
+ status = "okay";
+
+ power-sensor@40 {
+ compatible = "ti,ina3221";
+ reg = <0x40>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ input@0 {
+ reg = <0x0>;
+ label = "GPU";
+ shunt-resistor-micro-ohms = <5000>;
+ };
+ input@1 {
+ reg = <0x1>;
+ label = "CPU";
+ shunt-resistor-micro-ohms = <5000>;
+ };
+ input@2 {
+ reg = <0x2>;
+ label = "SOC";
+ shunt-resistor-micro-ohms = <5000>;
+ };
+ };
+
+ power-sensor@41 {
+ compatible = "ti,ina3221";
+ reg = <0x41>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ input@0 {
+ reg = <0x0>;
+ label = "CV";
+ shunt-resistor-micro-ohms = <5000>;
+ };
+ input@1 {
+ reg = <0x1>;
+ label = "VDDRQ";
+ shunt-resistor-micro-ohms = <5000>;
+ };
+ input@2 {
+ reg = <0x2>;
+ label = "SYS5V";
+ shunt-resistor-micro-ohms = <5000>;
+ };
+ };
+ };
+
serial@3110000 {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/nvidia/tegra194-p2972-0000.dts b/arch/arm64/boot/dts/nvidia/tegra194-p2972-0000.dts
index 64a3398fe7a6..c32876699a43 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194-p2972-0000.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra194-p2972-0000.dts
@@ -2062,8 +2062,15 @@
ports {
usb2-0 {
- mode = "host";
+ mode = "otg";
+ usb-role-switch;
status = "okay";
+
+ port {
+ hs_typec_p0: endpoint {
+ remote-endpoint = <&hs_ucsi_ccg_p0>;
+ };
+ };
};
usb2-1 {
@@ -2094,6 +2101,14 @@
};
};
+ usb@3550000 {
+ status = "okay";
+
+ phys = <&{/bus@0/padctl@3520000/pads/usb2/lanes/usb2-0}>,
+ <&{/bus@0/padctl@3520000/pads/usb3/lanes/usb3-2}>;
+ phy-names = "usb2-0", "usb3-0";
+ };
+
usb@3610000 {
status = "okay";
@@ -2106,6 +2121,40 @@
phy-names = "usb2-0", "usb2-1", "usb2-3", "usb3-0", "usb3-2", "usb3-3";
};
+ i2c@c240000 {
+ typec@8 {
+ compatible = "cypress,cypd4226";
+ reg = <0x08>;
+ interrupt-parent = <&gpio_aon>;
+ interrupts = <TEGRA194_AON_GPIO(BB, 2) IRQ_TYPE_LEVEL_LOW>;
+ firmware-name = "nvidia,jetson-agx-xavier";
+ status = "okay";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ccg_typec_con0: connector@0 {
+ compatible = "usb-c-connector";
+ reg = <0>;
+ label = "USB-C";
+ data-role = "dual";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ hs_ucsi_ccg_p0: endpoint {
+ remote-endpoint = <&hs_typec_p0>;
+ };
+ };
+ };
+ };
+ };
+ };
+
i2c@c250000 {
status = "okay";
diff --git a/arch/arm64/boot/dts/nvidia/tegra194-p3668.dtsi b/arch/arm64/boot/dts/nvidia/tegra194-p3668.dtsi
index 58f190b0f868..59860d19f0f6 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194-p3668.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra194-p3668.dtsi
@@ -50,6 +50,33 @@
status = "okay";
};
+ i2c@c250000 {
+ status = "okay";
+
+ power-sensor@40 {
+ compatible = "ti,ina3221";
+ reg = <0x40>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ input@0 {
+ reg = <0x0>;
+ label = "VDD_IN";
+ shunt-resistor-micro-ohms = <5000>;
+ };
+ input@1 {
+ reg = <0x1>;
+ label = "VDD_CPU_GPU_CV";
+ shunt-resistor-micro-ohms = <5000>;
+ };
+ input@2 {
+ reg = <0x2>;
+ label = "VDD_SOC";
+ shunt-resistor-micro-ohms = <5000>;
+ };
+ };
+ };
+
serial@3100000 {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3701.dtsi b/arch/arm64/boot/dts/nvidia/tegra234-p3701.dtsi
index db6ef711674a..320c8e9b06b4 100644
--- a/arch/arm64/boot/dts/nvidia/tegra234-p3701.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra234-p3701.dtsi
@@ -3,6 +3,11 @@
/ {
compatible = "nvidia,p3701", "nvidia,tegra234";
+ aliases {
+ mmc0 = "/bus@0/mmc@3460000";
+ mmc1 = "/bus@0/mmc@3400000";
+ };
+
bus@0 {
aconnect@2900000 {
status = "okay";
@@ -12,1970 +17,22 @@
i2s@2901000 {
status = "okay";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
-
- i2s1_cif: endpoint {
- remote-endpoint = <&xbar_i2s1>;
- };
- };
-
- i2s1_port: port@1 {
- reg = <1>;
-
- i2s1_dap: endpoint {
- dai-format = "i2s";
- /* placeholder for external codec */
- };
- };
- };
};
i2s@2901100 {
status = "okay";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
-
- i2s2_cif: endpoint {
- remote-endpoint = <&xbar_i2s2>;
- };
- };
-
- i2s2_port: port@1 {
- reg = <1>;
-
- i2s2_dap: endpoint {
- dai-format = "i2s";
- /* placeholder for external codec */
- };
- };
- };
};
i2s@2901300 {
status = "okay";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
-
- i2s4_cif: endpoint {
- remote-endpoint = <&xbar_i2s4>;
- };
- };
-
- i2s4_port: port@1 {
- reg = <1>;
-
- i2s4_dap: endpoint {
- dai-format = "i2s";
- /* placeholder for external codec */
- };
- };
- };
};
i2s@2901500 {
status = "okay";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
-
- i2s6_cif: endpoint {
- remote-endpoint = <&xbar_i2s6>;
- };
- };
-
- i2s6_port: port@1 {
- reg = <1>;
-
- i2s6_dap: endpoint {
- dai-format = "i2s";
- /* placeholder for external codec */
- };
- };
- };
- };
-
- sfc@2902000 {
- status = "okay";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
-
- sfc1_cif_in: endpoint {
- remote-endpoint = <&xbar_sfc1_in>;
- };
- };
-
- sfc1_out_port: port@1 {
- reg = <1>;
-
- sfc1_cif_out: endpoint {
- remote-endpoint = <&xbar_sfc1_out>;
- };
- };
- };
- };
-
- sfc@2902200 {
- status = "okay";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
-
- sfc2_cif_in: endpoint {
- remote-endpoint = <&xbar_sfc2_in>;
- };
- };
-
- sfc2_out_port: port@1 {
- reg = <1>;
-
- sfc2_cif_out: endpoint {
- remote-endpoint = <&xbar_sfc2_out>;
- };
- };
- };
- };
-
- sfc@2902400 {
- status = "okay";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
-
- sfc3_cif_in: endpoint {
- remote-endpoint = <&xbar_sfc3_in>;
- };
- };
-
- sfc3_out_port: port@1 {
- reg = <1>;
-
- sfc3_cif_out: endpoint {
- remote-endpoint = <&xbar_sfc3_out>;
- };
- };
- };
- };
-
- sfc@2902600 {
- status = "okay";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
-
- sfc4_cif_in: endpoint {
- remote-endpoint = <&xbar_sfc4_in>;
- };
- };
-
- sfc4_out_port: port@1 {
- reg = <1>;
-
- sfc4_cif_out: endpoint {
- remote-endpoint = <&xbar_sfc4_out>;
- };
- };
- };
- };
-
- amx@2903000 {
- status = "okay";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
-
- amx1_in1: endpoint {
- remote-endpoint = <&xbar_amx1_in1>;
- };
- };
-
- port@1 {
- reg = <1>;
-
- amx1_in2: endpoint {
- remote-endpoint = <&xbar_amx1_in2>;
- };
- };
-
- port@2 {
- reg = <2>;
-
- amx1_in3: endpoint {
- remote-endpoint = <&xbar_amx1_in3>;
- };
- };
-
- port@3 {
- reg = <3>;
-
- amx1_in4: endpoint {
- remote-endpoint = <&xbar_amx1_in4>;
- };
- };
-
- amx1_out_port: port@4 {
- reg = <4>;
-
- amx1_out: endpoint {
- remote-endpoint = <&xbar_amx1_out>;
- };
- };
- };
- };
-
- amx@2903100 {
- status = "okay";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
-
- amx2_in1: endpoint {
- remote-endpoint = <&xbar_amx2_in1>;
- };
- };
-
- port@1 {
- reg = <1>;
-
- amx2_in2: endpoint {
- remote-endpoint = <&xbar_amx2_in2>;
- };
- };
-
- port@2 {
- reg = <2>;
-
- amx2_in3: endpoint {
- remote-endpoint = <&xbar_amx2_in3>;
- };
- };
-
- port@3 {
- reg = <3>;
-
- amx2_in4: endpoint {
- remote-endpoint = <&xbar_amx2_in4>;
- };
- };
-
- amx2_out_port: port@4 {
- reg = <4>;
-
- amx2_out: endpoint {
- remote-endpoint = <&xbar_amx2_out>;
- };
- };
- };
- };
-
- amx@2903200 {
- status = "okay";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
-
- amx3_in1: endpoint {
- remote-endpoint = <&xbar_amx3_in1>;
- };
- };
-
- port@1 {
- reg = <1>;
-
- amx3_in2: endpoint {
- remote-endpoint = <&xbar_amx3_in2>;
- };
- };
-
- port@2 {
- reg = <2>;
-
- amx3_in3: endpoint {
- remote-endpoint = <&xbar_amx3_in3>;
- };
- };
-
- port@3 {
- reg = <3>;
-
- amx3_in4: endpoint {
- remote-endpoint = <&xbar_amx3_in4>;
- };
- };
-
- amx3_out_port: port@4 {
- reg = <4>;
-
- amx3_out: endpoint {
- remote-endpoint = <&xbar_amx3_out>;
- };
- };
- };
- };
-
- amx@2903300 {
- status = "okay";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
-
- amx4_in1: endpoint {
- remote-endpoint = <&xbar_amx4_in1>;
- };
- };
-
- port@1 {
- reg = <1>;
-
- amx4_in2: endpoint {
- remote-endpoint = <&xbar_amx4_in2>;
- };
- };
-
- port@2 {
- reg = <2>;
-
- amx4_in3: endpoint {
- remote-endpoint = <&xbar_amx4_in3>;
- };
- };
-
- port@3 {
- reg = <3>;
-
- amx4_in4: endpoint {
- remote-endpoint = <&xbar_amx4_in4>;
- };
- };
-
- amx4_out_port: port@4 {
- reg = <4>;
-
- amx4_out: endpoint {
- remote-endpoint = <&xbar_amx4_out>;
- };
- };
- };
- };
-
- adx@2903800 {
- status = "okay";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
-
- adx1_in: endpoint {
- remote-endpoint = <&xbar_adx1_in>;
- };
- };
-
- adx1_out1_port: port@1 {
- reg = <1>;
-
- adx1_out1: endpoint {
- remote-endpoint = <&xbar_adx1_out1>;
- };
- };
-
- adx1_out2_port: port@2 {
- reg = <2>;
-
- adx1_out2: endpoint {
- remote-endpoint = <&xbar_adx1_out2>;
- };
- };
-
- adx1_out3_port: port@3 {
- reg = <3>;
-
- adx1_out3: endpoint {
- remote-endpoint = <&xbar_adx1_out3>;
- };
- };
-
- adx1_out4_port: port@4 {
- reg = <4>;
-
- adx1_out4: endpoint {
- remote-endpoint = <&xbar_adx1_out4>;
- };
- };
- };
- };
-
- adx@2903900 {
- status = "okay";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
-
- adx2_in: endpoint {
- remote-endpoint = <&xbar_adx2_in>;
- };
- };
-
- adx2_out1_port: port@1 {
- reg = <1>;
-
- adx2_out1: endpoint {
- remote-endpoint = <&xbar_adx2_out1>;
- };
- };
-
- adx2_out2_port: port@2 {
- reg = <2>;
-
- adx2_out2: endpoint {
- remote-endpoint = <&xbar_adx2_out2>;
- };
- };
-
- adx2_out3_port: port@3 {
- reg = <3>;
-
- adx2_out3: endpoint {
- remote-endpoint = <&xbar_adx2_out3>;
- };
- };
-
- adx2_out4_port: port@4 {
- reg = <4>;
-
- adx2_out4: endpoint {
- remote-endpoint = <&xbar_adx2_out4>;
- };
- };
- };
- };
-
- adx@2903a00 {
- status = "okay";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
-
- adx3_in: endpoint {
- remote-endpoint = <&xbar_adx3_in>;
- };
- };
-
- adx3_out1_port: port@1 {
- reg = <1>;
-
- adx3_out1: endpoint {
- remote-endpoint = <&xbar_adx3_out1>;
- };
- };
-
- adx3_out2_port: port@2 {
- reg = <2>;
-
- adx3_out2: endpoint {
- remote-endpoint = <&xbar_adx3_out2>;
- };
- };
-
- adx3_out3_port: port@3 {
- reg = <3>;
-
- adx3_out3: endpoint {
- remote-endpoint = <&xbar_adx3_out3>;
- };
- };
-
- adx3_out4_port: port@4 {
- reg = <4>;
-
- adx3_out4: endpoint {
- remote-endpoint = <&xbar_adx3_out4>;
- };
- };
- };
- };
-
- adx@2903b00 {
- status = "okay";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
-
- adx4_in: endpoint {
- remote-endpoint = <&xbar_adx4_in>;
- };
- };
-
- adx4_out1_port: port@1 {
- reg = <1>;
-
- adx4_out1: endpoint {
- remote-endpoint = <&xbar_adx4_out1>;
- };
- };
-
- adx4_out2_port: port@2 {
- reg = <2>;
-
- adx4_out2: endpoint {
- remote-endpoint = <&xbar_adx4_out2>;
- };
- };
-
- adx4_out3_port: port@3 {
- reg = <3>;
-
- adx4_out3: endpoint {
- remote-endpoint = <&xbar_adx4_out3>;
- };
- };
-
- adx4_out4_port: port@4 {
- reg = <4>;
-
- adx4_out4: endpoint {
- remote-endpoint = <&xbar_adx4_out4>;
- };
- };
- };
};
dmic@2904200 {
status = "okay";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
-
- dmic3_cif: endpoint {
- remote-endpoint = <&xbar_dmic3>;
- };
- };
-
- dmic3_port: port@1 {
- reg = <1>;
-
- dmic3_dap: endpoint {
- /* placeholder for external codec */
- };
- };
- };
- };
-
- processing-engine@2908000 {
- status = "okay";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0x0>;
-
- ope1_cif_in_ep: endpoint {
- remote-endpoint = <&xbar_ope1_in_ep>;
- };
- };
-
- ope1_out_port: port@1 {
- reg = <0x1>;
-
- ope1_cif_out_ep: endpoint {
- remote-endpoint = <&xbar_ope1_out_ep>;
- };
- };
- };
- };
-
- mvc@290a000 {
- status = "okay";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
-
- mvc1_cif_in: endpoint {
- remote-endpoint = <&xbar_mvc1_in>;
- };
- };
-
- mvc1_out_port: port@1 {
- reg = <1>;
-
- mvc1_cif_out: endpoint {
- remote-endpoint = <&xbar_mvc1_out>;
- };
- };
- };
- };
-
- mvc@290a200 {
- status = "okay";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
-
- mvc2_cif_in: endpoint {
- remote-endpoint = <&xbar_mvc2_in>;
- };
- };
-
- mvc2_out_port: port@1 {
- reg = <1>;
-
- mvc2_cif_out: endpoint {
- remote-endpoint = <&xbar_mvc2_out>;
- };
- };
- };
- };
-
- amixer@290bb00 {
- status = "okay";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0x0>;
-
- mix_in1: endpoint {
- remote-endpoint = <&xbar_mix_in1>;
- };
- };
-
- port@1 {
- reg = <0x1>;
-
- mix_in2: endpoint {
- remote-endpoint = <&xbar_mix_in2>;
- };
- };
-
- port@2 {
- reg = <0x2>;
-
- mix_in3: endpoint {
- remote-endpoint = <&xbar_mix_in3>;
- };
- };
-
- port@3 {
- reg = <0x3>;
-
- mix_in4: endpoint {
- remote-endpoint = <&xbar_mix_in4>;
- };
- };
-
- port@4 {
- reg = <0x4>;
-
- mix_in5: endpoint {
- remote-endpoint = <&xbar_mix_in5>;
- };
- };
-
- port@5 {
- reg = <0x5>;
-
- mix_in6: endpoint {
- remote-endpoint = <&xbar_mix_in6>;
- };
- };
-
- port@6 {
- reg = <0x6>;
-
- mix_in7: endpoint {
- remote-endpoint = <&xbar_mix_in7>;
- };
- };
-
- port@7 {
- reg = <0x7>;
-
- mix_in8: endpoint {
- remote-endpoint = <&xbar_mix_in8>;
- };
- };
-
- port@8 {
- reg = <0x8>;
-
- mix_in9: endpoint {
- remote-endpoint = <&xbar_mix_in9>;
- };
- };
-
- port@9 {
- reg = <0x9>;
-
- mix_in10: endpoint {
- remote-endpoint = <&xbar_mix_in10>;
- };
- };
-
- mix_out1_port: port@a {
- reg = <0xa>;
-
- mix_out1: endpoint {
- remote-endpoint = <&xbar_mix_out1>;
- };
- };
-
- mix_out2_port: port@b {
- reg = <0xb>;
-
- mix_out2: endpoint {
- remote-endpoint = <&xbar_mix_out2>;
- };
- };
-
- mix_out3_port: port@c {
- reg = <0xc>;
-
- mix_out3: endpoint {
- remote-endpoint = <&xbar_mix_out3>;
- };
- };
-
- mix_out4_port: port@d {
- reg = <0xd>;
-
- mix_out4: endpoint {
- remote-endpoint = <&xbar_mix_out4>;
- };
- };
-
- mix_out5_port: port@e {
- reg = <0xe>;
-
- mix_out5: endpoint {
- remote-endpoint = <&xbar_mix_out5>;
- };
- };
- };
- };
-
- admaif@290f000 {
- status = "okay";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- admaif0_port: port@0 {
- reg = <0x0>;
-
- admaif0: endpoint {
- remote-endpoint = <&xbar_admaif0>;
- };
- };
-
- admaif1_port: port@1 {
- reg = <0x1>;
-
- admaif1: endpoint {
- remote-endpoint = <&xbar_admaif1>;
- };
- };
-
- admaif2_port: port@2 {
- reg = <0x2>;
-
- admaif2: endpoint {
- remote-endpoint = <&xbar_admaif2>;
- };
- };
-
- admaif3_port: port@3 {
- reg = <0x3>;
-
- admaif3: endpoint {
- remote-endpoint = <&xbar_admaif3>;
- };
- };
-
- admaif4_port: port@4 {
- reg = <0x4>;
-
- admaif4: endpoint {
- remote-endpoint = <&xbar_admaif4>;
- };
- };
-
- admaif5_port: port@5 {
- reg = <0x5>;
-
- admaif5: endpoint {
- remote-endpoint = <&xbar_admaif5>;
- };
- };
-
- admaif6_port: port@6 {
- reg = <0x6>;
-
- admaif6: endpoint {
- remote-endpoint = <&xbar_admaif6>;
- };
- };
-
- admaif7_port: port@7 {
- reg = <0x7>;
-
- admaif7: endpoint {
- remote-endpoint = <&xbar_admaif7>;
- };
- };
-
- admaif8_port: port@8 {
- reg = <0x8>;
-
- admaif8: endpoint {
- remote-endpoint = <&xbar_admaif8>;
- };
- };
-
- admaif9_port: port@9 {
- reg = <0x9>;
-
- admaif9: endpoint {
- remote-endpoint = <&xbar_admaif9>;
- };
- };
-
- admaif10_port: port@a {
- reg = <0xa>;
-
- admaif10: endpoint {
- remote-endpoint = <&xbar_admaif10>;
- };
- };
-
- admaif11_port: port@b {
- reg = <0xb>;
-
- admaif11: endpoint {
- remote-endpoint = <&xbar_admaif11>;
- };
- };
-
- admaif12_port: port@c {
- reg = <0xc>;
-
- admaif12: endpoint {
- remote-endpoint = <&xbar_admaif12>;
- };
- };
-
- admaif13_port: port@d {
- reg = <0xd>;
-
- admaif13: endpoint {
- remote-endpoint = <&xbar_admaif13>;
- };
- };
-
- admaif14_port: port@e {
- reg = <0xe>;
-
- admaif14: endpoint {
- remote-endpoint = <&xbar_admaif14>;
- };
- };
-
- admaif15_port: port@f {
- reg = <0xf>;
-
- admaif15: endpoint {
- remote-endpoint = <&xbar_admaif15>;
- };
- };
-
- admaif16_port: port@10 {
- reg = <0x10>;
-
- admaif16: endpoint {
- remote-endpoint = <&xbar_admaif16>;
- };
- };
-
- admaif17_port: port@11 {
- reg = <0x11>;
-
- admaif17: endpoint {
- remote-endpoint = <&xbar_admaif17>;
- };
- };
-
- admaif18_port: port@12 {
- reg = <0x12>;
-
- admaif18: endpoint {
- remote-endpoint = <&xbar_admaif18>;
- };
- };
-
- admaif19_port: port@13 {
- reg = <0x13>;
-
- admaif19: endpoint {
- remote-endpoint = <&xbar_admaif19>;
- };
- };
- };
- };
-
- asrc@2910000 {
- status = "okay";
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0x0>;
-
- asrc_in1_ep: endpoint {
- remote-endpoint = <&xbar_asrc_in1_ep>;
- };
- };
-
- port@1 {
- reg = <0x1>;
-
- asrc_in2_ep: endpoint {
- remote-endpoint = <&xbar_asrc_in2_ep>;
- };
- };
-
- port@2 {
- reg = <0x2>;
-
- asrc_in3_ep: endpoint {
- remote-endpoint = <&xbar_asrc_in3_ep>;
- };
- };
-
- port@3 {
- reg = <0x3>;
-
- asrc_in4_ep: endpoint {
- remote-endpoint = <&xbar_asrc_in4_ep>;
- };
- };
-
- port@4 {
- reg = <0x4>;
-
- asrc_in5_ep: endpoint {
- remote-endpoint = <&xbar_asrc_in5_ep>;
- };
- };
-
- port@5 {
- reg = <0x5>;
-
- asrc_in6_ep: endpoint {
- remote-endpoint = <&xbar_asrc_in6_ep>;
- };
- };
-
- port@6 {
- reg = <0x6>;
-
- asrc_in7_ep: endpoint {
- remote-endpoint = <&xbar_asrc_in7_ep>;
- };
- };
-
- asrc_out1_port: port@7 {
- reg = <0x7>;
-
- asrc_out1_ep: endpoint {
- remote-endpoint = <&xbar_asrc_out1_ep>;
- };
- };
-
- asrc_out2_port: port@8 {
- reg = <0x8>;
-
- asrc_out2_ep: endpoint {
- remote-endpoint = <&xbar_asrc_out2_ep>;
- };
- };
-
- asrc_out3_port: port@9 {
- reg = <0x9>;
-
- asrc_out3_ep: endpoint {
- remote-endpoint = <&xbar_asrc_out3_ep>;
- };
- };
-
- asrc_out4_port: port@a {
- reg = <0xa>;
-
- asrc_out4_ep: endpoint {
- remote-endpoint = <&xbar_asrc_out4_ep>;
- };
- };
-
- asrc_out5_port: port@b {
- reg = <0xb>;
-
- asrc_out5_ep: endpoint {
- remote-endpoint = <&xbar_asrc_out5_ep>;
- };
- };
-
- asrc_out6_port: port@c {
- reg = <0xc>;
-
- asrc_out6_ep: endpoint {
- remote-endpoint = <&xbar_asrc_out6_ep>;
- };
- };
- };
- };
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0x0>;
-
- xbar_admaif0: endpoint {
- remote-endpoint = <&admaif0>;
- };
- };
-
- port@1 {
- reg = <0x1>;
-
- xbar_admaif1: endpoint {
- remote-endpoint = <&admaif1>;
- };
- };
-
- port@2 {
- reg = <0x2>;
-
- xbar_admaif2: endpoint {
- remote-endpoint = <&admaif2>;
- };
- };
-
- port@3 {
- reg = <0x3>;
-
- xbar_admaif3: endpoint {
- remote-endpoint = <&admaif3>;
- };
- };
-
- port@4 {
- reg = <0x4>;
-
- xbar_admaif4: endpoint {
- remote-endpoint = <&admaif4>;
- };
- };
-
- port@5 {
- reg = <0x5>;
-
- xbar_admaif5: endpoint {
- remote-endpoint = <&admaif5>;
- };
- };
-
- port@6 {
- reg = <0x6>;
-
- xbar_admaif6: endpoint {
- remote-endpoint = <&admaif6>;
- };
- };
-
- port@7 {
- reg = <0x7>;
-
- xbar_admaif7: endpoint {
- remote-endpoint = <&admaif7>;
- };
- };
-
- port@8 {
- reg = <0x8>;
-
- xbar_admaif8: endpoint {
- remote-endpoint = <&admaif8>;
- };
- };
-
- port@9 {
- reg = <0x9>;
-
- xbar_admaif9: endpoint {
- remote-endpoint = <&admaif9>;
- };
- };
-
- port@a {
- reg = <0xa>;
-
- xbar_admaif10: endpoint {
- remote-endpoint = <&admaif10>;
- };
- };
-
- port@b {
- reg = <0xb>;
-
- xbar_admaif11: endpoint {
- remote-endpoint = <&admaif11>;
- };
- };
-
- port@c {
- reg = <0xc>;
-
- xbar_admaif12: endpoint {
- remote-endpoint = <&admaif12>;
- };
- };
-
- port@d {
- reg = <0xd>;
-
- xbar_admaif13: endpoint {
- remote-endpoint = <&admaif13>;
- };
- };
-
- port@e {
- reg = <0xe>;
-
- xbar_admaif14: endpoint {
- remote-endpoint = <&admaif14>;
- };
- };
-
- port@f {
- reg = <0xf>;
-
- xbar_admaif15: endpoint {
- remote-endpoint = <&admaif15>;
- };
- };
-
- port@10 {
- reg = <0x10>;
-
- xbar_admaif16: endpoint {
- remote-endpoint = <&admaif16>;
- };
- };
-
- port@11 {
- reg = <0x11>;
-
- xbar_admaif17: endpoint {
- remote-endpoint = <&admaif17>;
- };
- };
-
- port@12 {
- reg = <0x12>;
-
- xbar_admaif18: endpoint {
- remote-endpoint = <&admaif18>;
- };
- };
-
- port@13 {
- reg = <0x13>;
-
- xbar_admaif19: endpoint {
- remote-endpoint = <&admaif19>;
- };
- };
-
- xbar_i2s1_port: port@14 {
- reg = <0x14>;
-
- xbar_i2s1: endpoint {
- remote-endpoint = <&i2s1_cif>;
- };
- };
-
- xbar_i2s2_port: port@15 {
- reg = <0x15>;
-
- xbar_i2s2: endpoint {
- remote-endpoint = <&i2s2_cif>;
- };
- };
-
- xbar_i2s4_port: port@17 {
- reg = <0x17>;
-
- xbar_i2s4: endpoint {
- remote-endpoint = <&i2s4_cif>;
- };
- };
-
- xbar_i2s6_port: port@19 {
- reg = <0x19>;
-
- xbar_i2s6: endpoint {
- remote-endpoint = <&i2s6_cif>;
- };
- };
-
- xbar_dmic3_port: port@1c {
- reg = <0x1c>;
-
- xbar_dmic3: endpoint {
- remote-endpoint = <&dmic3_cif>;
- };
- };
-
- xbar_sfc1_in_port: port@20 {
- reg = <0x20>;
-
- xbar_sfc1_in: endpoint {
- remote-endpoint = <&sfc1_cif_in>;
- };
- };
-
- port@21 {
- reg = <0x21>;
-
- xbar_sfc1_out: endpoint {
- remote-endpoint = <&sfc1_cif_out>;
- };
- };
-
- xbar_sfc2_in_port: port@22 {
- reg = <0x22>;
-
- xbar_sfc2_in: endpoint {
- remote-endpoint = <&sfc2_cif_in>;
- };
- };
-
- port@23 {
- reg = <0x23>;
-
- xbar_sfc2_out: endpoint {
- remote-endpoint = <&sfc2_cif_out>;
- };
- };
-
- xbar_sfc3_in_port: port@24 {
- reg = <0x24>;
-
- xbar_sfc3_in: endpoint {
- remote-endpoint = <&sfc3_cif_in>;
- };
- };
-
- port@25 {
- reg = <0x25>;
-
- xbar_sfc3_out: endpoint {
- remote-endpoint = <&sfc3_cif_out>;
- };
- };
-
- xbar_sfc4_in_port: port@26 {
- reg = <0x26>;
-
- xbar_sfc4_in: endpoint {
- remote-endpoint = <&sfc4_cif_in>;
- };
- };
-
- port@27 {
- reg = <0x27>;
-
- xbar_sfc4_out: endpoint {
- remote-endpoint = <&sfc4_cif_out>;
- };
- };
-
- xbar_mvc1_in_port: port@28 {
- reg = <0x28>;
-
- xbar_mvc1_in: endpoint {
- remote-endpoint = <&mvc1_cif_in>;
- };
- };
-
- port@29 {
- reg = <0x29>;
-
- xbar_mvc1_out: endpoint {
- remote-endpoint = <&mvc1_cif_out>;
- };
- };
-
- xbar_mvc2_in_port: port@2a {
- reg = <0x2a>;
-
- xbar_mvc2_in: endpoint {
- remote-endpoint = <&mvc2_cif_in>;
- };
- };
-
- port@2b {
- reg = <0x2b>;
-
- xbar_mvc2_out: endpoint {
- remote-endpoint = <&mvc2_cif_out>;
- };
- };
-
- xbar_amx1_in1_port: port@2c {
- reg = <0x2c>;
-
- xbar_amx1_in1: endpoint {
- remote-endpoint = <&amx1_in1>;
- };
- };
-
- xbar_amx1_in2_port: port@2d {
- reg = <0x2d>;
-
- xbar_amx1_in2: endpoint {
- remote-endpoint = <&amx1_in2>;
- };
- };
-
- xbar_amx1_in3_port: port@2e {
- reg = <0x2e>;
-
- xbar_amx1_in3: endpoint {
- remote-endpoint = <&amx1_in3>;
- };
- };
-
- xbar_amx1_in4_port: port@2f {
- reg = <0x2f>;
-
- xbar_amx1_in4: endpoint {
- remote-endpoint = <&amx1_in4>;
- };
- };
-
- port@30 {
- reg = <0x30>;
-
- xbar_amx1_out: endpoint {
- remote-endpoint = <&amx1_out>;
- };
- };
-
- xbar_amx2_in1_port: port@31 {
- reg = <0x31>;
-
- xbar_amx2_in1: endpoint {
- remote-endpoint = <&amx2_in1>;
- };
- };
-
- xbar_amx2_in2_port: port@32 {
- reg = <0x32>;
-
- xbar_amx2_in2: endpoint {
- remote-endpoint = <&amx2_in2>;
- };
- };
-
- xbar_amx2_in3_port: port@33 {
- reg = <0x33>;
-
- xbar_amx2_in3: endpoint {
- remote-endpoint = <&amx2_in3>;
- };
- };
-
- xbar_amx2_in4_port: port@34 {
- reg = <0x34>;
-
- xbar_amx2_in4: endpoint {
- remote-endpoint = <&amx2_in4>;
- };
- };
-
- port@35 {
- reg = <0x35>;
-
- xbar_amx2_out: endpoint {
- remote-endpoint = <&amx2_out>;
- };
- };
-
- xbar_amx3_in1_port: port@36 {
- reg = <0x36>;
-
- xbar_amx3_in1: endpoint {
- remote-endpoint = <&amx3_in1>;
- };
- };
-
- xbar_amx3_in2_port: port@37 {
- reg = <0x37>;
-
- xbar_amx3_in2: endpoint {
- remote-endpoint = <&amx3_in2>;
- };
- };
-
- xbar_amx3_in3_port: port@38 {
- reg = <0x38>;
-
- xbar_amx3_in3: endpoint {
- remote-endpoint = <&amx3_in3>;
- };
- };
-
- xbar_amx3_in4_port: port@39 {
- reg = <0x39>;
-
- xbar_amx3_in4: endpoint {
- remote-endpoint = <&amx3_in4>;
- };
- };
-
- port@3a {
- reg = <0x3a>;
-
- xbar_amx3_out: endpoint {
- remote-endpoint = <&amx3_out>;
- };
- };
-
- xbar_amx4_in1_port: port@3b {
- reg = <0x3b>;
-
- xbar_amx4_in1: endpoint {
- remote-endpoint = <&amx4_in1>;
- };
- };
-
- xbar_amx4_in2_port: port@3c {
- reg = <0x3c>;
-
- xbar_amx4_in2: endpoint {
- remote-endpoint = <&amx4_in2>;
- };
- };
-
- xbar_amx4_in3_port: port@3d {
- reg = <0x3d>;
-
- xbar_amx4_in3: endpoint {
- remote-endpoint = <&amx4_in3>;
- };
- };
-
- xbar_amx4_in4_port: port@3e {
- reg = <0x3e>;
-
- xbar_amx4_in4: endpoint {
- remote-endpoint = <&amx4_in4>;
- };
- };
-
- port@3f {
- reg = <0x3f>;
-
- xbar_amx4_out: endpoint {
- remote-endpoint = <&amx4_out>;
- };
- };
-
- xbar_adx1_in_port: port@40 {
- reg = <0x40>;
-
- xbar_adx1_in: endpoint {
- remote-endpoint = <&adx1_in>;
- };
- };
-
- port@41 {
- reg = <0x41>;
-
- xbar_adx1_out1: endpoint {
- remote-endpoint = <&adx1_out1>;
- };
- };
-
- port@42 {
- reg = <0x42>;
-
- xbar_adx1_out2: endpoint {
- remote-endpoint = <&adx1_out2>;
- };
- };
-
- port@43 {
- reg = <0x43>;
-
- xbar_adx1_out3: endpoint {
- remote-endpoint = <&adx1_out3>;
- };
- };
-
- port@44 {
- reg = <0x44>;
-
- xbar_adx1_out4: endpoint {
- remote-endpoint = <&adx1_out4>;
- };
- };
-
- xbar_adx2_in_port: port@45 {
- reg = <0x45>;
-
- xbar_adx2_in: endpoint {
- remote-endpoint = <&adx2_in>;
- };
- };
-
- port@46 {
- reg = <0x46>;
-
- xbar_adx2_out1: endpoint {
- remote-endpoint = <&adx2_out1>;
- };
- };
-
- port@47 {
- reg = <0x47>;
-
- xbar_adx2_out2: endpoint {
- remote-endpoint = <&adx2_out2>;
- };
- };
-
- port@48 {
- reg = <0x48>;
-
- xbar_adx2_out3: endpoint {
- remote-endpoint = <&adx2_out3>;
- };
- };
-
- port@49 {
- reg = <0x49>;
-
- xbar_adx2_out4: endpoint {
- remote-endpoint = <&adx2_out4>;
- };
- };
-
- xbar_adx3_in_port: port@4a {
- reg = <0x4a>;
-
- xbar_adx3_in: endpoint {
- remote-endpoint = <&adx3_in>;
- };
- };
-
- port@4b {
- reg = <0x4b>;
-
- xbar_adx3_out1: endpoint {
- remote-endpoint = <&adx3_out1>;
- };
- };
-
- port@4c {
- reg = <0x4c>;
-
- xbar_adx3_out2: endpoint {
- remote-endpoint = <&adx3_out2>;
- };
- };
-
- port@4d {
- reg = <0x4d>;
-
- xbar_adx3_out3: endpoint {
- remote-endpoint = <&adx3_out3>;
- };
- };
-
- port@4e {
- reg = <0x4e>;
-
- xbar_adx3_out4: endpoint {
- remote-endpoint = <&adx3_out4>;
- };
- };
-
- xbar_adx4_in_port: port@4f {
- reg = <0x4f>;
-
- xbar_adx4_in: endpoint {
- remote-endpoint = <&adx4_in>;
- };
- };
-
- port@50 {
- reg = <0x50>;
-
- xbar_adx4_out1: endpoint {
- remote-endpoint = <&adx4_out1>;
- };
- };
-
- port@51 {
- reg = <0x51>;
-
- xbar_adx4_out2: endpoint {
- remote-endpoint = <&adx4_out2>;
- };
- };
-
- port@52 {
- reg = <0x52>;
-
- xbar_adx4_out3: endpoint {
- remote-endpoint = <&adx4_out3>;
- };
- };
-
- port@53 {
- reg = <0x53>;
-
- xbar_adx4_out4: endpoint {
- remote-endpoint = <&adx4_out4>;
- };
- };
-
- xbar_mix_in1_port: port@54 {
- reg = <0x54>;
-
- xbar_mix_in1: endpoint {
- remote-endpoint = <&mix_in1>;
- };
- };
-
- xbar_mix_in2_port: port@55 {
- reg = <0x55>;
-
- xbar_mix_in2: endpoint {
- remote-endpoint = <&mix_in2>;
- };
- };
-
- xbar_mix_in3_port: port@56 {
- reg = <0x56>;
-
- xbar_mix_in3: endpoint {
- remote-endpoint = <&mix_in3>;
- };
- };
-
- xbar_mix_in4_port: port@57 {
- reg = <0x57>;
-
- xbar_mix_in4: endpoint {
- remote-endpoint = <&mix_in4>;
- };
- };
-
- xbar_mix_in5_port: port@58 {
- reg = <0x58>;
-
- xbar_mix_in5: endpoint {
- remote-endpoint = <&mix_in5>;
- };
- };
-
- xbar_mix_in6_port: port@59 {
- reg = <0x59>;
-
- xbar_mix_in6: endpoint {
- remote-endpoint = <&mix_in6>;
- };
- };
-
- xbar_mix_in7_port: port@5a {
- reg = <0x5a>;
-
- xbar_mix_in7: endpoint {
- remote-endpoint = <&mix_in7>;
- };
- };
-
- xbar_mix_in8_port: port@5b {
- reg = <0x5b>;
-
- xbar_mix_in8: endpoint {
- remote-endpoint = <&mix_in8>;
- };
- };
-
- xbar_mix_in9_port: port@5c {
- reg = <0x5c>;
-
- xbar_mix_in9: endpoint {
- remote-endpoint = <&mix_in9>;
- };
- };
-
- xbar_mix_in10_port: port@5d {
- reg = <0x5d>;
-
- xbar_mix_in10: endpoint {
- remote-endpoint = <&mix_in10>;
- };
- };
-
- port@5e {
- reg = <0x5e>;
-
- xbar_mix_out1: endpoint {
- remote-endpoint = <&mix_out1>;
- };
- };
-
- port@5f {
- reg = <0x5f>;
-
- xbar_mix_out2: endpoint {
- remote-endpoint = <&mix_out2>;
- };
- };
-
- port@60 {
- reg = <0x60>;
-
- xbar_mix_out3: endpoint {
- remote-endpoint = <&mix_out3>;
- };
- };
-
- port@61 {
- reg = <0x61>;
-
- xbar_mix_out4: endpoint {
- remote-endpoint = <&mix_out4>;
- };
- };
-
- port@62 {
- reg = <0x62>;
-
- xbar_mix_out5: endpoint {
- remote-endpoint = <&mix_out5>;
- };
- };
-
- xbar_asrc_in1_port: port@63 {
- reg = <0x63>;
-
- xbar_asrc_in1_ep: endpoint {
- remote-endpoint = <&asrc_in1_ep>;
- };
- };
-
- port@64 {
- reg = <0x64>;
-
- xbar_asrc_out1_ep: endpoint {
- remote-endpoint = <&asrc_out1_ep>;
- };
- };
-
- xbar_asrc_in2_port: port@65 {
- reg = <0x65>;
-
- xbar_asrc_in2_ep: endpoint {
- remote-endpoint = <&asrc_in2_ep>;
- };
- };
-
- port@66 {
- reg = <0x66>;
-
- xbar_asrc_out2_ep: endpoint {
- remote-endpoint = <&asrc_out2_ep>;
- };
- };
-
- xbar_asrc_in3_port: port@67 {
- reg = <0x67>;
-
- xbar_asrc_in3_ep: endpoint {
- remote-endpoint = <&asrc_in3_ep>;
- };
- };
-
- port@68 {
- reg = <0x68>;
-
- xbar_asrc_out3_ep: endpoint {
- remote-endpoint = <&asrc_out3_ep>;
- };
- };
-
- xbar_asrc_in4_port: port@69 {
- reg = <0x69>;
-
- xbar_asrc_in4_ep: endpoint {
- remote-endpoint = <&asrc_in4_ep>;
- };
- };
-
- port@6a {
- reg = <0x6a>;
-
- xbar_asrc_out4_ep: endpoint {
- remote-endpoint = <&asrc_out4_ep>;
- };
- };
-
- xbar_asrc_in5_port: port@6b {
- reg = <0x6b>;
-
- xbar_asrc_in5_ep: endpoint {
- remote-endpoint = <&asrc_in5_ep>;
- };
- };
-
- port@6c {
- reg = <0x6c>;
-
- xbar_asrc_out5_ep: endpoint {
- remote-endpoint = <&asrc_out5_ep>;
- };
- };
-
- xbar_asrc_in6_port: port@6d {
- reg = <0x6d>;
-
- xbar_asrc_in6_ep: endpoint {
- remote-endpoint = <&asrc_in6_ep>;
- };
- };
-
- port@6e {
- reg = <0x6e>;
-
- xbar_asrc_out6_ep: endpoint {
- remote-endpoint = <&asrc_out6_ep>;
- };
- };
-
- xbar_asrc_in7_port: port@6f {
- reg = <0x6f>;
-
- xbar_asrc_in7_ep: endpoint {
- remote-endpoint = <&asrc_in7_ep>;
- };
- };
-
- xbar_ope1_in_port: port@70 {
- reg = <0x70>;
-
- xbar_ope1_in_ep: endpoint {
- remote-endpoint = <&ope1_cif_in_ep>;
- };
- };
-
- port@71 {
- reg = <0x71>;
-
- xbar_ope1_out_ep: endpoint {
- remote-endpoint = <&ope1_cif_out_ep>;
- };
- };
};
};
diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts b/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts
index 81a82933e350..69db584253da 100644
--- a/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts
@@ -12,7 +12,6 @@
compatible = "nvidia,p3737-0000+p3701-0000", "nvidia,p3701-0000", "nvidia,tegra234";
aliases {
- mmc3 = "/bus@0/mmc@3460000";
serial0 = &tcu;
serial1 = &uarta;
};
diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3767-0000.dtsi b/arch/arm64/boot/dts/nvidia/tegra234-p3767-0000.dtsi
deleted file mode 100644
index baf4f69e410d..000000000000
--- a/arch/arm64/boot/dts/nvidia/tegra234-p3767-0000.dtsi
+++ /dev/null
@@ -1,14 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-#include "tegra234-p3767.dtsi"
-
-/ {
- compatible = "nvidia,p3767-0000", "nvidia,tegra234";
- model = "NVIDIA Jetson Orin NX";
-
- bus@0 {
- hda@3510000 {
- nvidia,model = "NVIDIA Jetson Orin NX HDA";
- };
- };
-};
diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3767-0005.dtsi b/arch/arm64/boot/dts/nvidia/tegra234-p3767-0005.dtsi
deleted file mode 100644
index 232fa95ef4ae..000000000000
--- a/arch/arm64/boot/dts/nvidia/tegra234-p3767-0005.dtsi
+++ /dev/null
@@ -1,14 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-#include "tegra234-p3767.dtsi"
-
-/ {
- compatible = "nvidia,p3767-0005", "nvidia,tegra234";
- model = "NVIDIA Jetson Orin Nano";
-
- bus@0 {
- hda@3510000 {
- nvidia,model = "NVIDIA Jetson Orin Nano HDA";
- };
- };
-};
diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3767.dtsi b/arch/arm64/boot/dts/nvidia/tegra234-p3767.dtsi
index 59c14ded5e9f..84db7132e8fc 100644
--- a/arch/arm64/boot/dts/nvidia/tegra234-p3767.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra234-p3767.dtsi
@@ -5,7 +5,35 @@
/ {
compatible = "nvidia,p3767", "nvidia,tegra234";
+ aliases {
+ mmc0 = "/bus@0/mmc@3400000";
+ };
+
bus@0 {
+ aconnect@2900000 {
+ status = "okay";
+
+ ahub@2900800 {
+ status = "okay";
+
+ i2s@2901100 {
+ status = "okay";
+ };
+
+ i2s@2901300 {
+ status = "okay";
+ };
+ };
+
+ dma-controller@2930000 {
+ status = "okay";
+ };
+
+ interrupt-controller@2a40000 {
+ status = "okay";
+ };
+ };
+
i2c@3160000 {
status = "okay";
@@ -127,6 +155,64 @@
vin-supply = <&vdd_5v0_sys>;
};
+ sound {
+ compatible = "nvidia,tegra186-audio-graph-card";
+ status = "okay";
+
+ dais = /* ADMAIF (FE) Ports */
+ <&admaif0_port>, <&admaif1_port>, <&admaif2_port>, <&admaif3_port>,
+ <&admaif4_port>, <&admaif5_port>, <&admaif6_port>, <&admaif7_port>,
+ <&admaif8_port>, <&admaif9_port>, <&admaif10_port>, <&admaif11_port>,
+ <&admaif12_port>, <&admaif13_port>, <&admaif14_port>, <&admaif15_port>,
+ <&admaif16_port>, <&admaif17_port>, <&admaif18_port>, <&admaif19_port>,
+ /* XBAR Ports */
+ <&xbar_i2s2_port>, <&xbar_i2s4_port>,
+ <&xbar_sfc1_in_port>, <&xbar_sfc2_in_port>,
+ <&xbar_sfc3_in_port>, <&xbar_sfc4_in_port>,
+ <&xbar_mvc1_in_port>, <&xbar_mvc2_in_port>,
+ <&xbar_amx1_in1_port>, <&xbar_amx1_in2_port>,
+ <&xbar_amx1_in3_port>, <&xbar_amx1_in4_port>,
+ <&xbar_amx2_in1_port>, <&xbar_amx2_in2_port>,
+ <&xbar_amx2_in3_port>, <&xbar_amx2_in4_port>,
+ <&xbar_amx3_in1_port>, <&xbar_amx3_in2_port>,
+ <&xbar_amx3_in3_port>, <&xbar_amx3_in4_port>,
+ <&xbar_amx4_in1_port>, <&xbar_amx4_in2_port>,
+ <&xbar_amx4_in3_port>, <&xbar_amx4_in4_port>,
+ <&xbar_adx1_in_port>, <&xbar_adx2_in_port>,
+ <&xbar_adx3_in_port>, <&xbar_adx4_in_port>,
+ <&xbar_mix_in1_port>, <&xbar_mix_in2_port>,
+ <&xbar_mix_in3_port>, <&xbar_mix_in4_port>,
+ <&xbar_mix_in5_port>, <&xbar_mix_in6_port>,
+ <&xbar_mix_in7_port>, <&xbar_mix_in8_port>,
+ <&xbar_mix_in9_port>, <&xbar_mix_in10_port>,
+ <&xbar_asrc_in1_port>, <&xbar_asrc_in2_port>,
+ <&xbar_asrc_in3_port>, <&xbar_asrc_in4_port>,
+ <&xbar_asrc_in5_port>, <&xbar_asrc_in6_port>,
+ <&xbar_asrc_in7_port>,
+ <&xbar_ope1_in_port>,
+ /* HW accelerators */
+ <&sfc1_out_port>, <&sfc2_out_port>,
+ <&sfc3_out_port>, <&sfc4_out_port>,
+ <&mvc1_out_port>, <&mvc2_out_port>,
+ <&amx1_out_port>, <&amx2_out_port>,
+ <&amx3_out_port>, <&amx4_out_port>,
+ <&adx1_out1_port>, <&adx1_out2_port>,
+ <&adx1_out3_port>, <&adx1_out4_port>,
+ <&adx2_out1_port>, <&adx2_out2_port>,
+ <&adx2_out3_port>, <&adx2_out4_port>,
+ <&adx3_out1_port>, <&adx3_out2_port>,
+ <&adx3_out3_port>, <&adx3_out4_port>,
+ <&adx4_out1_port>, <&adx4_out2_port>,
+ <&adx4_out3_port>, <&adx4_out4_port>,
+ <&mix_out1_port>, <&mix_out2_port>, <&mix_out3_port>,
+ <&mix_out4_port>, <&mix_out5_port>,
+ <&asrc_out1_port>, <&asrc_out2_port>, <&asrc_out3_port>,
+ <&asrc_out4_port>, <&asrc_out5_port>, <&asrc_out6_port>,
+ <&ope1_out_port>,
+ /* BE I/O Ports */
+ <&i2s2_port>, <&i2s4_port>;
+ };
+
thermal-zones {
tj-thermal {
polling-delay = <1000>;
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 61b0e69d3d20..1607ee14216f 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
@@ -4,7 +4,7 @@
#include <dt-bindings/input/linux-event-codes.h>
#include <dt-bindings/input/gpio-keys.h>
-#include "tegra234-p3767-0000.dtsi"
+#include "tegra234-p3767.dtsi"
#include "tegra234-p3768-0000.dtsi"
/ {
@@ -37,7 +37,6 @@
hda@3510000 {
nvidia,model = "NVIDIA Jetson Orin NX HDA";
- status = "okay";
};
padctl@3520000 {
@@ -85,6 +84,10 @@
enable-active-high;
};
+ sound {
+ label = "NVIDIA Jetson Orin NX APE";
+ };
+
thermal-zones {
tj-thermal {
cooling-maps {
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 9e9bb9ca8be4..dc2d4bef1e83 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
@@ -4,17 +4,27 @@
#include <dt-bindings/input/linux-event-codes.h>
#include <dt-bindings/input/gpio-keys.h>
-#include "tegra234-p3767-0005.dtsi"
+#include "tegra234-p3767.dtsi"
#include "tegra234-p3768-0000.dtsi"
/ {
compatible = "nvidia,p3768-0000+p3767-0005", "nvidia,p3767-0005", "nvidia,tegra234";
model = "NVIDIA Jetson Orin Nano Developer Kit";
+ bus@0 {
+ hda@3510000 {
+ nvidia,model = "NVIDIA Jetson Orin Nano HDA";
+ };
+ };
+
pwm-fan {
cooling-levels = <0 88 187 255>;
};
+ sound {
+ label = "NVIDIA Jetson Orin Nano APE";
+ };
+
thermal-zones {
tj-thermal {
cooling-maps {
diff --git a/arch/arm64/boot/dts/nvidia/tegra234-sim-vdk.dts b/arch/arm64/boot/dts/nvidia/tegra234-sim-vdk.dts
index 9f3e9f30c3f7..292e28376eec 100644
--- a/arch/arm64/boot/dts/nvidia/tegra234-sim-vdk.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra234-sim-vdk.dts
@@ -8,7 +8,6 @@
compatible = "nvidia,tegra234-vdk", "nvidia,tegra234";
aliases {
- mmc3 = "/bus@0/mmc@3460000";
serial0 = &uarta;
};
diff --git a/arch/arm64/boot/dts/nvidia/tegra234.dtsi b/arch/arm64/boot/dts/nvidia/tegra234.dtsi
index d1bd328892af..78cbfdd98dd1 100644
--- a/arch/arm64/boot/dts/nvidia/tegra234.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra234.dtsi
@@ -200,6 +200,28 @@
assigned-clock-rates = <1536000>;
sound-name-prefix = "I2S1";
status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ i2s1_cif: endpoint {
+ remote-endpoint = <&xbar_i2s1>;
+ };
+ };
+
+ i2s1_port: port@1 {
+ reg = <1>;
+
+ i2s1_dap: endpoint {
+ dai-format = "i2s";
+ /* placeholder for external codec */
+ };
+ };
+ };
};
tegra_i2s2: i2s@2901100 {
@@ -214,6 +236,28 @@
assigned-clock-rates = <1536000>;
sound-name-prefix = "I2S2";
status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ i2s2_cif: endpoint {
+ remote-endpoint = <&xbar_i2s2>;
+ };
+ };
+
+ i2s2_port: port@1 {
+ reg = <1>;
+
+ i2s2_dap: endpoint {
+ dai-format = "i2s";
+ /* placeholder for external codec */
+ };
+ };
+ };
};
tegra_i2s3: i2s@2901200 {
@@ -228,6 +272,28 @@
assigned-clock-rates = <1536000>;
sound-name-prefix = "I2S3";
status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ i2s3_cif: endpoint {
+ remote-endpoint = <&xbar_i2s3>;
+ };
+ };
+
+ i2s3_port: port@1 {
+ reg = <1>;
+
+ i2s3_dap: endpoint {
+ dai-format = "i2s";
+ /* placeholder for external codec */
+ };
+ };
+ };
};
tegra_i2s4: i2s@2901300 {
@@ -242,6 +308,28 @@
assigned-clock-rates = <1536000>;
sound-name-prefix = "I2S4";
status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ i2s4_cif: endpoint {
+ remote-endpoint = <&xbar_i2s4>;
+ };
+ };
+
+ i2s4_port: port@1 {
+ reg = <1>;
+
+ i2s4_dap: endpoint {
+ dai-format = "i2s";
+ /* placeholder for external codec */
+ };
+ };
+ };
};
tegra_i2s5: i2s@2901400 {
@@ -256,6 +344,28 @@
assigned-clock-rates = <1536000>;
sound-name-prefix = "I2S5";
status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ i2s5_cif: endpoint {
+ remote-endpoint = <&xbar_i2s5>;
+ };
+ };
+
+ i2s5_port: port@1 {
+ reg = <1>;
+
+ i2s5_dap: endpoint {
+ dai-format = "i2s";
+ /* placeholder for external codec */
+ };
+ };
+ };
};
tegra_i2s6: i2s@2901500 {
@@ -270,6 +380,28 @@
assigned-clock-rates = <1536000>;
sound-name-prefix = "I2S6";
status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ i2s6_cif: endpoint {
+ remote-endpoint = <&xbar_i2s6>;
+ };
+ };
+
+ i2s6_port: port@1 {
+ reg = <1>;
+
+ i2s6_dap: endpoint {
+ dai-format = "i2s";
+ /* placeholder for external codec */
+ };
+ };
+ };
};
tegra_sfc1: sfc@2902000 {
@@ -277,7 +409,27 @@
"nvidia,tegra210-sfc";
reg = <0x0 0x2902000 0x0 0x200>;
sound-name-prefix = "SFC1";
- status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ sfc1_cif_in: endpoint {
+ remote-endpoint = <&xbar_sfc1_in>;
+ };
+ };
+
+ sfc1_out_port: port@1 {
+ reg = <1>;
+
+ sfc1_cif_out: endpoint {
+ remote-endpoint = <&xbar_sfc1_out>;
+ };
+ };
+ };
};
tegra_sfc2: sfc@2902200 {
@@ -285,7 +437,27 @@
"nvidia,tegra210-sfc";
reg = <0x0 0x2902200 0x0 0x200>;
sound-name-prefix = "SFC2";
- status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ sfc2_cif_in: endpoint {
+ remote-endpoint = <&xbar_sfc2_in>;
+ };
+ };
+
+ sfc2_out_port: port@1 {
+ reg = <1>;
+
+ sfc2_cif_out: endpoint {
+ remote-endpoint = <&xbar_sfc2_out>;
+ };
+ };
+ };
};
tegra_sfc3: sfc@2902400 {
@@ -293,7 +465,27 @@
"nvidia,tegra210-sfc";
reg = <0x0 0x2902400 0x0 0x200>;
sound-name-prefix = "SFC3";
- status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ sfc3_cif_in: endpoint {
+ remote-endpoint = <&xbar_sfc3_in>;
+ };
+ };
+
+ sfc3_out_port: port@1 {
+ reg = <1>;
+
+ sfc3_cif_out: endpoint {
+ remote-endpoint = <&xbar_sfc3_out>;
+ };
+ };
+ };
};
tegra_sfc4: sfc@2902600 {
@@ -301,7 +493,27 @@
"nvidia,tegra210-sfc";
reg = <0x0 0x2902600 0x0 0x200>;
sound-name-prefix = "SFC4";
- status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ sfc4_cif_in: endpoint {
+ remote-endpoint = <&xbar_sfc4_in>;
+ };
+ };
+
+ sfc4_out_port: port@1 {
+ reg = <1>;
+
+ sfc4_cif_out: endpoint {
+ remote-endpoint = <&xbar_sfc4_out>;
+ };
+ };
+ };
};
tegra_amx1: amx@2903000 {
@@ -309,7 +521,51 @@
"nvidia,tegra194-amx";
reg = <0x0 0x2903000 0x0 0x100>;
sound-name-prefix = "AMX1";
- status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ amx1_in1: endpoint {
+ remote-endpoint = <&xbar_amx1_in1>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ amx1_in2: endpoint {
+ remote-endpoint = <&xbar_amx1_in2>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ amx1_in3: endpoint {
+ remote-endpoint = <&xbar_amx1_in3>;
+ };
+ };
+
+ port@3 {
+ reg = <3>;
+
+ amx1_in4: endpoint {
+ remote-endpoint = <&xbar_amx1_in4>;
+ };
+ };
+
+ amx1_out_port: port@4 {
+ reg = <4>;
+
+ amx1_out: endpoint {
+ remote-endpoint = <&xbar_amx1_out>;
+ };
+ };
+ };
};
tegra_amx2: amx@2903100 {
@@ -317,7 +573,51 @@
"nvidia,tegra194-amx";
reg = <0x0 0x2903100 0x0 0x100>;
sound-name-prefix = "AMX2";
- status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ amx2_in1: endpoint {
+ remote-endpoint = <&xbar_amx2_in1>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ amx2_in2: endpoint {
+ remote-endpoint = <&xbar_amx2_in2>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ amx2_in3: endpoint {
+ remote-endpoint = <&xbar_amx2_in3>;
+ };
+ };
+
+ port@3 {
+ reg = <3>;
+
+ amx2_in4: endpoint {
+ remote-endpoint = <&xbar_amx2_in4>;
+ };
+ };
+
+ amx2_out_port: port@4 {
+ reg = <4>;
+
+ amx2_out: endpoint {
+ remote-endpoint = <&xbar_amx2_out>;
+ };
+ };
+ };
};
tegra_amx3: amx@2903200 {
@@ -325,7 +625,51 @@
"nvidia,tegra194-amx";
reg = <0x0 0x2903200 0x0 0x100>;
sound-name-prefix = "AMX3";
- status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ amx3_in1: endpoint {
+ remote-endpoint = <&xbar_amx3_in1>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ amx3_in2: endpoint {
+ remote-endpoint = <&xbar_amx3_in2>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ amx3_in3: endpoint {
+ remote-endpoint = <&xbar_amx3_in3>;
+ };
+ };
+
+ port@3 {
+ reg = <3>;
+
+ amx3_in4: endpoint {
+ remote-endpoint = <&xbar_amx3_in4>;
+ };
+ };
+
+ amx3_out_port: port@4 {
+ reg = <4>;
+
+ amx3_out: endpoint {
+ remote-endpoint = <&xbar_amx3_out>;
+ };
+ };
+ };
};
tegra_amx4: amx@2903300 {
@@ -333,7 +677,51 @@
"nvidia,tegra194-amx";
reg = <0x0 0x2903300 0x0 0x100>;
sound-name-prefix = "AMX4";
- status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ amx4_in1: endpoint {
+ remote-endpoint = <&xbar_amx4_in1>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ amx4_in2: endpoint {
+ remote-endpoint = <&xbar_amx4_in2>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ amx4_in3: endpoint {
+ remote-endpoint = <&xbar_amx4_in3>;
+ };
+ };
+
+ port@3 {
+ reg = <3>;
+
+ amx4_in4: endpoint {
+ remote-endpoint = <&xbar_amx4_in4>;
+ };
+ };
+
+ amx4_out_port: port@4 {
+ reg = <4>;
+
+ amx4_out: endpoint {
+ remote-endpoint = <&xbar_amx4_out>;
+ };
+ };
+ };
};
tegra_adx1: adx@2903800 {
@@ -341,7 +729,51 @@
"nvidia,tegra210-adx";
reg = <0x0 0x2903800 0x0 0x100>;
sound-name-prefix = "ADX1";
- status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ adx1_in: endpoint {
+ remote-endpoint = <&xbar_adx1_in>;
+ };
+ };
+
+ adx1_out1_port: port@1 {
+ reg = <1>;
+
+ adx1_out1: endpoint {
+ remote-endpoint = <&xbar_adx1_out1>;
+ };
+ };
+
+ adx1_out2_port: port@2 {
+ reg = <2>;
+
+ adx1_out2: endpoint {
+ remote-endpoint = <&xbar_adx1_out2>;
+ };
+ };
+
+ adx1_out3_port: port@3 {
+ reg = <3>;
+
+ adx1_out3: endpoint {
+ remote-endpoint = <&xbar_adx1_out3>;
+ };
+ };
+
+ adx1_out4_port: port@4 {
+ reg = <4>;
+
+ adx1_out4: endpoint {
+ remote-endpoint = <&xbar_adx1_out4>;
+ };
+ };
+ };
};
tegra_adx2: adx@2903900 {
@@ -349,7 +781,51 @@
"nvidia,tegra210-adx";
reg = <0x0 0x2903900 0x0 0x100>;
sound-name-prefix = "ADX2";
- status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ adx2_in: endpoint {
+ remote-endpoint = <&xbar_adx2_in>;
+ };
+ };
+
+ adx2_out1_port: port@1 {
+ reg = <1>;
+
+ adx2_out1: endpoint {
+ remote-endpoint = <&xbar_adx2_out1>;
+ };
+ };
+
+ adx2_out2_port: port@2 {
+ reg = <2>;
+
+ adx2_out2: endpoint {
+ remote-endpoint = <&xbar_adx2_out2>;
+ };
+ };
+
+ adx2_out3_port: port@3 {
+ reg = <3>;
+
+ adx2_out3: endpoint {
+ remote-endpoint = <&xbar_adx2_out3>;
+ };
+ };
+
+ adx2_out4_port: port@4 {
+ reg = <4>;
+
+ adx2_out4: endpoint {
+ remote-endpoint = <&xbar_adx2_out4>;
+ };
+ };
+ };
};
tegra_adx3: adx@2903a00 {
@@ -357,7 +833,51 @@
"nvidia,tegra210-adx";
reg = <0x0 0x2903a00 0x0 0x100>;
sound-name-prefix = "ADX3";
- status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ adx3_in: endpoint {
+ remote-endpoint = <&xbar_adx3_in>;
+ };
+ };
+
+ adx3_out1_port: port@1 {
+ reg = <1>;
+
+ adx3_out1: endpoint {
+ remote-endpoint = <&xbar_adx3_out1>;
+ };
+ };
+
+ adx3_out2_port: port@2 {
+ reg = <2>;
+
+ adx3_out2: endpoint {
+ remote-endpoint = <&xbar_adx3_out2>;
+ };
+ };
+
+ adx3_out3_port: port@3 {
+ reg = <3>;
+
+ adx3_out3: endpoint {
+ remote-endpoint = <&xbar_adx3_out3>;
+ };
+ };
+
+ adx3_out4_port: port@4 {
+ reg = <4>;
+
+ adx3_out4: endpoint {
+ remote-endpoint = <&xbar_adx3_out4>;
+ };
+ };
+ };
};
tegra_adx4: adx@2903b00 {
@@ -365,7 +885,51 @@
"nvidia,tegra210-adx";
reg = <0x0 0x2903b00 0x0 0x100>;
sound-name-prefix = "ADX4";
- status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ adx4_in: endpoint {
+ remote-endpoint = <&xbar_adx4_in>;
+ };
+ };
+
+ adx4_out1_port: port@1 {
+ reg = <1>;
+
+ adx4_out1: endpoint {
+ remote-endpoint = <&xbar_adx4_out1>;
+ };
+ };
+
+ adx4_out2_port: port@2 {
+ reg = <2>;
+
+ adx4_out2: endpoint {
+ remote-endpoint = <&xbar_adx4_out2>;
+ };
+ };
+
+ adx4_out3_port: port@3 {
+ reg = <3>;
+
+ adx4_out3: endpoint {
+ remote-endpoint = <&xbar_adx4_out3>;
+ };
+ };
+
+ adx4_out4_port: port@4 {
+ reg = <4>;
+
+ adx4_out4: endpoint {
+ remote-endpoint = <&xbar_adx4_out4>;
+ };
+ };
+ };
};
@@ -380,6 +944,27 @@
assigned-clock-rates = <3072000>;
sound-name-prefix = "DMIC1";
status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ dmic1_cif: endpoint {
+ remote-endpoint = <&xbar_dmic1>;
+ };
+ };
+
+ dmic1_port: port@1 {
+ reg = <1>;
+
+ dmic1_dap: endpoint {
+ /* placeholder for external codec */
+ };
+ };
+ };
};
tegra_dmic2: dmic@2904100 {
@@ -393,6 +978,27 @@
assigned-clock-rates = <3072000>;
sound-name-prefix = "DMIC2";
status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ dmic2_cif: endpoint {
+ remote-endpoint = <&xbar_dmic2>;
+ };
+ };
+
+ dmic2_port: port@1 {
+ reg = <1>;
+
+ dmic2_dap: endpoint {
+ /* placeholder for external codec */
+ };
+ };
+ };
};
tegra_dmic3: dmic@2904200 {
@@ -406,6 +1012,27 @@
assigned-clock-rates = <3072000>;
sound-name-prefix = "DMIC3";
status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ dmic3_cif: endpoint {
+ remote-endpoint = <&xbar_dmic3>;
+ };
+ };
+
+ dmic3_port: port@1 {
+ reg = <1>;
+
+ dmic3_dap: endpoint {
+ /* placeholder for external codec */
+ };
+ };
+ };
};
tegra_dmic4: dmic@2904300 {
@@ -419,6 +1046,27 @@
assigned-clock-rates = <3072000>;
sound-name-prefix = "DMIC4";
status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ dmic4_cif: endpoint {
+ remote-endpoint = <&xbar_dmic4>;
+ };
+ };
+
+ dmic4_port: port@1 {
+ reg = <1>;
+
+ dmic4_dap: endpoint {
+ /* placeholder for external codec */
+ };
+ };
+ };
};
tegra_dspk1: dspk@2905000 {
@@ -432,6 +1080,27 @@
assigned-clock-rates = <12288000>;
sound-name-prefix = "DSPK1";
status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ dspk1_cif: endpoint {
+ remote-endpoint = <&xbar_dspk1>;
+ };
+ };
+
+ dspk1_port: port@1 {
+ reg = <1>;
+
+ dspk1_dap: endpoint {
+ /* placeholder for external codec */
+ };
+ };
+ };
};
tegra_dspk2: dspk@2905100 {
@@ -445,6 +1114,27 @@
assigned-clock-rates = <12288000>;
sound-name-prefix = "DSPK2";
status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ dspk2_cif: endpoint {
+ remote-endpoint = <&xbar_dspk2>;
+ };
+ };
+
+ dspk2_port: port@1 {
+ reg = <1>;
+
+ dspk2_dap: endpoint {
+ /* placeholder for external codec */
+ };
+ };
+ };
};
tegra_ope1: processing-engine@2908000 {
@@ -452,7 +1142,6 @@
"nvidia,tegra210-ope";
reg = <0x0 0x2908000 0x0 0x100>;
sound-name-prefix = "OPE1";
- status = "disabled";
#address-cells = <2>;
#size-cells = <2>;
@@ -469,6 +1158,29 @@
"nvidia,tegra210-mbdrc";
reg = <0x0 0x2908200 0x0 0x200>;
};
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0x0>;
+
+ ope1_cif_in_ep: endpoint {
+ remote-endpoint =
+ <&xbar_ope1_in_ep>;
+ };
+ };
+
+ ope1_out_port: port@1 {
+ reg = <0x1>;
+
+ ope1_cif_out_ep: endpoint {
+ remote-endpoint =
+ <&xbar_ope1_out_ep>;
+ };
+ };
+ };
};
tegra_mvc1: mvc@290a000 {
@@ -476,7 +1188,27 @@
"nvidia,tegra210-mvc";
reg = <0x0 0x290a000 0x0 0x200>;
sound-name-prefix = "MVC1";
- status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ mvc1_cif_in: endpoint {
+ remote-endpoint = <&xbar_mvc1_in>;
+ };
+ };
+
+ mvc1_out_port: port@1 {
+ reg = <1>;
+
+ mvc1_cif_out: endpoint {
+ remote-endpoint = <&xbar_mvc1_out>;
+ };
+ };
+ };
};
tegra_mvc2: mvc@290a200 {
@@ -484,7 +1216,27 @@
"nvidia,tegra210-mvc";
reg = <0x0 0x290a200 0x0 0x200>;
sound-name-prefix = "MVC2";
- status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ mvc2_cif_in: endpoint {
+ remote-endpoint = <&xbar_mvc2_in>;
+ };
+ };
+
+ mvc2_out_port: port@1 {
+ reg = <1>;
+
+ mvc2_cif_out: endpoint {
+ remote-endpoint = <&xbar_mvc2_out>;
+ };
+ };
+ };
};
tegra_amixer: amixer@290bb00 {
@@ -492,7 +1244,131 @@
"nvidia,tegra210-amixer";
reg = <0x0 0x290bb00 0x0 0x800>;
sound-name-prefix = "MIXER1";
- status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0x0>;
+
+ mix_in1: endpoint {
+ remote-endpoint = <&xbar_mix_in1>;
+ };
+ };
+
+ port@1 {
+ reg = <0x1>;
+
+ mix_in2: endpoint {
+ remote-endpoint = <&xbar_mix_in2>;
+ };
+ };
+
+ port@2 {
+ reg = <0x2>;
+
+ mix_in3: endpoint {
+ remote-endpoint = <&xbar_mix_in3>;
+ };
+ };
+
+ port@3 {
+ reg = <0x3>;
+
+ mix_in4: endpoint {
+ remote-endpoint = <&xbar_mix_in4>;
+ };
+ };
+
+ port@4 {
+ reg = <0x4>;
+
+ mix_in5: endpoint {
+ remote-endpoint = <&xbar_mix_in5>;
+ };
+ };
+
+ port@5 {
+ reg = <0x5>;
+
+ mix_in6: endpoint {
+ remote-endpoint = <&xbar_mix_in6>;
+ };
+ };
+
+ port@6 {
+ reg = <0x6>;
+
+ mix_in7: endpoint {
+ remote-endpoint = <&xbar_mix_in7>;
+ };
+ };
+
+ port@7 {
+ reg = <0x7>;
+
+ mix_in8: endpoint {
+ remote-endpoint = <&xbar_mix_in8>;
+ };
+ };
+
+ port@8 {
+ reg = <0x8>;
+
+ mix_in9: endpoint {
+ remote-endpoint = <&xbar_mix_in9>;
+ };
+ };
+
+ port@9 {
+ reg = <0x9>;
+
+ mix_in10: endpoint {
+ remote-endpoint = <&xbar_mix_in10>;
+ };
+ };
+
+ mix_out1_port: port@a {
+ reg = <0xa>;
+
+ mix_out1: endpoint {
+ remote-endpoint = <&xbar_mix_out1>;
+ };
+ };
+
+ mix_out2_port: port@b {
+ reg = <0xb>;
+
+ mix_out2: endpoint {
+ remote-endpoint = <&xbar_mix_out2>;
+ };
+ };
+
+ mix_out3_port: port@c {
+ reg = <0xc>;
+
+ mix_out3: endpoint {
+ remote-endpoint = <&xbar_mix_out3>;
+ };
+ };
+
+ mix_out4_port: port@d {
+ reg = <0xd>;
+
+ mix_out4: endpoint {
+ remote-endpoint = <&xbar_mix_out4>;
+ };
+ };
+
+ mix_out5_port: port@e {
+ reg = <0xe>;
+
+ mix_out5: endpoint {
+ remote-endpoint = <&xbar_mix_out5>;
+ };
+ };
+ };
};
tegra_admaif: admaif@290f000 {
@@ -543,7 +1419,171 @@
<&mc TEGRA234_MEMORY_CLIENT_APEDMAW &emc>;
interconnect-names = "dma-mem", "write";
iommus = <&smmu_niso0 TEGRA234_SID_APE>;
- status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ admaif0_port: port@0 {
+ reg = <0x0>;
+
+ admaif0: endpoint {
+ remote-endpoint = <&xbar_admaif0>;
+ };
+ };
+
+ admaif1_port: port@1 {
+ reg = <0x1>;
+
+ admaif1: endpoint {
+ remote-endpoint = <&xbar_admaif1>;
+ };
+ };
+
+ admaif2_port: port@2 {
+ reg = <0x2>;
+
+ admaif2: endpoint {
+ remote-endpoint = <&xbar_admaif2>;
+ };
+ };
+
+ admaif3_port: port@3 {
+ reg = <0x3>;
+
+ admaif3: endpoint {
+ remote-endpoint = <&xbar_admaif3>;
+ };
+ };
+
+ admaif4_port: port@4 {
+ reg = <0x4>;
+
+ admaif4: endpoint {
+ remote-endpoint = <&xbar_admaif4>;
+ };
+ };
+
+ admaif5_port: port@5 {
+ reg = <0x5>;
+
+ admaif5: endpoint {
+ remote-endpoint = <&xbar_admaif5>;
+ };
+ };
+
+ admaif6_port: port@6 {
+ reg = <0x6>;
+
+ admaif6: endpoint {
+ remote-endpoint = <&xbar_admaif6>;
+ };
+ };
+
+ admaif7_port: port@7 {
+ reg = <0x7>;
+
+ admaif7: endpoint {
+ remote-endpoint = <&xbar_admaif7>;
+ };
+ };
+
+ admaif8_port: port@8 {
+ reg = <0x8>;
+
+ admaif8: endpoint {
+ remote-endpoint = <&xbar_admaif8>;
+ };
+ };
+
+ admaif9_port: port@9 {
+ reg = <0x9>;
+
+ admaif9: endpoint {
+ remote-endpoint = <&xbar_admaif9>;
+ };
+ };
+
+ admaif10_port: port@a {
+ reg = <0xa>;
+
+ admaif10: endpoint {
+ remote-endpoint = <&xbar_admaif10>;
+ };
+ };
+
+ admaif11_port: port@b {
+ reg = <0xb>;
+
+ admaif11: endpoint {
+ remote-endpoint = <&xbar_admaif11>;
+ };
+ };
+
+ admaif12_port: port@c {
+ reg = <0xc>;
+
+ admaif12: endpoint {
+ remote-endpoint = <&xbar_admaif12>;
+ };
+ };
+
+ admaif13_port: port@d {
+ reg = <0xd>;
+
+ admaif13: endpoint {
+ remote-endpoint = <&xbar_admaif13>;
+ };
+ };
+
+ admaif14_port: port@e {
+ reg = <0xe>;
+
+ admaif14: endpoint {
+ remote-endpoint = <&xbar_admaif14>;
+ };
+ };
+
+ admaif15_port: port@f {
+ reg = <0xf>;
+
+ admaif15: endpoint {
+ remote-endpoint = <&xbar_admaif15>;
+ };
+ };
+
+ admaif16_port: port@10 {
+ reg = <0x10>;
+
+ admaif16: endpoint {
+ remote-endpoint = <&xbar_admaif16>;
+ };
+ };
+
+ admaif17_port: port@11 {
+ reg = <0x11>;
+
+ admaif17: endpoint {
+ remote-endpoint = <&xbar_admaif17>;
+ };
+ };
+
+ admaif18_port: port@12 {
+ reg = <0x12>;
+
+ admaif18: endpoint {
+ remote-endpoint = <&xbar_admaif18>;
+ };
+ };
+
+ admaif19_port: port@13 {
+ reg = <0x13>;
+
+ admaif19: endpoint {
+ remote-endpoint = <&xbar_admaif19>;
+ };
+ };
+ };
};
tegra_asrc: asrc@2910000 {
@@ -551,7 +1591,1045 @@
"nvidia,tegra186-asrc";
reg = <0x0 0x2910000 0x0 0x2000>;
sound-name-prefix = "ASRC1";
- status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0x0>;
+
+ asrc_in1_ep: endpoint {
+ remote-endpoint =
+ <&xbar_asrc_in1_ep>;
+ };
+ };
+
+ port@1 {
+ reg = <0x1>;
+
+ asrc_in2_ep: endpoint {
+ remote-endpoint =
+ <&xbar_asrc_in2_ep>;
+ };
+ };
+
+ port@2 {
+ reg = <0x2>;
+
+ asrc_in3_ep: endpoint {
+ remote-endpoint =
+ <&xbar_asrc_in3_ep>;
+ };
+ };
+
+ port@3 {
+ reg = <0x3>;
+
+ asrc_in4_ep: endpoint {
+ remote-endpoint =
+ <&xbar_asrc_in4_ep>;
+ };
+ };
+
+ port@4 {
+ reg = <0x4>;
+
+ asrc_in5_ep: endpoint {
+ remote-endpoint =
+ <&xbar_asrc_in5_ep>;
+ };
+ };
+
+ port@5 {
+ reg = <0x5>;
+
+ asrc_in6_ep: endpoint {
+ remote-endpoint =
+ <&xbar_asrc_in6_ep>;
+ };
+ };
+
+ port@6 {
+ reg = <0x6>;
+
+ asrc_in7_ep: endpoint {
+ remote-endpoint =
+ <&xbar_asrc_in7_ep>;
+ };
+ };
+
+ asrc_out1_port: port@7 {
+ reg = <0x7>;
+
+ asrc_out1_ep: endpoint {
+ remote-endpoint =
+ <&xbar_asrc_out1_ep>;
+ };
+ };
+
+ asrc_out2_port: port@8 {
+ reg = <0x8>;
+
+ asrc_out2_ep: endpoint {
+ remote-endpoint =
+ <&xbar_asrc_out2_ep>;
+ };
+ };
+
+ asrc_out3_port: port@9 {
+ reg = <0x9>;
+
+ asrc_out3_ep: endpoint {
+ remote-endpoint =
+ <&xbar_asrc_out3_ep>;
+ };
+ };
+
+ asrc_out4_port: port@a {
+ reg = <0xa>;
+
+ asrc_out4_ep: endpoint {
+ remote-endpoint =
+ <&xbar_asrc_out4_ep>;
+ };
+ };
+
+ asrc_out5_port: port@b {
+ reg = <0xb>;
+
+ asrc_out5_ep: endpoint {
+ remote-endpoint =
+ <&xbar_asrc_out5_ep>;
+ };
+ };
+
+ asrc_out6_port: port@c {
+ reg = <0xc>;
+
+ asrc_out6_ep: endpoint {
+ remote-endpoint =
+ <&xbar_asrc_out6_ep>;
+ };
+ };
+ };
+ };
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0x0>;
+
+ xbar_admaif0: endpoint {
+ remote-endpoint = <&admaif0>;
+ };
+ };
+
+ port@1 {
+ reg = <0x1>;
+
+ xbar_admaif1: endpoint {
+ remote-endpoint = <&admaif1>;
+ };
+ };
+
+ port@2 {
+ reg = <0x2>;
+
+ xbar_admaif2: endpoint {
+ remote-endpoint = <&admaif2>;
+ };
+ };
+
+ port@3 {
+ reg = <0x3>;
+
+ xbar_admaif3: endpoint {
+ remote-endpoint = <&admaif3>;
+ };
+ };
+
+ port@4 {
+ reg = <0x4>;
+
+ xbar_admaif4: endpoint {
+ remote-endpoint = <&admaif4>;
+ };
+ };
+
+ port@5 {
+ reg = <0x5>;
+
+ xbar_admaif5: endpoint {
+ remote-endpoint = <&admaif5>;
+ };
+ };
+
+ port@6 {
+ reg = <0x6>;
+
+ xbar_admaif6: endpoint {
+ remote-endpoint = <&admaif6>;
+ };
+ };
+
+ port@7 {
+ reg = <0x7>;
+
+ xbar_admaif7: endpoint {
+ remote-endpoint = <&admaif7>;
+ };
+ };
+
+ port@8 {
+ reg = <0x8>;
+
+ xbar_admaif8: endpoint {
+ remote-endpoint = <&admaif8>;
+ };
+ };
+
+ port@9 {
+ reg = <0x9>;
+
+ xbar_admaif9: endpoint {
+ remote-endpoint = <&admaif9>;
+ };
+ };
+
+ port@a {
+ reg = <0xa>;
+
+ xbar_admaif10: endpoint {
+ remote-endpoint = <&admaif10>;
+ };
+ };
+
+ port@b {
+ reg = <0xb>;
+
+ xbar_admaif11: endpoint {
+ remote-endpoint = <&admaif11>;
+ };
+ };
+
+ port@c {
+ reg = <0xc>;
+
+ xbar_admaif12: endpoint {
+ remote-endpoint = <&admaif12>;
+ };
+ };
+
+ port@d {
+ reg = <0xd>;
+
+ xbar_admaif13: endpoint {
+ remote-endpoint = <&admaif13>;
+ };
+ };
+
+ port@e {
+ reg = <0xe>;
+
+ xbar_admaif14: endpoint {
+ remote-endpoint = <&admaif14>;
+ };
+ };
+
+ port@f {
+ reg = <0xf>;
+
+ xbar_admaif15: endpoint {
+ remote-endpoint = <&admaif15>;
+ };
+ };
+
+ port@10 {
+ reg = <0x10>;
+
+ xbar_admaif16: endpoint {
+ remote-endpoint = <&admaif16>;
+ };
+ };
+
+ port@11 {
+ reg = <0x11>;
+
+ xbar_admaif17: endpoint {
+ remote-endpoint = <&admaif17>;
+ };
+ };
+
+ port@12 {
+ reg = <0x12>;
+
+ xbar_admaif18: endpoint {
+ remote-endpoint = <&admaif18>;
+ };
+ };
+
+ port@13 {
+ reg = <0x13>;
+
+ xbar_admaif19: endpoint {
+ remote-endpoint = <&admaif19>;
+ };
+ };
+
+ xbar_i2s1_port: port@14 {
+ reg = <0x14>;
+
+ xbar_i2s1: endpoint {
+ remote-endpoint = <&i2s1_cif>;
+ };
+ };
+
+ xbar_i2s2_port: port@15 {
+ reg = <0x15>;
+
+ xbar_i2s2: endpoint {
+ remote-endpoint = <&i2s2_cif>;
+ };
+ };
+
+ xbar_i2s3_port: port@16 {
+ reg = <0x16>;
+
+ xbar_i2s3: endpoint {
+ remote-endpoint = <&i2s3_cif>;
+ };
+ };
+
+ xbar_i2s4_port: port@17 {
+ reg = <0x17>;
+
+ xbar_i2s4: endpoint {
+ remote-endpoint = <&i2s4_cif>;
+ };
+ };
+
+ xbar_i2s5_port: port@18 {
+ reg = <0x18>;
+
+ xbar_i2s5: endpoint {
+ remote-endpoint = <&i2s5_cif>;
+ };
+ };
+
+ xbar_i2s6_port: port@19 {
+ reg = <0x19>;
+
+ xbar_i2s6: endpoint {
+ remote-endpoint = <&i2s6_cif>;
+ };
+ };
+
+ xbar_dmic1_port: port@1a {
+ reg = <0x1a>;
+
+ xbar_dmic1: endpoint {
+ remote-endpoint = <&dmic1_cif>;
+ };
+ };
+
+ xbar_dmic2_port: port@1b {
+ reg = <0x1b>;
+
+ xbar_dmic2: endpoint {
+ remote-endpoint = <&dmic2_cif>;
+ };
+ };
+
+ xbar_dmic3_port: port@1c {
+ reg = <0x1c>;
+
+ xbar_dmic3: endpoint {
+ remote-endpoint = <&dmic3_cif>;
+ };
+ };
+
+ xbar_dmic4_port: port@1d {
+ reg = <0x1d>;
+
+ xbar_dmic4: endpoint {
+ remote-endpoint = <&dmic4_cif>;
+ };
+ };
+
+ xbar_dspk1_port: port@1e {
+ reg = <0x1e>;
+
+ xbar_dspk1: endpoint {
+ remote-endpoint = <&dspk1_cif>;
+ };
+ };
+
+ xbar_dspk2_port: port@1f {
+ reg = <0x1f>;
+
+ xbar_dspk2: endpoint {
+ remote-endpoint = <&dspk2_cif>;
+ };
+ };
+
+ xbar_sfc1_in_port: port@20 {
+ reg = <0x20>;
+
+ xbar_sfc1_in: endpoint {
+ remote-endpoint = <&sfc1_cif_in>;
+ };
+ };
+
+ port@21 {
+ reg = <0x21>;
+
+ xbar_sfc1_out: endpoint {
+ remote-endpoint = <&sfc1_cif_out>;
+ };
+ };
+
+ xbar_sfc2_in_port: port@22 {
+ reg = <0x22>;
+
+ xbar_sfc2_in: endpoint {
+ remote-endpoint = <&sfc2_cif_in>;
+ };
+ };
+
+ port@23 {
+ reg = <0x23>;
+
+ xbar_sfc2_out: endpoint {
+ remote-endpoint = <&sfc2_cif_out>;
+ };
+ };
+
+ xbar_sfc3_in_port: port@24 {
+ reg = <0x24>;
+
+ xbar_sfc3_in: endpoint {
+ remote-endpoint = <&sfc3_cif_in>;
+ };
+ };
+
+ port@25 {
+ reg = <0x25>;
+
+ xbar_sfc3_out: endpoint {
+ remote-endpoint = <&sfc3_cif_out>;
+ };
+ };
+
+ xbar_sfc4_in_port: port@26 {
+ reg = <0x26>;
+
+ xbar_sfc4_in: endpoint {
+ remote-endpoint = <&sfc4_cif_in>;
+ };
+ };
+
+ port@27 {
+ reg = <0x27>;
+
+ xbar_sfc4_out: endpoint {
+ remote-endpoint = <&sfc4_cif_out>;
+ };
+ };
+
+ xbar_mvc1_in_port: port@28 {
+ reg = <0x28>;
+
+ xbar_mvc1_in: endpoint {
+ remote-endpoint = <&mvc1_cif_in>;
+ };
+ };
+
+ port@29 {
+ reg = <0x29>;
+
+ xbar_mvc1_out: endpoint {
+ remote-endpoint = <&mvc1_cif_out>;
+ };
+ };
+
+ xbar_mvc2_in_port: port@2a {
+ reg = <0x2a>;
+
+ xbar_mvc2_in: endpoint {
+ remote-endpoint = <&mvc2_cif_in>;
+ };
+ };
+
+ port@2b {
+ reg = <0x2b>;
+
+ xbar_mvc2_out: endpoint {
+ remote-endpoint = <&mvc2_cif_out>;
+ };
+ };
+
+ xbar_amx1_in1_port: port@2c {
+ reg = <0x2c>;
+
+ xbar_amx1_in1: endpoint {
+ remote-endpoint = <&amx1_in1>;
+ };
+ };
+
+ xbar_amx1_in2_port: port@2d {
+ reg = <0x2d>;
+
+ xbar_amx1_in2: endpoint {
+ remote-endpoint = <&amx1_in2>;
+ };
+ };
+
+ xbar_amx1_in3_port: port@2e {
+ reg = <0x2e>;
+
+ xbar_amx1_in3: endpoint {
+ remote-endpoint = <&amx1_in3>;
+ };
+ };
+
+ xbar_amx1_in4_port: port@2f {
+ reg = <0x2f>;
+
+ xbar_amx1_in4: endpoint {
+ remote-endpoint = <&amx1_in4>;
+ };
+ };
+
+ port@30 {
+ reg = <0x30>;
+
+ xbar_amx1_out: endpoint {
+ remote-endpoint = <&amx1_out>;
+ };
+ };
+
+ xbar_amx2_in1_port: port@31 {
+ reg = <0x31>;
+
+ xbar_amx2_in1: endpoint {
+ remote-endpoint = <&amx2_in1>;
+ };
+ };
+
+ xbar_amx2_in2_port: port@32 {
+ reg = <0x32>;
+
+ xbar_amx2_in2: endpoint {
+ remote-endpoint = <&amx2_in2>;
+ };
+ };
+
+ xbar_amx2_in3_port: port@33 {
+ reg = <0x33>;
+
+ xbar_amx2_in3: endpoint {
+ remote-endpoint = <&amx2_in3>;
+ };
+ };
+
+ xbar_amx2_in4_port: port@34 {
+ reg = <0x34>;
+
+ xbar_amx2_in4: endpoint {
+ remote-endpoint = <&amx2_in4>;
+ };
+ };
+
+ port@35 {
+ reg = <0x35>;
+
+ xbar_amx2_out: endpoint {
+ remote-endpoint = <&amx2_out>;
+ };
+ };
+
+ xbar_amx3_in1_port: port@36 {
+ reg = <0x36>;
+
+ xbar_amx3_in1: endpoint {
+ remote-endpoint = <&amx3_in1>;
+ };
+ };
+
+ xbar_amx3_in2_port: port@37 {
+ reg = <0x37>;
+
+ xbar_amx3_in2: endpoint {
+ remote-endpoint = <&amx3_in2>;
+ };
+ };
+
+ xbar_amx3_in3_port: port@38 {
+ reg = <0x38>;
+
+ xbar_amx3_in3: endpoint {
+ remote-endpoint = <&amx3_in3>;
+ };
+ };
+
+ xbar_amx3_in4_port: port@39 {
+ reg = <0x39>;
+
+ xbar_amx3_in4: endpoint {
+ remote-endpoint = <&amx3_in4>;
+ };
+ };
+
+ port@3a {
+ reg = <0x3a>;
+
+ xbar_amx3_out: endpoint {
+ remote-endpoint = <&amx3_out>;
+ };
+ };
+
+ xbar_amx4_in1_port: port@3b {
+ reg = <0x3b>;
+
+ xbar_amx4_in1: endpoint {
+ remote-endpoint = <&amx4_in1>;
+ };
+ };
+
+ xbar_amx4_in2_port: port@3c {
+ reg = <0x3c>;
+
+ xbar_amx4_in2: endpoint {
+ remote-endpoint = <&amx4_in2>;
+ };
+ };
+
+ xbar_amx4_in3_port: port@3d {
+ reg = <0x3d>;
+
+ xbar_amx4_in3: endpoint {
+ remote-endpoint = <&amx4_in3>;
+ };
+ };
+
+ xbar_amx4_in4_port: port@3e {
+ reg = <0x3e>;
+
+ xbar_amx4_in4: endpoint {
+ remote-endpoint = <&amx4_in4>;
+ };
+ };
+
+ port@3f {
+ reg = <0x3f>;
+
+ xbar_amx4_out: endpoint {
+ remote-endpoint = <&amx4_out>;
+ };
+ };
+
+ xbar_adx1_in_port: port@40 {
+ reg = <0x40>;
+
+ xbar_adx1_in: endpoint {
+ remote-endpoint = <&adx1_in>;
+ };
+ };
+
+ port@41 {
+ reg = <0x41>;
+
+ xbar_adx1_out1: endpoint {
+ remote-endpoint = <&adx1_out1>;
+ };
+ };
+
+ port@42 {
+ reg = <0x42>;
+
+ xbar_adx1_out2: endpoint {
+ remote-endpoint = <&adx1_out2>;
+ };
+ };
+
+ port@43 {
+ reg = <0x43>;
+
+ xbar_adx1_out3: endpoint {
+ remote-endpoint = <&adx1_out3>;
+ };
+ };
+
+ port@44 {
+ reg = <0x44>;
+
+ xbar_adx1_out4: endpoint {
+ remote-endpoint = <&adx1_out4>;
+ };
+ };
+
+ xbar_adx2_in_port: port@45 {
+ reg = <0x45>;
+
+ xbar_adx2_in: endpoint {
+ remote-endpoint = <&adx2_in>;
+ };
+ };
+
+ port@46 {
+ reg = <0x46>;
+
+ xbar_adx2_out1: endpoint {
+ remote-endpoint = <&adx2_out1>;
+ };
+ };
+
+ port@47 {
+ reg = <0x47>;
+
+ xbar_adx2_out2: endpoint {
+ remote-endpoint = <&adx2_out2>;
+ };
+ };
+
+ port@48 {
+ reg = <0x48>;
+
+ xbar_adx2_out3: endpoint {
+ remote-endpoint = <&adx2_out3>;
+ };
+ };
+
+ port@49 {
+ reg = <0x49>;
+
+ xbar_adx2_out4: endpoint {
+ remote-endpoint = <&adx2_out4>;
+ };
+ };
+
+ xbar_adx3_in_port: port@4a {
+ reg = <0x4a>;
+
+ xbar_adx3_in: endpoint {
+ remote-endpoint = <&adx3_in>;
+ };
+ };
+
+ port@4b {
+ reg = <0x4b>;
+
+ xbar_adx3_out1: endpoint {
+ remote-endpoint = <&adx3_out1>;
+ };
+ };
+
+ port@4c {
+ reg = <0x4c>;
+
+ xbar_adx3_out2: endpoint {
+ remote-endpoint = <&adx3_out2>;
+ };
+ };
+
+ port@4d {
+ reg = <0x4d>;
+
+ xbar_adx3_out3: endpoint {
+ remote-endpoint = <&adx3_out3>;
+ };
+ };
+
+ port@4e {
+ reg = <0x4e>;
+
+ xbar_adx3_out4: endpoint {
+ remote-endpoint = <&adx3_out4>;
+ };
+ };
+
+ xbar_adx4_in_port: port@4f {
+ reg = <0x4f>;
+
+ xbar_adx4_in: endpoint {
+ remote-endpoint = <&adx4_in>;
+ };
+ };
+
+ port@50 {
+ reg = <0x50>;
+
+ xbar_adx4_out1: endpoint {
+ remote-endpoint = <&adx4_out1>;
+ };
+ };
+
+ port@51 {
+ reg = <0x51>;
+
+ xbar_adx4_out2: endpoint {
+ remote-endpoint = <&adx4_out2>;
+ };
+ };
+
+ port@52 {
+ reg = <0x52>;
+
+ xbar_adx4_out3: endpoint {
+ remote-endpoint = <&adx4_out3>;
+ };
+ };
+
+ port@53 {
+ reg = <0x53>;
+
+ xbar_adx4_out4: endpoint {
+ remote-endpoint = <&adx4_out4>;
+ };
+ };
+
+ xbar_mix_in1_port: port@54 {
+ reg = <0x54>;
+
+ xbar_mix_in1: endpoint {
+ remote-endpoint = <&mix_in1>;
+ };
+ };
+
+ xbar_mix_in2_port: port@55 {
+ reg = <0x55>;
+
+ xbar_mix_in2: endpoint {
+ remote-endpoint = <&mix_in2>;
+ };
+ };
+
+ xbar_mix_in3_port: port@56 {
+ reg = <0x56>;
+
+ xbar_mix_in3: endpoint {
+ remote-endpoint = <&mix_in3>;
+ };
+ };
+
+ xbar_mix_in4_port: port@57 {
+ reg = <0x57>;
+
+ xbar_mix_in4: endpoint {
+ remote-endpoint = <&mix_in4>;
+ };
+ };
+
+ xbar_mix_in5_port: port@58 {
+ reg = <0x58>;
+
+ xbar_mix_in5: endpoint {
+ remote-endpoint = <&mix_in5>;
+ };
+ };
+
+ xbar_mix_in6_port: port@59 {
+ reg = <0x59>;
+
+ xbar_mix_in6: endpoint {
+ remote-endpoint = <&mix_in6>;
+ };
+ };
+
+ xbar_mix_in7_port: port@5a {
+ reg = <0x5a>;
+
+ xbar_mix_in7: endpoint {
+ remote-endpoint = <&mix_in7>;
+ };
+ };
+
+ xbar_mix_in8_port: port@5b {
+ reg = <0x5b>;
+
+ xbar_mix_in8: endpoint {
+ remote-endpoint = <&mix_in8>;
+ };
+ };
+
+ xbar_mix_in9_port: port@5c {
+ reg = <0x5c>;
+
+ xbar_mix_in9: endpoint {
+ remote-endpoint = <&mix_in9>;
+ };
+ };
+
+ xbar_mix_in10_port: port@5d {
+ reg = <0x5d>;
+
+ xbar_mix_in10: endpoint {
+ remote-endpoint = <&mix_in10>;
+ };
+ };
+
+ port@5e {
+ reg = <0x5e>;
+
+ xbar_mix_out1: endpoint {
+ remote-endpoint = <&mix_out1>;
+ };
+ };
+
+ port@5f {
+ reg = <0x5f>;
+
+ xbar_mix_out2: endpoint {
+ remote-endpoint = <&mix_out2>;
+ };
+ };
+
+ port@60 {
+ reg = <0x60>;
+
+ xbar_mix_out3: endpoint {
+ remote-endpoint = <&mix_out3>;
+ };
+ };
+
+ port@61 {
+ reg = <0x61>;
+
+ xbar_mix_out4: endpoint {
+ remote-endpoint = <&mix_out4>;
+ };
+ };
+
+ port@62 {
+ reg = <0x62>;
+
+ xbar_mix_out5: endpoint {
+ remote-endpoint = <&mix_out5>;
+ };
+ };
+
+ xbar_asrc_in1_port: port@63 {
+ reg = <0x63>;
+
+ xbar_asrc_in1_ep: endpoint {
+ remote-endpoint = <&asrc_in1_ep>;
+ };
+ };
+
+ port@64 {
+ reg = <0x64>;
+
+ xbar_asrc_out1_ep: endpoint {
+ remote-endpoint = <&asrc_out1_ep>;
+ };
+ };
+
+ xbar_asrc_in2_port: port@65 {
+ reg = <0x65>;
+
+ xbar_asrc_in2_ep: endpoint {
+ remote-endpoint = <&asrc_in2_ep>;
+ };
+ };
+
+ port@66 {
+ reg = <0x66>;
+
+ xbar_asrc_out2_ep: endpoint {
+ remote-endpoint = <&asrc_out2_ep>;
+ };
+ };
+
+ xbar_asrc_in3_port: port@67 {
+ reg = <0x67>;
+
+ xbar_asrc_in3_ep: endpoint {
+ remote-endpoint = <&asrc_in3_ep>;
+ };
+ };
+
+ port@68 {
+ reg = <0x68>;
+
+ xbar_asrc_out3_ep: endpoint {
+ remote-endpoint = <&asrc_out3_ep>;
+ };
+ };
+
+ xbar_asrc_in4_port: port@69 {
+ reg = <0x69>;
+
+ xbar_asrc_in4_ep: endpoint {
+ remote-endpoint = <&asrc_in4_ep>;
+ };
+ };
+
+ port@6a {
+ reg = <0x6a>;
+
+ xbar_asrc_out4_ep: endpoint {
+ remote-endpoint = <&asrc_out4_ep>;
+ };
+ };
+
+ xbar_asrc_in5_port: port@6b {
+ reg = <0x6b>;
+
+ xbar_asrc_in5_ep: endpoint {
+ remote-endpoint = <&asrc_in5_ep>;
+ };
+ };
+
+ port@6c {
+ reg = <0x6c>;
+
+ xbar_asrc_out5_ep: endpoint {
+ remote-endpoint = <&asrc_out5_ep>;
+ };
+ };
+
+ xbar_asrc_in6_port: port@6d {
+ reg = <0x6d>;
+
+ xbar_asrc_in6_ep: endpoint {
+ remote-endpoint = <&asrc_in6_ep>;
+ };
+ };
+
+ port@6e {
+ reg = <0x6e>;
+
+ xbar_asrc_out6_ep: endpoint {
+ remote-endpoint = <&asrc_out6_ep>;
+ };
+ };
+
+ xbar_asrc_in7_port: port@6f {
+ reg = <0x6f>;
+
+ xbar_asrc_in7_ep: endpoint {
+ remote-endpoint = <&asrc_in7_ep>;
+ };
+ };
+
+ xbar_ope1_in_port: port@70 {
+ reg = <0x70>;
+
+ xbar_ope1_in_ep: endpoint {
+ remote-endpoint = <&ope1_cif_in_ep>;
+ };
+ };
+
+ port@71 {
+ reg = <0x71>;
+
+ xbar_ope1_out_ep: endpoint {
+ remote-endpoint = <&ope1_cif_out_ep>;
+ };
+ };
};
};
@@ -1461,6 +3539,14 @@
iommus = <&smmu_niso0 TEGRA234_SID_MGBE>;
power-domains = <&bpmp TEGRA234_POWER_DOMAIN_MGBEB>;
status = "disabled";
+
+ snps,axi-config = <&mgbe0_axi_setup>;
+
+ mgbe0_axi_setup: stmmac-axi-config {
+ snps,blen = <256 128 64 32>;
+ snps,rd_osr_lmt = <63>;
+ snps,wr_osr_lmt = <63>;
+ };
};
ethernet@6900000 {
@@ -1495,6 +3581,14 @@
iommus = <&smmu_niso0 TEGRA234_SID_MGBE_VF1>;
power-domains = <&bpmp TEGRA234_POWER_DOMAIN_MGBEC>;
status = "disabled";
+
+ snps,axi-config = <&mgbe1_axi_setup>;
+
+ mgbe1_axi_setup: stmmac-axi-config {
+ snps,blen = <256 128 64 32>;
+ snps,rd_osr_lmt = <63>;
+ snps,wr_osr_lmt = <63>;
+ };
};
ethernet@6a00000 {
@@ -1529,6 +3623,14 @@
iommus = <&smmu_niso0 TEGRA234_SID_MGBE_VF2>;
power-domains = <&bpmp TEGRA234_POWER_DOMAIN_MGBED>;
status = "disabled";
+
+ snps,axi-config = <&mgbe2_axi_setup>;
+
+ mgbe2_axi_setup: stmmac-axi-config {
+ snps,blen = <256 128 64 32>;
+ snps,rd_osr_lmt = <63>;
+ snps,wr_osr_lmt = <63>;
+ };
};
ethernet@6b00000 {
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 39889d5f8e12..7d40ec5e7d21 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -23,6 +23,7 @@ dtb-$(CONFIG_ARCH_QCOM) += ipq9574-rdp433.dtb
dtb-$(CONFIG_ARCH_QCOM) += ipq9574-rdp449.dtb
dtb-$(CONFIG_ARCH_QCOM) += ipq9574-rdp453.dtb
dtb-$(CONFIG_ARCH_QCOM) += ipq9574-rdp454.dtb
+dtb-$(CONFIG_ARCH_QCOM) += msm8216-samsung-fortuna3g.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8916-acer-a1-724.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8916-alcatel-idol347.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8916-asus-z00l.dtb
@@ -35,11 +36,14 @@ dtb-$(CONFIG_ARCH_QCOM) += msm8916-samsung-a3u-eur.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8916-samsung-a5u-eur.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8916-samsung-e5.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8916-samsung-e7.dtb
+dtb-$(CONFIG_ARCH_QCOM) += msm8916-samsung-gprimeltecan.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8916-samsung-grandmax.dtb
+dtb-$(CONFIG_ARCH_QCOM) += msm8916-samsung-grandprimelte.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8916-samsung-gt510.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8916-samsung-gt58.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8916-samsung-j5.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8916-samsung-j5x.dtb
+dtb-$(CONFIG_ARCH_QCOM) += msm8916-samsung-rossa.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8916-samsung-serranove.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8916-thwc-uf896.dtb
dtb-$(CONFIG_ARCH_QCOM) += msm8916-thwc-ufi001c.dtb
@@ -210,6 +214,7 @@ dtb-$(CONFIG_ARCH_QCOM) += sm6125-sony-xperia-seine-pdx201.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm6125-xiaomi-laurel-sprout.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm6350-sony-xperia-lena-pdx213.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm6375-sony-xperia-murray-pdx225.dtb
+dtb-$(CONFIG_ARCH_QCOM) += sm7125-xiaomi-curtana.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm7125-xiaomi-joyeuse.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm7225-fairphone-fp4.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8150-hdk.dtb
@@ -233,6 +238,7 @@ dtb-$(CONFIG_ARCH_QCOM) += sm8450-hdk.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8450-qrd.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm8450-sony-xperia-nagara-pdx223.dtb
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) += sm8650-mtp.dtb
diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc-d3-camera-mezzanine.dts b/arch/arm64/boot/dts/qcom/apq8016-sbc-d3-camera-mezzanine.dts
index c08b4be5cc7e..f9cbf8c1d689 100644
--- a/arch/arm64/boot/dts/qcom/apq8016-sbc-d3-camera-mezzanine.dts
+++ b/arch/arm64/boot/dts/qcom/apq8016-sbc-d3-camera-mezzanine.dts
@@ -9,7 +9,7 @@
#include "apq8016-sbc.dts"
/ {
- camera_vdddo_1v8: camera-vdddo-1v8 {
+ camera_vdddo_1v8: regulator-camera-vdddo {
compatible = "regulator-fixed";
regulator-name = "camera_vdddo";
regulator-min-microvolt = <1800000>;
@@ -17,7 +17,7 @@
regulator-always-on;
};
- camera_vdda_2v8: camera-vdda-2v8 {
+ camera_vdda_2v8: regulator-camera-vdda {
compatible = "regulator-fixed";
regulator-name = "camera_vdda";
regulator-min-microvolt = <2800000>;
@@ -25,7 +25,7 @@
regulator-always-on;
};
- camera_vddd_1v5: camera-vddd-1v5 {
+ camera_vddd_1v5: regulator-camera-vddd {
compatible = "regulator-fixed";
regulator-name = "camera_vddd";
regulator-min-microvolt = <1500000>;
@@ -53,7 +53,7 @@
};
&cci_i2c0 {
- camera_rear@3b {
+ camera@3b {
compatible = "ovti,ov5640";
reg = <0x3b>;
diff --git a/arch/arm64/boot/dts/qcom/ipq5332.dtsi b/arch/arm64/boot/dts/qcom/ipq5332.dtsi
index 42e2e48b2bc3..770d9c2fb456 100644
--- a/arch/arm64/boot/dts/qcom/ipq5332.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq5332.dtsi
@@ -320,8 +320,12 @@
compatible = "qcom,ipq5332-dwc3", "qcom,dwc3";
reg = <0x08af8800 0x400>;
- interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "hs_phy_irq";
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 53 IRQ_TYPE_EDGE_BOTH>,
+ <GIC_SPI 52 IRQ_TYPE_EDGE_BOTH>;
+ interrupt-names = "pwr_event",
+ "dp_hs_phy_irq",
+ "dm_hs_phy_irq";
clocks = <&gcc GCC_USB0_MASTER_CLK>,
<&gcc GCC_SNOC_USB_CLK>,
diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
index 61c8fd49c966..4e29adea570a 100644
--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
@@ -9,6 +9,7 @@
#include <dt-bindings/clock/qcom,gcc-ipq6018.h>
#include <dt-bindings/reset/qcom,gcc-ipq6018.h>
#include <dt-bindings/clock/qcom,apss-ipq.h>
+#include <dt-bindings/thermal/thermal.h>
/ {
#address-cells = <2>;
@@ -43,6 +44,7 @@
clock-names = "cpu";
operating-points-v2 = <&cpu_opp_table>;
cpu-supply = <&ipq6018_s2>;
+ #cooling-cells = <2>;
};
CPU1: cpu@1 {
@@ -55,6 +57,7 @@
clock-names = "cpu";
operating-points-v2 = <&cpu_opp_table>;
cpu-supply = <&ipq6018_s2>;
+ #cooling-cells = <2>;
};
CPU2: cpu@2 {
@@ -67,6 +70,7 @@
clock-names = "cpu";
operating-points-v2 = <&cpu_opp_table>;
cpu-supply = <&ipq6018_s2>;
+ #cooling-cells = <2>;
};
CPU3: cpu@3 {
@@ -79,6 +83,7 @@
clock-names = "cpu";
operating-points-v2 = <&cpu_opp_table>;
cpu-supply = <&ipq6018_s2>;
+ #cooling-cells = <2>;
};
L2_0: l2-cache {
@@ -330,6 +335,16 @@
clock-names = "core";
};
+ tsens: thermal-sensor@4a9000 {
+ compatible = "qcom,ipq6018-tsens", "qcom,ipq8074-tsens";
+ reg = <0x0 0x004a9000 0x0 0x1000>,
+ <0x0 0x004a8000 0x0 0x1000>;
+ interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "combined";
+ #qcom,sensors = <16>;
+ #thermal-sensor-cells = <1>;
+ };
+
cryptobam: dma-controller@704000 {
compatible = "qcom,bam-v1.7.0";
reg = <0x0 0x00704000 0x0 0x20000>;
@@ -418,6 +433,12 @@
<&gcc GCC_USB1_MOCK_UTMI_CLK>;
assigned-clock-rates = <133330000>,
<24000000>;
+
+ interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "pwr_event",
+ "qusb2_phy";
+
resets = <&gcc GCC_USB1_BCR>;
status = "disabled";
@@ -578,6 +599,21 @@
status = "disabled";
};
+ blsp1_i2c6: i2c@78ba000 {
+ compatible = "qcom,i2c-qup-v2.2.1";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0 0x078ba000 0x0 0x600>;
+ interrupts = <GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&gcc GCC_BLSP1_QUP6_I2C_APPS_CLK>,
+ <&gcc GCC_BLSP1_AHB_CLK>;
+ clock-names = "core", "iface";
+ clock-frequency = <400000>;
+ dmas = <&blsp_dma 22>, <&blsp_dma 23>;
+ dma-names = "tx", "rx";
+ status = "disabled";
+ };
+
qpic_bam: dma-controller@7984000 {
compatible = "qcom,bam-v1.7.0";
reg = <0x0 0x07984000 0x0 0x1a000>;
@@ -630,6 +666,13 @@
<133330000>,
<24000000>;
+ interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "pwr_event",
+ "qusb2_phy",
+ "ss_phy_irq";
+
resets = <&gcc GCC_USB0_BCR>;
status = "disabled";
@@ -867,6 +910,122 @@
};
};
+ thermal-zones {
+ nss-top-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&tsens 4>;
+
+ trips {
+ nss-top-critical {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ nss-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&tsens 5>;
+
+ trips {
+ nss-critical {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ wcss-phya0-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&tsens 7>;
+
+ trips {
+ wcss-phya0-critical {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ wcss-phya1-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&tsens 8>;
+
+ trips {
+ wcss-phya1-critical {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpu-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&tsens 13>;
+
+ trips {
+ cpu-critical {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+
+ cpu_alert: cpu-passive {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "passive";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ 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>;
+ };
+ };
+ };
+
+ lpass-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&tsens 14>;
+
+ trips {
+ lpass-critical {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
+ ddrss-top-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&tsens 15>;
+
+ trips {
+ ddrss-top-critical {
+ temperature = <125000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+ };
+
timer {
compatible = "arm,armv8-timer";
interrupts = <GIC_PPI 2 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
index 26441447c866..e5b89753aa5c 100644
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -252,6 +252,8 @@
clocks = <&gcc GCC_MDIO_AHB_CLK>;
clock-names = "gcc_mdio_ahb_clk";
+ clock-frequency = <6250000>;
+
status = "disabled";
};
@@ -627,6 +629,13 @@
<133330000>,
<19200000>;
+ interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "pwr_event",
+ "qusb2_phy",
+ "ss_phy_irq";
+
power-domains = <&gcc USB0_GDSC>;
resets = <&gcc GCC_USB0_BCR>;
@@ -669,6 +678,13 @@
<133330000>,
<19200000>;
+ interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "pwr_event",
+ "qusb2_phy",
+ "ss_phy_irq";
+
power-domains = <&gcc USB1_GDSC>;
resets = <&gcc GCC_USB1_BCR>;
diff --git a/arch/arm64/boot/dts/qcom/ipq9574.dtsi b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
index 5f83ee42a719..7f2e5cbf3bbb 100644
--- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
@@ -321,8 +321,10 @@
sdhc_1: mmc@7804000 {
compatible = "qcom,ipq9574-sdhci", "qcom,sdhci-msm-v5";
- reg = <0x07804000 0x1000>, <0x07805000 0x1000>;
- reg-names = "hc", "cqhci";
+ reg = <0x07804000 0x1000>,
+ <0x07805000 0x1000>,
+ <0x07808000 0x2000>;
+ reg-names = "hc", "cqhci", "ice";
interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
@@ -330,9 +332,11 @@
clocks = <&gcc GCC_SDCC1_AHB_CLK>,
<&gcc GCC_SDCC1_APPS_CLK>,
- <&xo_board_clk>;
- clock-names = "iface", "core", "xo";
+ <&xo_board_clk>,
+ <&gcc GCC_SDCC1_ICE_CORE_CLK>;
+ clock-names = "iface", "core", "xo", "ice";
non-removable;
+ supports-cqe;
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/qcom/msm8216-samsung-fortuna3g.dts b/arch/arm64/boot/dts/qcom/msm8216-samsung-fortuna3g.dts
new file mode 100644
index 000000000000..366914be7d53
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8216-samsung-fortuna3g.dts
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+/dts-v1/;
+
+#include "msm8916-samsung-fortuna-common.dtsi"
+
+/ {
+ model = "Samsung Galaxy Grand Prime (SM-G530H)";
+ compatible = "samsung,fortuna3g", "qcom,msm8916";
+ chassis-type = "handset";
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-fortuna-common.dtsi b/arch/arm64/boot/dts/qcom/msm8916-samsung-fortuna-common.dtsi
new file mode 100644
index 000000000000..c2800ad2dd5b
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-fortuna-common.dtsi
@@ -0,0 +1,203 @@
+// 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_uart2;
+ };
+
+ chosen {
+ stdout-path = "serial0";
+ };
+
+ reserved-memory {
+ /* Additional memory used by Samsung firmware modifications */
+ tz-apps@85a00000 {
+ reg = <0x0 0x85a00000 0x0 0x600000>;
+ no-map;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ pinctrl-0 = <&gpio_keys_default>;
+ pinctrl-names = "default";
+
+ label = "GPIO Buttons";
+
+ button-volume-up {
+ label = "Volume Up";
+ gpios = <&tlmm 107 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ };
+
+ button-home {
+ label = "Home";
+ gpios = <&tlmm 109 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_HOMEPAGE>;
+ };
+ };
+
+ haptic {
+ compatible = "regulator-haptic";
+ haptic-supply = <&reg_motor_vdd>;
+ min-microvolt = <3300000>;
+ max-microvolt = <3300000>;
+ };
+
+ reg_motor_vdd: regulator-motor-vdd {
+ compatible = "regulator-fixed";
+ regulator-name = "motor_vdd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ gpio = <&tlmm 72 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-0 = <&motor_en_default>;
+ pinctrl-names = "default";
+ };
+};
+
+&blsp_i2c1 {
+ status = "okay";
+
+ muic: extcon@25 {
+ compatible = "siliconmitus,sm5502-muic";
+ reg = <0x25>;
+ interrupts-extended = <&tlmm 12 IRQ_TYPE_EDGE_FALLING>;
+ pinctrl-0 = <&muic_int_default>;
+ pinctrl-names = "default";
+ };
+};
+
+&blsp_i2c4 {
+ status = "okay";
+
+ fuel-gauge@35 {
+ compatible = "richtek,rt5033-battery";
+ reg = <0x35>;
+
+ interrupts-extended = <&tlmm 121 IRQ_TYPE_EDGE_FALLING>;
+
+ pinctrl-0 = <&fg_alert_default>;
+ pinctrl-names = "default";
+ };
+};
+
+&blsp_uart2 {
+ status = "okay";
+};
+
+&mpss_mem {
+ reg = <0x0 0x86800000 0x0 0x5000000>;
+};
+
+&pm8916_resin {
+ linux,code = <KEY_VOLUMEDOWN>;
+ status = "okay";
+};
+
+&pm8916_rpm_regulators {
+ pm8916_l17: l17 {
+ regulator-min-microvolt = <2850000>;
+ regulator-max-microvolt = <2850000>;
+ };
+};
+
+&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 {
+ model = "msm8916-1mic";
+ audio-routing =
+ "AMIC1", "MIC BIAS External1",
+ "AMIC2", "MIC BIAS Internal2",
+ "AMIC3", "MIC BIAS External1";
+};
+
+&usb {
+ extcon = <&muic>, <&muic>;
+ status = "okay";
+};
+
+&usb_hs_phy {
+ extcon = <&muic>;
+};
+
+&venus {
+ status = "okay";
+};
+
+&venus_mem {
+ status = "okay";
+};
+
+&wcnss {
+ status = "okay";
+};
+
+&wcnss_iris {
+ compatible = "qcom,wcn3620";
+};
+
+&wcnss_mem {
+ status = "okay";
+};
+
+&tlmm {
+ fg_alert_default: fg-alert-default-state {
+ pins = "gpio121";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ gpio_keys_default: gpio-keys-default-state {
+ pins = "gpio107", "gpio109";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ motor_en_default: motor-en-default-state {
+ pins = "gpio72";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ muic_int_default: muic-int-default-state {
+ pins = "gpio12";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ sdc2_cd_default: sdc2-cd-default-state {
+ pins = "gpio38";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-gprimeltecan.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-gprimeltecan.dts
new file mode 100644
index 000000000000..9d65fa58ba92
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-gprimeltecan.dts
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+/dts-v1/;
+
+#include "msm8916-samsung-fortuna-common.dtsi"
+
+/ {
+ model = "Samsung Galaxy Grand Prime (SM-G530W)";
+ compatible = "samsung,gprimeltecan", "qcom,msm8916";
+ chassis-type = "handset";
+
+ reserved-memory {
+ /* Firmware for gprimeltecan needs more space */
+ /delete-node/ tz-apps@85a00000;
+
+ /* Additional memory used by Samsung firmware modifications */
+ tz-apps@85500000 {
+ reg = <0x0 0x85500000 0x0 0xb00000>;
+ no-map;
+ };
+ };
+};
+
+&mpss_mem {
+ /* Firmware for gprimeltecan needs more space */
+ reg = <0x0 0x86800000 0x0 0x5400000>;
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-grandprimelte.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-grandprimelte.dts
new file mode 100644
index 000000000000..a66ce4b13547
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-grandprimelte.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+/dts-v1/;
+
+#include "msm8916-samsung-fortuna-common.dtsi"
+
+/ {
+ model = "Samsung Galaxy Grand Prime (SM-G530FZ)";
+ compatible = "samsung,grandprimelte", "qcom,msm8916";
+ chassis-type = "handset";
+};
+
+&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
new file mode 100644
index 000000000000..42843771ae2a
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-rossa-common.dtsi
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "msm8916-samsung-fortuna-common.dtsi"
+
+/* SM5504 MUIC instead of SM5502 */
+/delete-node/ &muic;
+
+&blsp_i2c1 {
+ muic: extcon@14 {
+ compatible = "siliconmitus,sm5504-muic";
+ reg = <0x14>;
+ interrupts-extended = <&tlmm 12 IRQ_TYPE_EDGE_FALLING>;
+ pinctrl-0 = <&muic_int_default>;
+ pinctrl-names = "default";
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-rossa.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-rossa.dts
new file mode 100644
index 000000000000..ebaa13c6b016
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8916-samsung-rossa.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+/dts-v1/;
+
+#include "msm8916-samsung-rossa-common.dtsi"
+
+/ {
+ model = "Samsung Galaxy Core Prime LTE";
+ compatible = "samsung,rossa", "qcom,msm8916";
+ chassis-type = "handset";
+};
+
+&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 e423c57ddd41..cedff4166bfb 100644
--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
@@ -1785,6 +1785,8 @@
power-domains = <&gcc OXILI_GDSC>;
operating-points-v2 = <&gpu_opp_table>;
iommus = <&gpu_iommu 1>, <&gpu_iommu 2>;
+ #cooling-cells = <2>;
+
status = "disabled";
gpu_opp_table: opp-table {
@@ -2688,6 +2690,13 @@
thermal-sensors = <&tsens 2>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu_alert0>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
gpu_alert0: trip-point0 {
temperature = <75000>;
diff --git a/arch/arm64/boot/dts/qcom/msm8939.dtsi b/arch/arm64/boot/dts/qcom/msm8939.dtsi
index 82d85ff61045..dd45975682b2 100644
--- a/arch/arm64/boot/dts/qcom/msm8939.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8939.dtsi
@@ -1427,6 +1427,8 @@
power-domains = <&gcc OXILI_GDSC>;
operating-points-v2 = <&opp_table>;
iommus = <&gpu_iommu 1>, <&gpu_iommu 2>;
+ #cooling-cells = <2>;
+
status = "disabled";
opp_table: opp-table {
@@ -2456,6 +2458,13 @@
thermal-sensors = <&tsens 3>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu_alert0>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
gpu_alert0: trip-point0 {
temperature = <75000>;
@@ -2463,7 +2472,7 @@
type = "passive";
};
- gpu_crit: gpu_crit {
+ gpu_crit: gpu-crit {
temperature = <95000>;
hysteresis = <2000>;
type = "critical";
diff --git a/arch/arm64/boot/dts/qcom/msm8953.dtsi b/arch/arm64/boot/dts/qcom/msm8953.dtsi
index ad2f8cf9c966..f1011bb641c6 100644
--- a/arch/arm64/boot/dts/qcom/msm8953.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953.dtsi
@@ -859,6 +859,8 @@
"vsync",
"core";
+ resets = <&gcc GCC_MDSS_BCR>;
+
#address-cells = <1>;
#size-cells = <1>;
ranges;
@@ -1044,6 +1046,125 @@
};
};
+ gpu: gpu@1c00000 {
+ compatible = "qcom,adreno-506.0", "qcom,adreno";
+ reg = <0x01c00000 0x40000>;
+ reg-names = "kgsl_3d0_reg_memory";
+ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+
+ clocks = <&gcc GCC_OXILI_GFX3D_CLK>,
+ <&gcc GCC_OXILI_AHB_CLK>,
+ <&gcc GCC_BIMC_GFX_CLK>,
+ <&gcc GCC_BIMC_GPU_CLK>,
+ <&gcc GCC_OXILI_TIMER_CLK>,
+ <&gcc GCC_OXILI_AON_CLK>;
+ clock-names = "core",
+ "iface",
+ "mem_iface",
+ "alt_mem_iface",
+ "rbbmtimer",
+ "alwayson";
+ power-domains = <&gcc OXILI_GX_GDSC>;
+
+ iommus = <&gpu_iommu 0>;
+ operating-points-v2 = <&gpu_opp_table>;
+
+ #cooling-cells = <2>;
+
+ status = "disabled";
+
+ zap-shader {
+ memory-region = <&zap_shader_region>;
+ };
+
+ gpu_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-19200000 {
+ opp-hz = /bits/ 64 <19200000>;
+ opp-supported-hw = <0xff>;
+ required-opps = <&rpmpd_opp_min_svs>;
+ };
+
+ opp-133300000 {
+ opp-hz = /bits/ 64 <133300000>;
+ opp-supported-hw = <0xff>;
+ required-opps = <&rpmpd_opp_min_svs>;
+ };
+
+ opp-216000000 {
+ opp-hz = /bits/ 64 <216000000>;
+ opp-supported-hw = <0xff>;
+ required-opps = <&rpmpd_opp_low_svs>;
+ };
+
+ opp-320000000 {
+ opp-hz = /bits/ 64 <320000000>;
+ opp-supported-hw = <0xff>;
+ required-opps = <&rpmpd_opp_svs>;
+ };
+
+ opp-400000000 {
+ opp-hz = /bits/ 64 <400000000>;
+ opp-supported-hw = <0xff>;
+ required-opps = <&rpmpd_opp_svs_plus>;
+ };
+
+ opp-510000000 {
+ opp-hz = /bits/ 64 <510000000>;
+ opp-supported-hw = <0xff>;
+ required-opps = <&rpmpd_opp_nom>;
+ };
+
+ opp-560000000 {
+ opp-hz = /bits/ 64 <560000000>;
+ opp-supported-hw = <0xff>;
+ required-opps = <&rpmpd_opp_nom_plus>;
+ };
+
+ /*
+ * This opp is only available on msm8953 and
+ * sdm632, the max for sdm450 is 600MHz.
+ */
+ opp-650000000 {
+ opp-hz = /bits/ 64 <650000000>;
+ opp-supported-hw = <0xff>;
+ required-opps = <&rpmpd_opp_turbo>;
+ };
+ };
+ };
+
+ gpu_iommu: iommu@1c48000 {
+ compatible = "qcom,msm8953-iommu", "qcom,msm-iommu-v2";
+ ranges = <0 0x01c48000 0x8000>;
+
+ clocks = <&gcc GCC_OXILI_AHB_CLK>,
+ <&gcc GCC_BIMC_GFX_CLK>;
+ clock-names = "iface", "bus";
+
+ power-domains = <&gcc OXILI_CX_GDSC>;
+
+ qcom,iommu-secure-id = <18>;
+
+ #address-cells = <1>;
+ #iommu-cells = <1>;
+ #size-cells = <1>;
+
+ /* gfx3d_user */
+ iommu-ctx@0 {
+ compatible = "qcom,msm-iommu-v2-ns";
+ reg = <0x0000 0x1000>;
+ interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ /* gfx3d_secure */
+ iommu-ctx@2000 {
+ compatible = "qcom,msm-iommu-v2-sec";
+ reg = <0x2000 0x1000>;
+ interrupts = <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
apps_iommu: iommu@1e20000 {
compatible = "qcom,msm8953-iommu", "qcom,msm-iommu-v1";
ranges = <0 0x01e20000 0x20000>;
@@ -1160,9 +1281,12 @@
#size-cells = <1>;
ranges;
- interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+ interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "hs_phy_irq", "ss_phy_irq";
+ interrupt-names = "pwr_event",
+ "qusb2_phy",
+ "ss_phy_irq";
clocks = <&gcc GCC_USB_PHY_CFG_AHB_CLK>,
<&gcc GCC_USB30_MASTER_CLK>,
@@ -2012,6 +2136,33 @@
};
};
};
+
+ gpu-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&tsens0 15>;
+
+ trips {
+ gpu_alert: trip-point0 {
+ temperature = <70000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ gpu_crit: crit {
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&gpu_alert>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
};
timer {
diff --git a/arch/arm64/boot/dts/qcom/msm8994-msft-lumia-octagon.dtsi b/arch/arm64/boot/dts/qcom/msm8994-msft-lumia-octagon.dtsi
index cbc84459a5ae..10cd244dea4f 100644
--- a/arch/arm64/boot/dts/qcom/msm8994-msft-lumia-octagon.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8994-msft-lumia-octagon.dtsi
@@ -377,7 +377,7 @@
&blsp2_i2c1 {
status = "okay";
- sideinteraction: ad7147_captouch@2c {
+ sideinteraction: touch@2c {
compatible = "ad,ad7147_captouch";
reg = <0x2c>;
diff --git a/arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi b/arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi
index 9dbde79f26a2..0163d41f95f8 100644
--- a/arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi
@@ -79,7 +79,7 @@
pmsg-size = <0x80000>;
};
- fb_region: fb_region@40000000 {
+ fb_region: fb@40000000 {
reg = <0 0x40000000 0 0x1000000>;
no-map;
};
diff --git a/arch/arm64/boot/dts/qcom/msm8994.dtsi b/arch/arm64/boot/dts/qcom/msm8994.dtsi
index 8295bf1b219d..695e541832ad 100644
--- a/arch/arm64/boot/dts/qcom/msm8994.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8994.dtsi
@@ -233,7 +233,7 @@
#size-cells = <2>;
ranges;
- dfps_data_mem: dfps_data_mem@3400000 {
+ dfps_data_mem: dfps-data@3400000 {
reg = <0 0x03400000 0 0x1000>;
no-map;
};
@@ -243,7 +243,7 @@
no-map;
};
- smem_mem: smem_region@6a00000 {
+ smem_mem: smem@6a00000 {
reg = <0 0x06a00000 0 0x200000>;
no-map;
};
diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
index ee6f87c828ae..1601e46549e7 100644
--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -756,12 +756,12 @@
#address-cells = <1>;
#size-cells = <1>;
- qusb2p_hstx_trim: hstx_trim@24e {
+ qusb2p_hstx_trim: hstx-trim@24e {
reg = <0x24e 0x2>;
bits = <5 4>;
};
- qusb2s_hstx_trim: hstx_trim@24f {
+ qusb2s_hstx_trim: hstx-trim@24f {
reg = <0x24f 0x1>;
bits = <1 4>;
};
@@ -2077,7 +2077,7 @@
<0 0>,
<0 0>,
<150000000 300000000>,
- <0 0>,
+ <75000000 150000000>,
<0 0>,
<0 0>,
<0 0>,
@@ -2096,8 +2096,8 @@
compatible = "qcom,msm8996-qmp-ufs-phy";
reg = <0x00627000 0x1000>;
- clocks = <&gcc GCC_UFS_CLKREF_CLK>;
- clock-names = "ref";
+ clocks = <&rpmcc RPM_SMD_LN_BB_CLK>, <&gcc GCC_UFS_CLKREF_CLK>;
+ clock-names = "ref", "qref";
resets = <&ufshc 0>;
reset-names = "ufsphy";
@@ -3381,8 +3381,12 @@
#size-cells = <1>;
ranges;
- interrupts = <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "hs_phy_irq";
+ interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "pwr_event",
+ "qusb2_phy",
+ "hs_phy_irq";
clocks = <&gcc GCC_PERIPH_NOC_USB20_AHB_CLK>,
<&gcc GCC_USB20_MASTER_CLK>,
diff --git a/arch/arm64/boot/dts/qcom/msm8998.dtsi b/arch/arm64/boot/dts/qcom/msm8998.dtsi
index 2793cc22d381..4dfe2d09ac28 100644
--- a/arch/arm64/boot/dts/qcom/msm8998.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8998.dtsi
@@ -1047,12 +1047,12 @@
compatible = "qcom,msm8998-qmp-ufs-phy";
reg = <0x01da7000 0x1000>;
- clock-names =
- "ref",
- "ref_aux";
- clocks =
- <&gcc GCC_UFS_CLKREF_CLK>,
- <&gcc GCC_UFS_PHY_AUX_CLK>;
+ clocks = <&rpmcc RPM_SMD_LN_BB_CLK1>,
+ <&gcc GCC_UFS_PHY_AUX_CLK>,
+ <&gcc GCC_UFS_CLKREF_CLK>;
+ clock-names = "ref",
+ "ref_aux",
+ "qref";
reset-names = "ufsphy";
resets = <&ufshc 0>;
@@ -1072,6 +1072,11 @@
reg = <0x01f60000 0x20000>;
};
+ tcsr_regs_2: syscon@1fc0000 {
+ compatible = "qcom,msm8998-tcsr", "syscon";
+ reg = <0x01fc0000 0x26000>;
+ };
+
tlmm: pinctrl@3400000 {
compatible = "qcom,msm8998-pinctrl";
reg = <0x03400000 0xc00000>;
@@ -2132,9 +2137,12 @@
<&gcc GCC_USB30_MASTER_CLK>;
assigned-clock-rates = <19200000>, <120000000>;
- interrupts = <GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH>,
+ interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "hs_phy_irq", "ss_phy_irq";
+ interrupt-names = "pwr_event",
+ "qusb2_phy",
+ "ss_phy_irq";
power-domains = <&gcc USB_30_GDSC>;
@@ -2174,6 +2182,8 @@
reset-names = "phy",
"phy_phy";
+ qcom,tcsr-reg = <&tcsr_regs_2 0xb244>;
+
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/qcom/pm2250.dtsi b/arch/arm64/boot/dts/qcom/pm4125.dtsi
index 5f1d15db5c99..cf8c822e80ce 100644
--- a/arch/arm64/boot/dts/qcom/pm2250.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm4125.dtsi
@@ -19,7 +19,7 @@
compatible = "qcom,pm8916-pon";
reg = <0x800>;
- pm2250_pwrkey: pwrkey {
+ pm4125_pwrkey: pwrkey {
compatible = "qcom,pm8941-pwrkey";
interrupts-extended = <&spmi_bus 0x0 0x8 0 IRQ_TYPE_EDGE_BOTH>;
linux,code = <KEY_POWER>;
@@ -27,7 +27,7 @@
bias-pull-up;
};
- pm2250_resin: resin {
+ pm4125_resin: resin {
compatible = "qcom,pm8941-resin";
interrupts-extended = <&spmi_bus 0x0 0x8 1 IRQ_TYPE_EDGE_BOTH>;
debounce = <15625>;
@@ -36,6 +36,36 @@
};
};
+ pm4125_vbus: usb-vbus-regulator@1100 {
+ compatible = "qcom,pm4125-vbus-reg", "qcom,pm8150b-vbus-reg";
+ reg = <0x1100>;
+ status = "disabled";
+ };
+
+ pm4125_typec: typec@1500 {
+ compatible = "qcom,pm4125-typec", "qcom,pmi632-typec";
+ reg = <0x1500>;
+ interrupts = <0x0 0x15 0x00 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0x15 0x01 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x15 0x02 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0x15 0x03 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x15 0x04 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0x15 0x05 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0x15 0x06 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x15 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";
+ vdd-vbus-supply = <&pm4125_vbus>;
+
+ status = "disabled";
+ };
+
rtc@6000 {
compatible = "qcom,pm8941-rtc";
reg = <0x6000>, <0x6100>;
@@ -43,11 +73,11 @@
interrupts-extended = <&spmi_bus 0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>;
};
- pm2250_gpios: gpio@c000 {
+ pm4125_gpios: gpio@c000 {
compatible = "qcom,pm2250-gpio", "qcom,spmi-gpio";
reg = <0xc000>;
gpio-controller;
- gpio-ranges = <&pm2250_gpios 0 0 10>;
+ gpio-ranges = <&pm4125_gpios 0 0 10>;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
diff --git a/arch/arm64/boot/dts/qcom/pm6150.dtsi b/arch/arm64/boot/dts/qcom/pm6150.dtsi
index ddbaf7280b03..11158c2bd524 100644
--- a/arch/arm64/boot/dts/qcom/pm6150.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm6150.dtsi
@@ -63,6 +63,52 @@
};
};
+ pm6150_vbus: usb-vbus-regulator@1100 {
+ compatible = "qcom,pm6150-vbus-reg,
+ qcom,pm8150b-vbus-reg";
+ reg = <0x1100>;
+ status = "disabled";
+ };
+
+ pm6150_typec: typec@1500 {
+ 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>,
+ <0x0 0x15 0x02 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0x15 0x03 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x15 0x04 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0x15 0x05 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0x15 0x06 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x15 0x07 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0x17 0x00 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0x17 0x01 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0x17 0x02 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0x17 0x03 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0x17 0x04 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0x17 0x05 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0x17 0x06 IRQ_TYPE_EDGE_RISING>,
+ <0x0 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";
+ status = "disabled";
+ };
+
pm6150_temp: temp-alarm@2400 {
compatible = "qcom,spmi-temp-alarm";
reg = <0x2400>;
diff --git a/arch/arm64/boot/dts/qcom/pmi632.dtsi b/arch/arm64/boot/dts/qcom/pmi632.dtsi
index 4eb79e0ce40a..94d53b1cf6c8 100644
--- a/arch/arm64/boot/dts/qcom/pmi632.dtsi
+++ b/arch/arm64/boot/dts/qcom/pmi632.dtsi
@@ -45,6 +45,36 @@
#address-cells = <1>;
#size-cells = <0>;
+ pmi632_vbus: usb-vbus-regulator@1100 {
+ compatible = "qcom,pmi632-vbus-reg", "qcom,pm8150b-vbus-reg";
+ reg = <0x1100>;
+ status = "disabled";
+ };
+
+ pmi632_typec: typec@1500 {
+ compatible = "qcom,pmi632-typec";
+ reg = <0x1500>;
+ interrupts = <0x2 0x15 0x00 IRQ_TYPE_EDGE_RISING>,
+ <0x2 0x15 0x01 IRQ_TYPE_EDGE_BOTH>,
+ <0x2 0x15 0x02 IRQ_TYPE_EDGE_RISING>,
+ <0x2 0x15 0x03 IRQ_TYPE_EDGE_BOTH>,
+ <0x2 0x15 0x04 IRQ_TYPE_EDGE_RISING>,
+ <0x2 0x15 0x05 IRQ_TYPE_EDGE_RISING>,
+ <0x2 0x15 0x06 IRQ_TYPE_EDGE_BOTH>,
+ <0x2 0x15 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";
+ vdd-vbus-supply = <&pmi632_vbus>;
+
+ status = "disabled";
+ };
+
pmi632_temp: temp-alarm@2400 {
compatible = "qcom,spmi-temp-alarm";
reg = <0x2400>;
@@ -127,6 +157,11 @@
status = "disabled";
};
+ pmi632_pbs_client3: pbs@7400 {
+ compatible = "qcom,pmi632-pbs", "qcom,pbs";
+ reg = <0x7400>;
+ };
+
pmi632_sdam_7: nvram@b600 {
compatible = "qcom,spmi-sdam";
reg = <0xb600>;
@@ -155,6 +190,10 @@
pmi632_lpg: pwm {
compatible = "qcom,pmi632-lpg";
+ nvmem = <&pmi632_sdam_7>;
+ nvmem-names = "lpg_chan_sdam";
+ qcom,pbs = <&pmi632_pbs_client3>;
+
#address-cells = <1>;
#size-cells = <0>;
#pwm-cells = <2>;
diff --git a/arch/arm64/boot/dts/qcom/qcm2290.dtsi b/arch/arm64/boot/dts/qcom/qcm2290.dtsi
index 0911fb08ed63..89beac833d43 100644
--- a/arch/arm64/boot/dts/qcom/qcm2290.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcm2290.dtsi
@@ -442,6 +442,11 @@
#hwlock-cells = <1>;
};
+ tcsr_regs: syscon@3c0000 {
+ compatible = "qcom,qcm2290-tcsr", "syscon";
+ reg = <0x0 0x003c0000 0x0 0x40000>;
+ };
+
tlmm: pinctrl@500000 {
compatible = "qcom,qcm2290-tlmm";
reg = <0x0 0x00500000 0x0 0x300000>;
@@ -690,6 +695,8 @@
#phy-cells = <0>;
+ qcom,tcsr-reg = <&tcsr_regs 0xb244>;
+
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts b/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts
index 176898c9dbbd..4ff9fc24e50e 100644
--- a/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts
+++ b/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts
@@ -71,6 +71,41 @@
};
};
+ 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_1_dwc3_ss>;
+ };
+ };
+ };
+ };
+ };
+
reserved-memory {
cont_splash_mem: cont-splash@e1000000 {
reg = <0x0 0xe1000000 0x0 0x2300000>;
@@ -82,6 +117,11 @@
no-map;
};
+ removed_mem: removed@c0000000 {
+ reg = <0x0 0xc0000000 0x0 0x5100000>;
+ no-map;
+ };
+
rmtfs_mem: memory@f8500000 {
compatible = "qcom,rmtfs-mem";
reg = <0x0 0xf8500000 0x0 0x600000>;
@@ -886,7 +926,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 = <&pmic_glink_ss_in>;
};
&usb_1_hsphy {
@@ -915,6 +964,11 @@
status = "okay";
};
+&venus {
+ firmware-name = "qcom/qcm6490/fairphone5/venus.mbn";
+ status = "okay";
+};
+
&wifi {
qcom,ath11k-calibration-variant = "Fairphone_5";
status = "okay";
diff --git a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts
index 03e97e27d16d..e4bfad50a669 100644
--- a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts
+++ b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts
@@ -5,8 +5,14 @@
/dts-v1/;
+/* PM7250B is configured to use SID8/9 */
+#define PM7250B_SID 8
+#define PM7250B_SID1 9
+
+#include <dt-bindings/leds/common.h>
#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
#include "sc7280.dtsi"
+#include "pm7250b.dtsi"
#include "pm7325.dtsi"
#include "pm8350c.dtsi"
#include "pmk8350.dtsi"
@@ -109,7 +115,7 @@
no-map;
};
- trusted_apps_mem: trusted_apps@c1800000 {
+ trusted_apps_mem: trusted-apps@c1800000 {
reg = <0x0 0xc1800000 0x0 0x1c00000>;
no-map;
};
@@ -123,8 +129,8 @@
vph_pwr: vph-pwr-regulator {
compatible = "regulator-fixed";
regulator-name = "vph_pwr";
- regulator-min-microvolt = <2500000>;
- regulator-max-microvolt = <4350000>;
+ regulator-min-microvolt = <3700000>;
+ regulator-max-microvolt = <3700000>;
};
};
@@ -415,6 +421,33 @@
};
};
+&pm8350c_pwm {
+ status = "okay";
+
+ multi-led {
+ color = <LED_COLOR_ID_RGB>;
+ function = LED_FUNCTION_STATUS;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_RED>;
+ };
+
+ led@2 {
+ reg = <2>;
+ color = <LED_COLOR_ID_GREEN>;
+ };
+
+ led@3 {
+ reg = <3>;
+ color = <LED_COLOR_ID_BLUE>;
+ };
+ };
+};
+
&qupv3_id_0 {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/qcom/qcs404.dtsi b/arch/arm64/boot/dts/qcom/qcs404.dtsi
index 2f2eeaf2e945..a05d0234f7fc 100644
--- a/arch/arm64/boot/dts/qcom/qcs404.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcs404.dtsi
@@ -675,6 +675,14 @@
assigned-clocks = <&gcc GCC_USB20_MOCK_UTMI_CLK>,
<&gcc GCC_USB30_MASTER_CLK>;
assigned-clock-rates = <19200000>, <200000000>;
+
+ interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "pwr_event",
+ "hs_phy_irq",
+ "qusb2_phy";
+
status = "disabled";
usb3_dwc3: usb@7580000 {
@@ -704,6 +712,14 @@
assigned-clocks = <&gcc GCC_USB20_MOCK_UTMI_CLK>,
<&gcc GCC_USB_HS_SYSTEM_CLK>;
assigned-clock-rates = <19200000>, <133333333>;
+
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "pwr_event",
+ "hs_phy_irq",
+ "qusb2_phy";
+
status = "disabled";
usb@78c0000 {
diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
index 8bb7d13d85f6..97824c769ba3 100644
--- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
+++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
@@ -110,7 +110,7 @@
no-map;
};
- trusted_apps_mem: trusted_apps@c1800000 {
+ trusted_apps_mem: trusted-apps@c1800000 {
reg = <0x0 0xc1800000 0x0 0x1c00000>;
no-map;
};
@@ -124,8 +124,8 @@
vph_pwr: vph-pwr-regulator {
compatible = "regulator-fixed";
regulator-name = "vph_pwr";
- regulator-min-microvolt = <2500000>;
- regulator-max-microvolt = <4350000>;
+ regulator-min-microvolt = <3700000>;
+ regulator-max-microvolt = <3700000>;
};
};
@@ -413,6 +413,23 @@
};
};
+&gcc {
+ protected-clocks = <GCC_CFG_NOC_LPASS_CLK>,
+ <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>;
+};
+
&qupv3_id_0 {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts b/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts
index aa53b6af6d9c..6e9dd0312adc 100644
--- a/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts
+++ b/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts
@@ -7,7 +7,7 @@
#include <dt-bindings/leds/common.h>
#include "qcm2290.dtsi"
-#include "pm2250.dtsi"
+#include "pm4125.dtsi"
/ {
model = "Qualcomm Technologies, Inc. Robotics RB1";
@@ -177,6 +177,24 @@
};
};
+&CPU_PD0 {
+ /delete-property/ power-domains;
+};
+
+&CPU_PD1 {
+ /delete-property/ power-domains;
+};
+
+&CPU_PD2 {
+ /delete-property/ power-domains;
+};
+
+&CPU_PD3 {
+ /delete-property/ power-domains;
+};
+
+/delete-node/ &CLUSTER_PD;
+
&gpi_dma0 {
status = "okay";
};
@@ -226,7 +244,7 @@
};
&mdss_dsi0 {
- vdda-supply = <&pm2250_l5>;
+ vdda-supply = <&pm4125_l5>;
status = "okay";
};
@@ -239,7 +257,7 @@
status = "okay";
};
-&pm2250_resin {
+&pm4125_resin {
linux,code = <KEY_VOLUMEDOWN>;
status = "okay";
};
@@ -263,23 +281,23 @@
compatible = "qcom,rpm-pm2250-regulators";
vdd_s3-supply = <&vph_pwr>;
vdd_s4-supply = <&vph_pwr>;
- vdd_l1_l2_l3_l5_l6_l7_l8_l9_l10_l11_l12-supply = <&pm2250_s3>;
+ vdd_l1_l2_l3_l5_l6_l7_l8_l9_l10_l11_l12-supply = <&pm4125_s3>;
vdd_l4_l17_l18_l19_l20_l21_l22-supply = <&vph_pwr>;
- vdd_l13_l14_l15_l16-supply = <&pm2250_s4>;
+ vdd_l13_l14_l15_l16-supply = <&pm4125_s4>;
/*
* S1 - VDD_APC
* S2 - VDD_CX
*/
- pm2250_s3: s3 {
+ pm4125_s3: s3 {
/* 0.4V-1.6625V -> 1.3V (Power tree requirements) */
regulator-min-microvolt = <1352000>;
regulator-max-microvolt = <1352000>;
regulator-boot-on;
};
- pm2250_s4: s4 {
+ pm4125_s4: s4 {
/* 1.2V-2.35V -> 2.05V (Power tree requirements) */
regulator-min-microvolt = <2072000>;
regulator-max-microvolt = <2072000>;
@@ -288,7 +306,7 @@
/* L1 - VDD_MX */
- pm2250_l2: l2 {
+ pm4125_l2: l2 {
/* LPDDR4X VDD2 */
regulator-min-microvolt = <1136000>;
regulator-max-microvolt = <1136000>;
@@ -296,7 +314,7 @@
regulator-boot-on;
};
- pm2250_l3: l3 {
+ pm4125_l3: l3 {
/* LPDDR4X VDDQ */
regulator-min-microvolt = <616000>;
regulator-max-microvolt = <616000>;
@@ -304,14 +322,14 @@
regulator-boot-on;
};
- pm2250_l4: l4 {
+ pm4125_l4: l4 {
/* max = 3.05V -> max = 2.7 to disable 3V signaling (SDHCI2) */
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <2700000>;
regulator-allow-set-load;
};
- pm2250_l5: l5 {
+ pm4125_l5: l5 {
/* CSI/DSI */
regulator-min-microvolt = <1232000>;
regulator-max-microvolt = <1232000>;
@@ -319,7 +337,7 @@
regulator-boot-on;
};
- pm2250_l6: l6 {
+ pm4125_l6: l6 {
/* DRAM PLL */
regulator-min-microvolt = <928000>;
regulator-max-microvolt = <928000>;
@@ -327,7 +345,7 @@
regulator-boot-on;
};
- pm2250_l7: l7 {
+ pm4125_l7: l7 {
/* Wi-Fi CX/MX */
regulator-min-microvolt = <664000>;
regulator-max-microvolt = <664000>;
@@ -338,20 +356,20 @@
* L9 - VDD_LPI_MX
*/
- pm2250_l10: l10 {
+ pm4125_l10: l10 {
/* Wi-Fi RFA */
regulator-min-microvolt = <1304000>;
regulator-max-microvolt = <1304000>;
};
- pm2250_l11: l11 {
+ pm4125_l11: l11 {
/* GPS RF1 */
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
regulator-boot-on;
};
- pm2250_l12: l12 {
+ pm4125_l12: l12 {
/* USB PHYs */
regulator-min-microvolt = <928000>;
regulator-max-microvolt = <928000>;
@@ -359,7 +377,7 @@
regulator-boot-on;
};
- pm2250_l13: l13 {
+ pm4125_l13: l13 {
/* USB/QFPROM/PLLs */
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
@@ -367,7 +385,7 @@
regulator-boot-on;
};
- pm2250_l14: l14 {
+ pm4125_l14: l14 {
/* SDHCI1 VQMMC */
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
@@ -376,7 +394,7 @@
regulator-always-on;
};
- pm2250_l15: l15 {
+ pm4125_l15: l15 {
/* WCD/DSI/BT VDDIO */
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
@@ -385,38 +403,38 @@
regulator-boot-on;
};
- pm2250_l16: l16 {
+ pm4125_l16: l16 {
/* GPS RF2 */
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-boot-on;
};
- pm2250_l17: l17 {
+ pm4125_l17: l17 {
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
};
- pm2250_l18: l18 {
+ pm4125_l18: l18 {
/* VDD_PXn */
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
- pm2250_l19: l19 {
+ pm4125_l19: l19 {
/* VDD_PXn */
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
- pm2250_l20: l20 {
+ pm4125_l20: l20 {
/* SDHCI1 VMMC */
regulator-min-microvolt = <2400000>;
regulator-max-microvolt = <3600000>;
regulator-allow-set-load;
};
- pm2250_l21: l21 {
+ pm4125_l21: l21 {
/* SDHCI2 VMMC */
regulator-min-microvolt = <2960000>;
regulator-max-microvolt = <3300000>;
@@ -424,7 +442,7 @@
regulator-boot-on;
};
- pm2250_l22: l22 {
+ pm4125_l22: l22 {
/* Wi-Fi */
regulator-min-microvolt = <3312000>;
regulator-max-microvolt = <3312000>;
@@ -433,8 +451,8 @@
};
&sdhc_1 {
- vmmc-supply = <&pm2250_l20>;
- vqmmc-supply = <&pm2250_l14>;
+ vmmc-supply = <&pm4125_l20>;
+ vqmmc-supply = <&pm4125_l14>;
pinctrl-0 = <&sdc1_state_on>;
pinctrl-1 = <&sdc1_state_off>;
pinctrl-names = "default", "sleep";
@@ -446,8 +464,8 @@
};
&sdhc_2 {
- vmmc-supply = <&pm2250_l21>;
- vqmmc-supply = <&pm2250_l4>;
+ vmmc-supply = <&pm4125_l21>;
+ vqmmc-supply = <&pm4125_l4>;
cd-gpios = <&tlmm 88 GPIO_ACTIVE_LOW>;
pinctrl-0 = <&sdc2_state_on &sd_det_in_on>;
pinctrl-1 = <&sdc2_state_off &sd_det_in_off>;
@@ -518,8 +536,8 @@
};
&usb_qmpphy {
- vdda-phy-supply = <&pm2250_l12>;
- vdda-pll-supply = <&pm2250_l13>;
+ vdda-phy-supply = <&pm4125_l12>;
+ vdda-pll-supply = <&pm4125_l13>;
status = "okay";
};
@@ -528,17 +546,17 @@
};
&usb_hsphy {
- vdd-supply = <&pm2250_l12>;
- vdda-pll-supply = <&pm2250_l13>;
- vdda-phy-dpdm-supply = <&pm2250_l21>;
+ vdd-supply = <&pm4125_l12>;
+ vdda-pll-supply = <&pm4125_l13>;
+ vdda-phy-dpdm-supply = <&pm4125_l21>;
status = "okay";
};
&wifi {
- vdd-0.8-cx-mx-supply = <&pm2250_l7>;
- vdd-1.8-xo-supply = <&pm2250_l13>;
- vdd-1.3-rfa-supply = <&pm2250_l10>;
- vdd-3.3-ch0-supply = <&pm2250_l22>;
+ 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";
status = "okay";
};
diff --git a/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts b/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts
index 7c19f874fa71..696d6d43c56b 100644
--- a/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts
+++ b/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts
@@ -6,8 +6,10 @@
/dts-v1/;
#include <dt-bindings/leds/common.h>
+#include <dt-bindings/usb/pd.h>
#include "sm4250.dtsi"
#include "pm6125.dtsi"
+#include "pmi632.dtsi"
/ {
model = "Qualcomm Technologies, Inc. QRB4210 RB2";
@@ -256,6 +258,46 @@
};
};
+&pmi632_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>;
+ pmi632_hs_in: endpoint {
+ remote-endpoint = <&usb_dwc3_hs>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ pmi632_ss_in: endpoint {
+ remote-endpoint = <&usb_qmpphy_out>;
+ };
+ };
+ };
+ };
+};
+
+&pmi632_vbus {
+ regulator-min-microamp = <500000>;
+ regulator-max-microamp = <3000000>;
+ status = "okay";
+};
+
&pon_pwrkey {
status = "okay";
};
@@ -607,8 +649,8 @@
status = "okay";
};
-&usb_dwc3 {
- maximum-speed = "super-speed";
+&usb_dwc3_hs {
+ remote-endpoint = <&pmi632_hs_in>;
};
&usb_hsphy {
@@ -626,6 +668,10 @@
status = "okay";
};
+&usb_qmpphy_out {
+ remote-endpoint = <&pmi632_ss_in>;
+};
+
&wifi {
vdd-0.8-cx-mx-supply = <&vreg_l8a_0p664>;
vdd-1.8-xo-supply = <&vreg_l16a_1p3>;
diff --git a/arch/arm64/boot/dts/qcom/sa8295p-adp.dts b/arch/arm64/boot/dts/qcom/sa8295p-adp.dts
index fd253942e5e5..78e933c42c31 100644
--- a/arch/arm64/boot/dts/qcom/sa8295p-adp.dts
+++ b/arch/arm64/boot/dts/qcom/sa8295p-adp.dts
@@ -108,6 +108,13 @@
};
};
};
+
+ reserved-memory {
+ gpu_mem: gpu-mem@8bf00000 {
+ reg = <0 0x8bf00000 0 0x2000>;
+ no-map;
+ };
+ };
};
&apps_rsc {
@@ -266,6 +273,48 @@
status = "okay";
};
+&i2c12 {
+ pinctrl-0 = <&qup1_i2c4_state>;
+ pinctrl-names = "default";
+
+ status = "okay";
+
+ vdd_gfx: regulator@39 {
+ compatible = "maxim,max20411";
+ reg = <0x39>;
+
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <800000>;
+
+ enable-gpios = <&pmm8540a_gpios 2 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-0 = <&max20411_en>;
+ pinctrl-names = "default";
+ };
+};
+
+&gpucc {
+ vdd-gfx-supply = <&vdd_gfx>;
+ status = "okay";
+};
+
+&gmu {
+ status = "okay";
+};
+
+&gpu {
+ status = "okay";
+
+ zap-shader {
+ memory-region = <&gpu_mem>;
+ firmware-name = "qcom/sa8295p/a690_zap.mbn";
+ };
+};
+
+&gpu_smmu {
+ status = "okay";
+};
+
&mdss0 {
status = "okay";
};
@@ -476,6 +525,10 @@
status = "okay";
};
+&qup1 {
+ status = "okay";
+};
+
&qup2 {
status = "okay";
};
@@ -636,6 +689,14 @@
/* PINCTRL */
+&pmm8540a_gpios {
+ max20411_en: max20411-en-state {
+ pins = "gpio2";
+ function = "normal";
+ output-enable;
+ };
+};
+
&tlmm {
pcie2a_default: pcie2a-default-state {
clkreq-n-pins {
@@ -728,4 +789,11 @@
bias-pull-up;
};
};
+
+ qup1_i2c4_state: qup1-i2c4-state {
+ pins = "gpio0", "gpio1";
+ function = "qup12";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
};
diff --git a/arch/arm64/boot/dts/qcom/sa8540p-ride.dts b/arch/arm64/boot/dts/qcom/sa8540p-ride.dts
index b04f72ec097c..177b9dad6ff7 100644
--- a/arch/arm64/boot/dts/qcom/sa8540p-ride.dts
+++ b/arch/arm64/boot/dts/qcom/sa8540p-ride.dts
@@ -376,14 +376,14 @@
pinctrl-names = "default";
pinctrl-0 = <&pcie2a_default>;
- status = "okay";
+ status = "disabled";
};
&pcie2a_phy {
vdda-phy-supply = <&vreg_l11a>;
vdda-pll-supply = <&vreg_l3a>;
- status = "okay";
+ status = "disabled";
};
&pcie3a {
diff --git a/arch/arm64/boot/dts/qcom/sa8540p.dtsi b/arch/arm64/boot/dts/qcom/sa8540p.dtsi
index 96b2c59ad02b..23888029cc11 100644
--- a/arch/arm64/boot/dts/qcom/sa8540p.dtsi
+++ b/arch/arm64/boot/dts/qcom/sa8540p.dtsi
@@ -168,6 +168,9 @@
};
&gpucc {
+ /* SA8295P and SA8540P doesn't provide gfx.lvl */
+ /delete-property/ power-domains;
+
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/qcom/sa8775p.dtsi b/arch/arm64/boot/dts/qcom/sa8775p.dtsi
index a7eaca33d326..231cea1f0fa8 100644
--- a/arch/arm64/boot/dts/qcom/sa8775p.dtsi
+++ b/arch/arm64/boot/dts/qcom/sa8775p.dtsi
@@ -356,13 +356,18 @@
no-map;
};
+ ddr_training_checksum: ddr-training-checksum@908c0000 {
+ reg = <0x0 0x908c0000 0x0 0x1000>;
+ no-map;
+ };
+
reserved_mem: reserved@908f0000 {
- reg = <0x0 0x908f0000 0x0 0xf000>;
+ reg = <0x0 0x908f0000 0x0 0xe000>;
no-map;
};
- secdata_apss_mem: secdata-apss@908ff000 {
- reg = <0x0 0x908ff000 0x0 0x1000>;
+ secdata_apss_mem: secdata-apss@908fe000 {
+ reg = <0x0 0x908fe000 0x0 0x2000>;
no-map;
};
@@ -373,8 +378,43 @@
hwlocks = <&tcsr_mutex 3>;
};
- cpucp_fw_mem: cpucp-fw@90b00000 {
- reg = <0x0 0x90b00000 0x0 0x100000>;
+ tz_sail_mailbox_mem: tz-sail-mailbox@90c00000 {
+ reg = <0x0 0x90c00000 0x0 0x100000>;
+ no-map;
+ };
+
+ sail_mailbox_mem: sail-ss@90d00000 {
+ reg = <0x0 0x90d00000 0x0 0x100000>;
+ no-map;
+ };
+
+ sail_ota_mem: sail-ss@90e00000 {
+ reg = <0x0 0x90e00000 0x0 0x300000>;
+ no-map;
+ };
+
+ aoss_backup_mem: aoss-backup@91b00000 {
+ reg = <0x0 0x91b00000 0x0 0x40000>;
+ no-map;
+ };
+
+ cpucp_backup_mem: cpucp-backup@91b40000 {
+ reg = <0x0 0x91b40000 0x0 0x40000>;
+ no-map;
+ };
+
+ tz_config_backup_mem: tz-config-backup@91b80000 {
+ reg = <0x0 0x91b80000 0x0 0x10000>;
+ no-map;
+ };
+
+ ddr_training_data_mem: ddr-training-data@91b90000 {
+ reg = <0x0 0x91b90000 0x0 0x10000>;
+ no-map;
+ };
+
+ cdt_data_backup_mem: cdt-data-backup@91ba0000 {
+ reg = <0x0 0x91ba0000 0x0 0x1000>;
no-map;
};
@@ -433,13 +473,43 @@
no-map;
};
+ audio_mdf_mem: audio-mdf-region@ae000000 {
+ reg = <0x0 0xae000000 0x0 0x1000000>;
+ no-map;
+ };
+
+ firmware_mem: firmware-region@b0000000 {
+ reg = <0x0 0xb0000000 0x0 0x800000>;
+ no-map;
+ };
+
hyptz_reserved_mem: hyptz-reserved@beb00000 {
reg = <0x0 0xbeb00000 0x0 0x11500000>;
no-map;
};
- tz_stat_mem: tz-stat@d0000000 {
- reg = <0x0 0xd0000000 0x0 0x100000>;
+ scmi_mem: scmi-region@d0000000 {
+ reg = <0x0 0xd0000000 0x0 0x40000>;
+ no-map;
+ };
+
+ firmware_logs_mem: firmware-logs@d0040000 {
+ reg = <0x0 0xd0040000 0x0 0x10000>;
+ no-map;
+ };
+
+ firmware_audio_mem: firmware-audio@d0050000 {
+ reg = <0x0 0xd0050000 0x0 0x4000>;
+ no-map;
+ };
+
+ firmware_reserved_mem: firmware-reserved@d0054000 {
+ reg = <0x0 0xd0054000 0x0 0x9c000>;
+ no-map;
+ };
+
+ firmware_quantum_test_mem: firmware-quantum-test@d00f0000 {
+ reg = <0x0 0xd00f0000 0x0 0x10000>;
no-map;
};
@@ -453,8 +523,23 @@
no-map;
};
- trusted_apps_mem: trusted-apps@d1800000 {
- reg = <0x0 0xd1800000 0x0 0x3900000>;
+ deepsleep_backup_mem: deepsleep-backup@d1800000 {
+ reg = <0x0 0xd1800000 0x0 0x100000>;
+ no-map;
+ };
+
+ trusted_apps_mem: trusted-apps@d1900000 {
+ reg = <0x0 0xd1900000 0x0 0x3800000>;
+ no-map;
+ };
+
+ tz_stat_mem: tz-stat@db100000 {
+ reg = <0x0 0xdb100000 0x0 0x100000>;
+ no-map;
+ };
+
+ cpucp_fw_mem: cpucp-fw@db200000 {
+ reg = <0x0 0xdb200000 0x0 0x100000>;
no-map;
};
};
@@ -1615,10 +1700,12 @@
assigned-clock-rates = <19200000>, <200000000>;
interrupts-extended = <&intc GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>,
<&pdc 14 IRQ_TYPE_EDGE_BOTH>,
<&pdc 15 IRQ_TYPE_EDGE_BOTH>,
<&pdc 12 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "pwr_event",
+ "hs_phy_irq",
"dp_hs_phy_irq",
"dm_hs_phy_irq",
"ss_phy_irq";
@@ -1702,10 +1789,12 @@
assigned-clock-rates = <19200000>, <200000000>;
interrupts-extended = <&intc GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 351 IRQ_TYPE_LEVEL_HIGH>,
<&pdc 8 IRQ_TYPE_EDGE_BOTH>,
<&pdc 7 IRQ_TYPE_EDGE_BOTH>,
<&pdc 13 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "pwr_event",
+ "hs_phy_irq",
"dp_hs_phy_irq",
"dm_hs_phy_irq",
"ss_phy_irq";
@@ -1765,9 +1854,11 @@
assigned-clock-rates = <19200000>, <200000000>;
interrupts-extended = <&intc GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 443 IRQ_TYPE_LEVEL_HIGH>,
<&pdc 10 IRQ_TYPE_EDGE_BOTH>,
<&pdc 9 IRQ_TYPE_EDGE_BOTH>;
interrupt-names = "pwr_event",
+ "hs_phy_irq",
"dp_hs_phy_irq",
"dm_hs_phy_irq";
@@ -2394,8 +2485,9 @@
<0x0 0x23016000 0x0 0x100>;
reg-names = "stmmaceth", "rgmii";
- interrupts = <GIC_SPI 929 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "macirq";
+ interrupts = <GIC_SPI 929 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 781 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "macirq", "sfty";
clocks = <&gcc GCC_EMAC1_AXI_CLK>,
<&gcc GCC_EMAC1_SLV_AHB_CLK>,
@@ -2427,8 +2519,9 @@
<0x0 0x23056000 0x0 0x100>;
reg-names = "stmmaceth", "rgmii";
- interrupts = <GIC_SPI 946 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "macirq";
+ interrupts = <GIC_SPI 946 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 782 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "macirq", "sfty";
clocks = <&gcc GCC_EMAC0_AXI_CLK>,
<&gcc GCC_EMAC0_SLV_AHB_CLK>,
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
index 46aaeba28604..5260c63db007 100644
--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
@@ -649,6 +649,7 @@ ap_ec_spi: &spi6 {
pinctrl-names = "default";
pinctrl-0 = <&ap_ec_int_l>;
spi-max-frequency = <3000000>;
+ wakeup-source;
cros_ec_pwm: pwm {
compatible = "google,cros-ec-pwm";
@@ -943,6 +944,8 @@ ap_spi_fp: &spi10 {
vddrf-supply = <&pp1300_l2c>;
vddch0-supply = <&pp3300_l10c>;
max-speed = <3200000>;
+
+ qcom,local-bd-address-broken;
};
};
diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi
index 4dcaa15caef2..2b481e20ae38 100644
--- a/arch/arm64/boot/dts/qcom/sc7180.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi
@@ -817,7 +817,7 @@
bits = <1 3>;
};
- gpu_speed_bin: gpu_speed_bin@1d2 {
+ gpu_speed_bin: gpu-speed-bin@1d2 {
reg = <0x1d2 0x2>;
bits = <5 8>;
};
@@ -1532,6 +1532,76 @@
qcom,bcm-voters = <&apps_bcm_voter>;
};
+ ufs_mem_hc: ufshc@1d84000 {
+ compatible = "qcom,sc7180-ufshc", "qcom,ufshc",
+ "jedec,ufs-2.0";
+ reg = <0 0x01d84000 0 0x3000>;
+ interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&ufs_mem_phy>;
+ phy-names = "ufsphy";
+ lanes-per-direction = <1>;
+ #reset-cells = <1>;
+ resets = <&gcc GCC_UFS_PHY_BCR>;
+ reset-names = "rst";
+
+ power-domains = <&gcc UFS_PHY_GDSC>;
+
+ iommus = <&apps_smmu 0xa0 0x0>;
+
+ clock-names = "core_clk",
+ "bus_aggr_clk",
+ "iface_clk",
+ "core_clk_unipro",
+ "ref_clk",
+ "tx_lane0_sync_clk",
+ "rx_lane0_sync_clk";
+ clocks = <&gcc GCC_UFS_PHY_AXI_CLK>,
+ <&gcc GCC_AGGRE_UFS_PHY_AXI_CLK>,
+ <&gcc GCC_UFS_PHY_AHB_CLK>,
+ <&gcc GCC_UFS_PHY_UNIPRO_CORE_CLK>,
+ <&rpmhcc RPMH_CXO_CLK>,
+ <&gcc GCC_UFS_PHY_TX_SYMBOL_0_CLK>,
+ <&gcc GCC_UFS_PHY_RX_SYMBOL_0_CLK>;
+ freq-table-hz = <50000000 200000000>,
+ <0 0>,
+ <0 0>,
+ <37500000 150000000>,
+ <0 0>,
+ <0 0>,
+ <0 0>;
+
+ 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";
+
+ qcom,ice = <&ice>;
+
+ status = "disabled";
+ };
+
+ ufs_mem_phy: phy@1d87000 {
+ compatible = "qcom,sc7180-qmp-ufs-phy",
+ "qcom,sm7150-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";
+ power-domains = <&gcc UFS_PHY_GDSC>;
+ resets = <&ufs_mem_hc 0>;
+ reset-names = "ufsphy";
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+
+ ice: crypto@1d90000 {
+ compatible = "qcom,sc7180-inline-crypto-engine",
+ "qcom,inline-crypto-engine";
+ reg = <0 0x01d90000 0 0x8000>;
+ clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>;
+ };
+
ipa: ipa@1e40000 {
compatible = "qcom,sc7180-ipa";
@@ -2964,12 +3034,16 @@
<&gcc GCC_USB30_PRIM_MASTER_CLK>;
assigned-clock-rates = <19200000>, <150000000>;
- interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
- <&pdc 6 IRQ_TYPE_LEVEL_HIGH>,
+ interrupts-extended = <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <&pdc 9 IRQ_TYPE_EDGE_BOTH>,
<&pdc 8 IRQ_TYPE_EDGE_BOTH>,
- <&pdc 9 IRQ_TYPE_EDGE_BOTH>;
- interrupt-names = "hs_phy_irq", "ss_phy_irq",
- "dm_hs_phy_irq", "dp_hs_phy_irq";
+ <&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>;
diff --git a/arch/arm64/boot/dts/qcom/sc7280-chrome-common.dtsi b/arch/arm64/boot/dts/qcom/sc7280-chrome-common.dtsi
index c4d00a81da39..cecb3e89f7f7 100644
--- a/arch/arm64/boot/dts/qcom/sc7280-chrome-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7280-chrome-common.dtsi
@@ -18,6 +18,7 @@
*/
/delete-node/ &cdsp_mem;
+/delete-node/ &domain_idle_states;
/delete-node/ &gpu_zap_mem;
/delete-node/ &gpu_zap_shader;
/delete-node/ &hyp_mem;
@@ -26,6 +27,18 @@
/delete-node/ &sec_apps_mem;
/ {
+ cpus {
+ domain_idle_states: domain-idle-states {
+ CLUSTER_SLEEP_0: cluster-sleep-0 {
+ compatible = "domain-idle-state";
+ arm,psci-suspend-param = <0x40003444>;
+ entry-latency-us = <2752>;
+ exit-latency-us = <6562>;
+ min-residency-us = <9926>;
+ };
+ };
+ };
+
reserved-memory {
camera_mem: memory@8ad00000 {
reg = <0x0 0x8ad00000 0x0 0x500000>;
@@ -39,6 +52,10 @@
};
};
+&CLUSTER_PD {
+ domain-idle-states = <&CLUSTER_SLEEP_0>;
+};
+
&lpass_aon {
status = "okay";
};
@@ -119,6 +136,17 @@
dma-coherent;
};
+&venus {
+ iommus = <&apps_smmu 0x2180 0x20>,
+ <&apps_smmu 0x2184 0x20>;
+
+ status = "okay";
+
+ video-firmware {
+ iommus = <&apps_smmu 0x21a2 0x0>;
+ };
+};
+
&watchdog {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi b/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi
index 9ea6636125ad..2ba4ea60cb14 100644
--- a/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi
@@ -548,6 +548,7 @@ ap_ec_spi: &spi10 {
pinctrl-names = "default";
pinctrl-0 = <&ap_ec_int_l>;
spi-max-frequency = <3000000>;
+ wakeup-source;
cros_ec_pwm: pwm {
compatible = "google,cros-ec-pwm";
diff --git a/arch/arm64/boot/dts/qcom/sc7280-idp-ec-h1.dtsi b/arch/arm64/boot/dts/qcom/sc7280-idp-ec-h1.dtsi
index ebae545c587c..fbfac7534d3c 100644
--- a/arch/arm64/boot/dts/qcom/sc7280-idp-ec-h1.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7280-idp-ec-h1.dtsi
@@ -19,6 +19,7 @@ ap_ec_spi: &spi10 {
pinctrl-names = "default";
pinctrl-0 = <&ap_ec_int_l>;
spi-max-frequency = <3000000>;
+ wakeup-source;
cros_ec_pwm: pwm {
compatible = "google,cros-ec-pwm";
diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi
index 83b5b76ba179..7e7f0f0fb41b 100644
--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
@@ -202,6 +202,8 @@
power-domain-names = "psci";
next-level-cache = <&L2_0>;
operating-points-v2 = <&cpu0_opp_table>;
+ capacity-dmips-mhz = <1024>;
+ dynamic-power-coefficient = <100>;
interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
<&epss_l3 MASTER_EPSS_L3_APPS &epss_l3 SLAVE_EPSS_L3_SHARED>;
qcom,freq-domain = <&cpufreq_hw 0>;
@@ -229,6 +231,8 @@
power-domain-names = "psci";
next-level-cache = <&L2_100>;
operating-points-v2 = <&cpu0_opp_table>;
+ capacity-dmips-mhz = <1024>;
+ dynamic-power-coefficient = <100>;
interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
<&epss_l3 MASTER_EPSS_L3_APPS &epss_l3 SLAVE_EPSS_L3_SHARED>;
qcom,freq-domain = <&cpufreq_hw 0>;
@@ -251,6 +255,8 @@
power-domain-names = "psci";
next-level-cache = <&L2_200>;
operating-points-v2 = <&cpu0_opp_table>;
+ capacity-dmips-mhz = <1024>;
+ dynamic-power-coefficient = <100>;
interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
<&epss_l3 MASTER_EPSS_L3_APPS &epss_l3 SLAVE_EPSS_L3_SHARED>;
qcom,freq-domain = <&cpufreq_hw 0>;
@@ -273,6 +279,8 @@
power-domain-names = "psci";
next-level-cache = <&L2_300>;
operating-points-v2 = <&cpu0_opp_table>;
+ capacity-dmips-mhz = <1024>;
+ dynamic-power-coefficient = <100>;
interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
<&epss_l3 MASTER_EPSS_L3_APPS &epss_l3 SLAVE_EPSS_L3_SHARED>;
qcom,freq-domain = <&cpufreq_hw 0>;
@@ -295,6 +303,8 @@
power-domain-names = "psci";
next-level-cache = <&L2_400>;
operating-points-v2 = <&cpu4_opp_table>;
+ capacity-dmips-mhz = <1946>;
+ dynamic-power-coefficient = <520>;
interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
<&epss_l3 MASTER_EPSS_L3_APPS &epss_l3 SLAVE_EPSS_L3_SHARED>;
qcom,freq-domain = <&cpufreq_hw 1>;
@@ -317,6 +327,8 @@
power-domain-names = "psci";
next-level-cache = <&L2_500>;
operating-points-v2 = <&cpu4_opp_table>;
+ capacity-dmips-mhz = <1946>;
+ dynamic-power-coefficient = <520>;
interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
<&epss_l3 MASTER_EPSS_L3_APPS &epss_l3 SLAVE_EPSS_L3_SHARED>;
qcom,freq-domain = <&cpufreq_hw 1>;
@@ -339,6 +351,8 @@
power-domain-names = "psci";
next-level-cache = <&L2_600>;
operating-points-v2 = <&cpu4_opp_table>;
+ capacity-dmips-mhz = <1946>;
+ dynamic-power-coefficient = <520>;
interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
<&epss_l3 MASTER_EPSS_L3_APPS &epss_l3 SLAVE_EPSS_L3_SHARED>;
qcom,freq-domain = <&cpufreq_hw 1>;
@@ -361,6 +375,8 @@
power-domain-names = "psci";
next-level-cache = <&L2_700>;
operating-points-v2 = <&cpu7_opp_table>;
+ capacity-dmips-mhz = <1985>;
+ dynamic-power-coefficient = <552>;
interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
<&epss_l3 MASTER_EPSS_L3_APPS &epss_l3 SLAVE_EPSS_L3_SHARED>;
qcom,freq-domain = <&cpufreq_hw 2>;
@@ -453,15 +469,29 @@
};
};
- domain-idle-states {
- CLUSTER_SLEEP_0: cluster-sleep-0 {
+ domain_idle_states: domain-idle-states {
+ CLUSTER_SLEEP_APSS_OFF: cluster-sleep-0 {
compatible = "domain-idle-state";
- idle-state-name = "cluster-power-down";
- arm,psci-suspend-param = <0x40003444>;
+ arm,psci-suspend-param = <0x41000044>;
+ entry-latency-us = <2752>;
+ exit-latency-us = <3048>;
+ min-residency-us = <6118>;
+ };
+
+ CLUSTER_SLEEP_CX_RET: cluster-sleep-1 {
+ compatible = "domain-idle-state";
+ arm,psci-suspend-param = <0x41001344>;
entry-latency-us = <3263>;
+ exit-latency-us = <4562>;
+ min-residency-us = <8467>;
+ };
+
+ CLUSTER_SLEEP_LLCC_OFF: cluster-sleep-2 {
+ compatible = "domain-idle-state";
+ arm,psci-suspend-param = <0x4100b344>;
+ entry-latency-us = <3638>;
exit-latency-us = <6562>;
- min-residency-us = <9926>;
- local-timer-stop;
+ min-residency-us = <9826>;
};
};
};
@@ -872,7 +902,7 @@
CLUSTER_PD: power-domain-cluster {
#power-domain-cells = <0>;
- domain-idle-states = <&CLUSTER_SLEEP_0>;
+ domain-idle-states = <&CLUSTER_SLEEP_APSS_OFF &CLUSTER_SLEEP_CX_RET &CLUSTER_SLEEP_LLCC_OFF>;
};
};
@@ -966,7 +996,7 @@
#address-cells = <1>;
#size-cells = <1>;
- gpu_speed_bin: gpu_speed_bin@1e9 {
+ gpu_speed_bin: gpu-speed-bin@1e9 {
reg = <0x1e9 0x2>;
bits = <5 8>;
};
@@ -2178,8 +2208,16 @@
ranges = <0x01000000 0x0 0x00000000 0x0 0x40200000 0x0 0x100000>,
<0x02000000 0x0 0x40300000 0x0 0x40300000 0x0 0x1fd00000>;
- interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "msi";
+ interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi0", "msi1", "msi2", "msi3",
+ "msi4", "msi5", "msi6", "msi7";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0x7>;
interrupt-map = <0 0 0 1 &intc 0 0 0 434 IRQ_TYPE_LEVEL_HIGH>,
@@ -2345,6 +2383,8 @@
<&apps_smmu 0x4e6 0x0011>;
qcom,ee = <0>;
qcom,controlled-remotely;
+ num-channels = <16>;
+ qcom,num-ees = <4>;
};
crypto: crypto@1dfa000 {
@@ -2648,6 +2688,31 @@
status = "disabled";
};
+ slimbam: dma-controller@3a84000 {
+ compatible = "qcom,bam-v1.7.0";
+ reg = <0 0x03a84000 0 0x20000>;
+ interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ qcom,controlled-remotely;
+ num-channels = <31>;
+ qcom,ee = <1>;
+ qcom,num-ees = <2>;
+ iommus = <&apps_smmu 0x1826 0x0>;
+ status = "disabled";
+ };
+
+ slim: slim-ngd@3ac0000 {
+ compatible = "qcom,slim-ngd-v1.5.0";
+ reg = <0 0x03ac0000 0 0x2c000>;
+ interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&slimbam 3>, <&slimbam 4>;
+ dma-names = "rx", "tx";
+ iommus = <&apps_smmu 0x1826 0x0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
lpass_hm: clock-controller@3c00000 {
compatible = "qcom,sc7280-lpasshm";
reg = <0 0x03c00000 0 0x28>;
@@ -3582,10 +3647,12 @@
<&gcc GCC_USB30_SEC_MASTER_CLK>;
assigned-clock-rates = <19200000>, <200000000>;
- interrupts-extended = <&intc GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ interrupts-extended = <&intc GIC_SPI 241 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
<&pdc 12 IRQ_TYPE_EDGE_BOTH>,
<&pdc 13 IRQ_TYPE_EDGE_BOTH>;
- interrupt-names = "hs_phy_irq",
+ interrupt-names = "pwr_event",
+ "hs_phy_irq",
"dp_hs_phy_irq",
"dm_hs_phy_irq";
@@ -4035,11 +4102,13 @@
<&gcc GCC_USB30_PRIM_MASTER_CLK>;
assigned-clock-rates = <19200000>, <200000000>;
- interrupts-extended = <&intc GIC_SPI 131 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_BOTH>,
<&pdc 15 IRQ_TYPE_EDGE_BOTH>,
<&pdc 17 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "hs_phy_irq",
+ interrupt-names = "pwr_event",
+ "hs_phy_irq",
"dp_hs_phy_irq",
"dm_hs_phy_irq",
"ss_phy_irq";
@@ -4065,6 +4134,25 @@
phys = <&usb_1_hsphy>, <&usb_1_qmpphy QMP_USB43DP_USB3_PHY>;
phy-names = "usb2-phy", "usb3-phy";
maximum-speed = "super-speed";
+
+ 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 {
+ };
+ };
+ };
};
};
@@ -4091,10 +4179,11 @@
<&mmss_noc MASTER_VIDEO_P0 0 &mc_virt SLAVE_EBI1 0>;
interconnect-names = "cpu-cfg", "video-mem";
- iommus = <&apps_smmu 0x2180 0x20>,
- <&apps_smmu 0x2184 0x20>;
+ iommus = <&apps_smmu 0x2180 0x20>;
memory-region = <&video_mem>;
+ status = "disabled";
+
video-decoder {
compatible = "venus-decoder";
};
@@ -4103,10 +4192,6 @@
compatible = "venus-encoder";
};
- video-firmware {
- iommus = <&apps_smmu 0x21a2 0x0>;
- };
-
venus_opp_table: opp-table {
compatible = "operating-points-v2";
diff --git a/arch/arm64/boot/dts/qcom/sc8180x.dtsi b/arch/arm64/boot/dts/qcom/sc8180x.dtsi
index 0430d99091e3..32afc78d5b76 100644
--- a/arch/arm64/boot/dts/qcom/sc8180x.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc8180x.dtsi
@@ -290,7 +290,7 @@
BIG_CPU_SLEEP_0: cpu-sleep-1-0 {
compatible = "arm,idle-state";
arm,psci-suspend-param = <0x40000004>;
- entry-latency-us = <241>;
+ entry-latency-us = <2411>;
exit-latency-us = <1461>;
min-residency-us = <4488>;
local-timer-stop;
@@ -298,7 +298,15 @@
};
domain-idle-states {
- CLUSTER_SLEEP_0: cluster-sleep-0 {
+ CLUSTER_SLEEP_APSS_OFF: cluster-sleep-0 {
+ compatible = "domain-idle-state";
+ arm,psci-suspend-param = <0x41000044>;
+ entry-latency-us = <3300>;
+ exit-latency-us = <3300>;
+ min-residency-us = <6000>;
+ };
+
+ CLUSTER_SLEEP_AOSS_SLEEP: cluster-sleep-1 {
compatible = "domain-idle-state";
arm,psci-suspend-param = <0x4100a344>;
entry-latency-us = <3263>;
@@ -582,7 +590,7 @@
CLUSTER_PD: power-domain-cpu-cluster0 {
#power-domain-cells = <0>;
- domain-idle-states = <&CLUSTER_SLEEP_0>;
+ domain-idle-states = <&CLUSTER_SLEEP_APSS_OFF &CLUSTER_SLEEP_AOSS_SLEEP>;
};
};
@@ -782,6 +790,7 @@
clock-names = "bi_tcxo",
"bi_tcxo_ao",
"sleep_clk";
+ power-domains = <&rpmhpd SC8180X_CX>;
};
qupv3_id_0: geniqup@8c0000 {
@@ -1708,8 +1717,22 @@
ranges = <0x01000000 0x0 0x60200000 0x0 0x60200000 0x0 0x100000>,
<0x02000000 0x0 0x60300000 0x0 0x60300000 0x0 0x3d00000>;
- interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "msi";
+ interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi0",
+ "msi1",
+ "msi2",
+ "msi3",
+ "msi4",
+ "msi5",
+ "msi6",
+ "msi7";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0x7>;
interrupt-map = <0 0 0 1 &intc 0 149 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
@@ -1805,8 +1828,22 @@
ranges = <0x01000000 0x0 0x40200000 0x0 0x40200000 0x0 0x100000>,
<0x02000000 0x0 0x40300000 0x0 0x40300000 0x0 0x1fd00000>;
- interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "msi";
+ interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi0",
+ "msi1",
+ "msi2",
+ "msi3",
+ "msi4",
+ "msi5",
+ "msi6",
+ "msi7";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0x7>;
interrupt-map = <0 0 0 1 &intc 0 434 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
@@ -1903,8 +1940,22 @@
ranges = <0x01000000 0x0 0x68200000 0x0 0x68200000 0x0 0x100000>,
<0x02000000 0x0 0x68300000 0x0 0x68300000 0x0 0x3d00000>;
- interrupts = <GIC_SPI 755 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "msi";
+ interrupts = <GIC_SPI 756 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 755 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 754 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 753 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 752 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 751 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 750 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 749 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi0",
+ "msi1",
+ "msi2",
+ "msi3",
+ "msi4",
+ "msi5",
+ "msi6",
+ "msi7";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0x7>;
interrupt-map = <0 0 0 1 &intc 0 747 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
@@ -2001,8 +2052,22 @@
ranges = <0x01000000 0x0 0x70200000 0x0 0x70200000 0x0 0x100000>,
<0x02000000 0x0 0x70300000 0x0 0x70300000 0x0 0x3d00000>;
- interrupts = <GIC_SPI 671 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "msi";
+ interrupts = <GIC_SPI 672 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 671 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 670 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 669 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 668 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 667 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 666 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 665 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi0",
+ "msi1",
+ "msi2",
+ "msi3",
+ "msi4",
+ "msi5",
+ "msi6",
+ "msi7";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0x7>;
interrupt-map = <0 0 0 1 &intc 0 663 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
@@ -2131,9 +2196,11 @@
reg = <0 0x01d87000 0 0x1000>;
clocks = <&rpmhcc RPMH_CXO_CLK>,
- <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
+ <&gcc GCC_UFS_PHY_PHY_AUX_CLK>,
+ <&gcc GCC_UFS_MEM_CLKREF_EN>;
clock-names = "ref",
- "ref_aux";
+ "ref_aux",
+ "qref";
resets = <&ufs_mem_hc 0>;
reset-names = "ufsphy";
@@ -2173,6 +2240,8 @@
interconnect-names = "gfx-mem";
qcom,gmu = <&gmu>;
+ #cooling-cells = <2>;
+
status = "disabled";
gpu_opp_table: opp-table {
@@ -2692,9 +2761,15 @@
interrupt-controller;
#interrupt-cells = <1>;
- interconnects = <&mmss_noc MASTER_MDP_PORT0 0 &mc_virt SLAVE_EBI_CH0 0>,
- <&mmss_noc MASTER_MDP_PORT1 0 &mc_virt SLAVE_EBI_CH0 0>;
- interconnect-names = "mdp0-mem", "mdp1-mem";
+ interconnects = <&mmss_noc MASTER_MDP_PORT0 QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI_CH0 QCOM_ICC_TAG_ALWAYS>,
+ <&mmss_noc MASTER_MDP_PORT1 QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI_CH0 QCOM_ICC_TAG_ALWAYS>,
+ <&gem_noc MASTER_AMPSS_M0 QCOM_ICC_TAG_ALWAYS
+ &config_noc SLAVE_DISPLAY_CFG QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "mdp0-mem",
+ "mdp1-mem",
+ "cpu-cfg";
iommus = <&apps_smmu 0x800 0x420>;
@@ -2723,10 +2798,8 @@
"rot",
"lut";
- assigned-clocks = <&dispcc DISP_CC_MDSS_MDP_CLK>,
- <&dispcc DISP_CC_MDSS_VSYNC_CLK>;
- assigned-clock-rates = <460000000>,
- <19200000>;
+ assigned-clocks = <&dispcc DISP_CC_MDSS_VSYNC_CLK>;
+ assigned-clock-rates = <19200000>;
operating-points-v2 = <&mdp_opp_table>;
power-domains = <&rpmhpd SC8180X_MMCX>;
@@ -3184,7 +3257,7 @@
<&dispcc DISP_CC_MDSS_AHB_CLK>;
clock-names = "aux", "cfg_ahb";
- power-domains = <&dispcc MDSS_GDSC>;
+ power-domains = <&rpmhpd SC8180X_MX>;
#clock-cells = <1>;
#phy-cells = <0>;
@@ -3210,6 +3283,7 @@
"edp_phy_pll_link_clk",
"edp_phy_pll_vco_div_clk";
power-domains = <&rpmhpd SC8180X_MMCX>;
+ required-opps = <&rpmhpd_opp_low_svs>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
@@ -3248,7 +3322,7 @@
aoss_qmp: power-controller@c300000 {
compatible = "qcom,sc8180x-aoss-qmp", "qcom,aoss-qmp";
- reg = <0x0 0x0c300000 0x0 0x100000>;
+ reg = <0x0 0x0c300000 0x0 0x400>;
interrupts = <GIC_SPI 389 IRQ_TYPE_EDGE_RISING>;
mboxes = <&apss_shared 0>;
@@ -3256,6 +3330,11 @@
#power-domain-cells = <1>;
};
+ sram@c3f0000 {
+ compatible = "qcom,rpmh-stats";
+ reg = <0x0 0x0c3f0000 0x0 0x400>;
+ };
+
spmi_bus: spmi@c440000 {
compatible = "qcom,spmi-pmic-arb";
reg = <0x0 0x0c440000 0x0 0x0001100>,
@@ -3880,8 +3959,15 @@
thermal-sensors = <&tsens0 15>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu_top_alert0>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
- trip-point0 {
+ gpu_top_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <2000>;
type = "hot";
@@ -4030,8 +4116,15 @@
thermal-sensors = <&tsens1 11>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu_bottom_alert0>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
- trip-point0 {
+ gpu_bottom_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <2000>;
type = "hot";
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 eb657e544961..15ae94c1602d 100644
--- a/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts
+++ b/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts
@@ -6,10 +6,8 @@
/dts-v1/;
-#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/iio/qcom,spmi-adc7-pm8350.h>
-#include <dt-bindings/iio/qcom,spmi-adc7-pmk8350.h>
-#include <dt-bindings/iio/qcom,spmi-adc7-pmr735a.h>
+#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/gpio-keys.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/leds/common.h>
@@ -855,27 +853,6 @@
};
&pmk8280_vadc {
- status = "okay";
-
- channel@3 {
- reg = <PMK8350_ADC7_DIE_TEMP>;
- qcom,pre-scaling = <1 1>;
- label = "pmk8350_die_temp";
- };
-
- channel@44 {
- reg = <PMK8350_ADC7_AMUX_THM1_100K_PU>;
- qcom,hw-settle-time = <200>;
- qcom,ratiometric;
- label = "pmk8350_xo_therm";
- };
-
- channel@103 {
- reg = <PM8350_ADC7_DIE_TEMP(1)>;
- qcom,pre-scaling = <1 1>;
- label = "pmc8280_1_die_temp";
- };
-
channel@144 {
reg = <PM8350_ADC7_AMUX_THM1_100K_PU(1)>;
qcom,hw-settle-time = <200>;
@@ -904,12 +881,6 @@
label = "sys_therm4";
};
- channel@303 {
- reg = <PM8350_ADC7_DIE_TEMP(3)>;
- qcom,pre-scaling = <1 1>;
- label = "pmc8280_2_die_temp";
- };
-
channel@344 {
reg = <PM8350_ADC7_AMUX_THM1_100K_PU(3)>;
qcom,hw-settle-time = <200>;
@@ -937,12 +908,6 @@
qcom,ratiometric;
label = "sys_therm8";
};
-
- channel@403 {
- reg = <PMR735A_ADC7_DIE_TEMP>;
- qcom,pre-scaling = <1 1>;
- label = "pmr735a_die_temp";
- };
};
&qup0 {
@@ -1204,7 +1169,7 @@
};
&vamacro {
- pinctrl-0 = <&dmic01_default>, <&dmic02_default>;
+ pinctrl-0 = <&dmic01_default>, <&dmic23_default>;
pinctrl-names = "default";
vdd-micb-supply = <&vreg_s10b>;
diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-pmics.dtsi b/arch/arm64/boot/dts/qcom/sc8280xp-pmics.dtsi
index 80ee12ded4f4..945de77911de 100644
--- a/arch/arm64/boot/dts/qcom/sc8280xp-pmics.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc8280xp-pmics.dtsi
@@ -3,6 +3,9 @@
* Copyright (c) 2022, Linaro Limited
*/
+#include <dt-bindings/iio/qcom,spmi-adc7-pm8350.h>
+#include <dt-bindings/iio/qcom,spmi-adc7-pmk8350.h>
+#include <dt-bindings/iio/qcom,spmi-adc7-pmr735a.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/spmi/spmi.h>
@@ -84,7 +87,37 @@
#address-cells = <1>;
#size-cells = <0>;
#io-channel-cells = <1>;
- status = "disabled";
+
+ channel@3 {
+ reg = <PMK8350_ADC7_DIE_TEMP>;
+ qcom,pre-scaling = <1 1>;
+ label = "pmk8350_die_temp";
+ };
+
+ channel@44 {
+ reg = <PMK8350_ADC7_AMUX_THM1_100K_PU>;
+ qcom,hw-settle-time = <200>;
+ qcom,ratiometric;
+ label = "pmk8350_xo_therm";
+ };
+
+ channel@103 {
+ reg = <PM8350_ADC7_DIE_TEMP(1)>;
+ qcom,pre-scaling = <1 1>;
+ label = "pmc8280_1_die_temp";
+ };
+
+ channel@303 {
+ reg = <PM8350_ADC7_DIE_TEMP(3)>;
+ qcom,pre-scaling = <1 1>;
+ label = "pmc8280_2_die_temp";
+ };
+
+ channel@403 {
+ reg = <PMR735A_ADC7_DIE_TEMP>;
+ qcom,pre-scaling = <1 1>;
+ label = "pmr735a_die_temp";
+ };
};
pmk8280_adc_tm: adc-tm@3400 {
@@ -126,6 +159,8 @@
compatible = "qcom,spmi-temp-alarm";
reg = <0xa00>;
interrupts-extended = <&spmi_bus 0x1 0xa 0x0 IRQ_TYPE_EDGE_BOTH>;
+ io-channels = <&pmk8280_vadc PM8350_ADC7_DIE_TEMP(1)>;
+ io-channel-names = "thermal";
#thermal-sensor-cells = <0>;
};
@@ -178,6 +213,8 @@
compatible = "qcom,spmi-temp-alarm";
reg = <0xa00>;
interrupts-extended = <&spmi_bus 0x2 0xa 0x0 IRQ_TYPE_EDGE_BOTH>;
+ io-channels = <&pmk8280_vadc PM8350_ADC7_DIE_TEMP(3)>;
+ io-channel-names = "thermal";
#thermal-sensor-cells = <0>;
};
diff --git a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
index febf28356ff8..a5b194813079 100644
--- a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
@@ -2257,9 +2257,12 @@
compatible = "qcom,sc8280xp-qmp-ufs-phy";
reg = <0 0x01d87000 0 0x1000>;
- clocks = <&gcc GCC_UFS_CARD_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_CARD_CLKREF_CLK>;
+ clock-names = "ref",
+ "ref_aux",
+ "qref";
power-domains = <&gcc UFS_PHY_GDSC>;
@@ -2319,9 +2322,12 @@
compatible = "qcom,sc8280xp-qmp-ufs-phy";
reg = <0 0x01da7000 0 0x1000>;
- clocks = <&gcc GCC_UFS_1_CARD_CLKREF_CLK>,
- <&gcc GCC_UFS_CARD_PHY_AUX_CLK>;
- clock-names = "ref", "ref_aux";
+ clocks = <&rpmhcc RPMH_CXO_CLK>,
+ <&gcc GCC_UFS_CARD_PHY_AUX_CLK>,
+ <&gcc GCC_UFS_1_CARD_CLKREF_CLK>;
+ clock-names = "ref",
+ "ref_aux",
+ "qref";
power-domains = <&gcc UFS_CARD_GDSC>;
@@ -2978,7 +2984,7 @@
};
};
- dmic02_default: dmic02-default-state {
+ dmic23_default: dmic23-default-state {
clk-pins {
pins = "gpio8";
function = "dmic2_clk";
@@ -2994,7 +3000,7 @@
};
};
- dmic02_sleep: dmic02-sleep-state {
+ dmic23_sleep: dmic23-sleep-state {
clk-pins {
pins = "gpio8";
function = "dmic2_clk";
@@ -3451,6 +3457,404 @@
};
};
+ cci0: cci@ac4a000 {
+ compatible = "qcom,sc8280xp-cci", "qcom,msm8996-cci";
+ reg = <0 0x0ac4a000 0 0x1000>;
+
+ interrupts = <GIC_SPI 460 IRQ_TYPE_EDGE_RISING>;
+
+ clocks = <&camcc CAMCC_CAMNOC_AXI_CLK>,
+ <&camcc CAMCC_SLOW_AHB_CLK_SRC>,
+ <&camcc CAMCC_CPAS_AHB_CLK>,
+ <&camcc CAMCC_CCI_0_CLK>;
+ clock-names = "camnoc_axi",
+ "slow_ahb_src",
+ "cpas_ahb",
+ "cci";
+
+ power-domains = <&camcc TITAN_TOP_GDSC>;
+
+ pinctrl-0 = <&cci0_default>;
+ pinctrl-1 = <&cci0_sleep>;
+ pinctrl-names = "default", "sleep";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+
+ cci0_i2c0: i2c-bus@0 {
+ reg = <0>;
+ clock-frequency = <1000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ cci0_i2c1: i2c-bus@1 {
+ reg = <1>;
+ clock-frequency = <1000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ cci1: cci@ac4b000 {
+ compatible = "qcom,sc8280xp-cci", "qcom,msm8996-cci";
+ reg = <0 0x0ac4b000 0 0x1000>;
+
+ interrupts = <GIC_SPI 271 IRQ_TYPE_EDGE_RISING>;
+
+ clocks = <&camcc CAMCC_CAMNOC_AXI_CLK>,
+ <&camcc CAMCC_SLOW_AHB_CLK_SRC>,
+ <&camcc CAMCC_CPAS_AHB_CLK>,
+ <&camcc CAMCC_CCI_1_CLK>;
+ clock-names = "camnoc_axi",
+ "slow_ahb_src",
+ "cpas_ahb",
+ "cci";
+
+ power-domains = <&camcc TITAN_TOP_GDSC>;
+
+ pinctrl-0 = <&cci1_default>;
+ pinctrl-1 = <&cci1_sleep>;
+ pinctrl-names = "default", "sleep";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+
+ cci1_i2c0: i2c-bus@0 {
+ reg = <0>;
+ clock-frequency = <1000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ cci1_i2c1: i2c-bus@1 {
+ reg = <1>;
+ clock-frequency = <1000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ cci2: cci@ac4c000 {
+ compatible = "qcom,sc8280xp-cci", "qcom,msm8996-cci";
+ reg = <0 0x0ac4c000 0 0x1000>;
+
+ interrupts = <GIC_SPI 651 IRQ_TYPE_EDGE_RISING>;
+
+ clocks = <&camcc CAMCC_CAMNOC_AXI_CLK>,
+ <&camcc CAMCC_SLOW_AHB_CLK_SRC>,
+ <&camcc CAMCC_CPAS_AHB_CLK>,
+ <&camcc CAMCC_CCI_2_CLK>;
+ clock-names = "camnoc_axi",
+ "slow_ahb_src",
+ "cpas_ahb",
+ "cci";
+ power-domains = <&camcc TITAN_TOP_GDSC>;
+
+ pinctrl-0 = <&cci2_default>;
+ pinctrl-1 = <&cci2_sleep>;
+ pinctrl-names = "default", "sleep";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+
+ cci2_i2c0: i2c-bus@0 {
+ reg = <0>;
+ clock-frequency = <1000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ cci2_i2c1: i2c-bus@1 {
+ reg = <1>;
+ clock-frequency = <1000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ cci3: cci@ac4d000 {
+ compatible = "qcom,sc8280xp-cci", "qcom,msm8996-cci";
+ reg = <0 0x0ac4d000 0 0x1000>;
+
+ interrupts = <GIC_SPI 650 IRQ_TYPE_EDGE_RISING>;
+
+ clocks = <&camcc CAMCC_CAMNOC_AXI_CLK>,
+ <&camcc CAMCC_SLOW_AHB_CLK_SRC>,
+ <&camcc CAMCC_CPAS_AHB_CLK>,
+ <&camcc CAMCC_CCI_3_CLK>;
+ clock-names = "camnoc_axi",
+ "slow_ahb_src",
+ "cpas_ahb",
+ "cci";
+
+ power-domains = <&camcc TITAN_TOP_GDSC>;
+
+ pinctrl-0 = <&cci3_default>;
+ pinctrl-1 = <&cci3_sleep>;
+ pinctrl-names = "default", "sleep";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ status = "disabled";
+
+ cci3_i2c0: i2c-bus@0 {
+ reg = <0>;
+ clock-frequency = <1000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ cci3_i2c1: i2c-bus@1 {
+ reg = <1>;
+ clock-frequency = <1000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+
+ camss: camss@ac5a000 {
+ compatible = "qcom,sc8280xp-camss";
+
+ reg = <0 0x0ac5a000 0 0x2000>,
+ <0 0x0ac5c000 0 0x2000>,
+ <0 0x0ac65000 0 0x2000>,
+ <0 0x0ac67000 0 0x2000>,
+ <0 0x0acaf000 0 0x4000>,
+ <0 0x0acb3000 0 0x1000>,
+ <0 0x0acb6000 0 0x4000>,
+ <0 0x0acba000 0 0x1000>,
+ <0 0x0acbd000 0 0x4000>,
+ <0 0x0acc1000 0 0x1000>,
+ <0 0x0acc4000 0 0x4000>,
+ <0 0x0acc8000 0 0x1000>,
+ <0 0x0accb000 0 0x4000>,
+ <0 0x0accf000 0 0x1000>,
+ <0 0x0acd2000 0 0x4000>,
+ <0 0x0acd6000 0 0x1000>,
+ <0 0x0acd9000 0 0x4000>,
+ <0 0x0acdd000 0 0x1000>,
+ <0 0x0ace0000 0 0x4000>,
+ <0 0x0ace4000 0 0x1000>;
+ reg-names = "csiphy2",
+ "csiphy3",
+ "csiphy0",
+ "csiphy1",
+ "vfe0",
+ "csid0",
+ "vfe1",
+ "csid1",
+ "vfe2",
+ "csid2",
+ "vfe_lite0",
+ "csid0_lite",
+ "vfe_lite1",
+ "csid1_lite",
+ "vfe_lite2",
+ "csid2_lite",
+ "vfe_lite3",
+ "csid3_lite",
+ "vfe3",
+ "csid3";
+
+ interrupts = <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 448 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 464 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 465 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 477 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 478 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 479 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 640 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 641 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 758 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 759 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 760 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 761 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 762 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 764 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "csid1_lite",
+ "vfe_lite1",
+ "csiphy3",
+ "csid0",
+ "vfe0",
+ "csid1",
+ "vfe1",
+ "csid0_lite",
+ "vfe_lite0",
+ "csiphy0",
+ "csiphy1",
+ "csiphy2",
+ "csid2",
+ "vfe2",
+ "csid3_lite",
+ "csid2_lite",
+ "vfe_lite3",
+ "vfe_lite2",
+ "csid3",
+ "vfe3";
+
+ power-domains = <&camcc IFE_0_GDSC>,
+ <&camcc IFE_1_GDSC>,
+ <&camcc IFE_2_GDSC>,
+ <&camcc IFE_3_GDSC>,
+ <&camcc TITAN_TOP_GDSC>;
+ power-domain-names = "ife0",
+ "ife1",
+ "ife2",
+ "ife3",
+ "top";
+
+ clocks = <&camcc CAMCC_CAMNOC_AXI_CLK>,
+ <&camcc CAMCC_CPAS_AHB_CLK>,
+ <&camcc CAMCC_CSIPHY0_CLK>,
+ <&camcc CAMCC_CSI0PHYTIMER_CLK>,
+ <&camcc CAMCC_CSIPHY1_CLK>,
+ <&camcc CAMCC_CSI1PHYTIMER_CLK>,
+ <&camcc CAMCC_CSIPHY2_CLK>,
+ <&camcc CAMCC_CSI2PHYTIMER_CLK>,
+ <&camcc CAMCC_CSIPHY3_CLK>,
+ <&camcc CAMCC_CSI3PHYTIMER_CLK>,
+ <&camcc CAMCC_IFE_0_AXI_CLK>,
+ <&camcc CAMCC_IFE_0_CLK>,
+ <&camcc CAMCC_IFE_0_CPHY_RX_CLK>,
+ <&camcc CAMCC_IFE_0_CSID_CLK>,
+ <&camcc CAMCC_IFE_1_AXI_CLK>,
+ <&camcc CAMCC_IFE_1_CLK>,
+ <&camcc CAMCC_IFE_1_CPHY_RX_CLK>,
+ <&camcc CAMCC_IFE_1_CSID_CLK>,
+ <&camcc CAMCC_IFE_2_AXI_CLK>,
+ <&camcc CAMCC_IFE_2_CLK>,
+ <&camcc CAMCC_IFE_2_CPHY_RX_CLK>,
+ <&camcc CAMCC_IFE_2_CSID_CLK>,
+ <&camcc CAMCC_IFE_3_AXI_CLK>,
+ <&camcc CAMCC_IFE_3_CLK>,
+ <&camcc CAMCC_IFE_3_CPHY_RX_CLK>,
+ <&camcc CAMCC_IFE_3_CSID_CLK>,
+ <&camcc CAMCC_IFE_LITE_0_CLK>,
+ <&camcc CAMCC_IFE_LITE_0_CPHY_RX_CLK>,
+ <&camcc CAMCC_IFE_LITE_0_CSID_CLK>,
+ <&camcc CAMCC_IFE_LITE_1_CLK>,
+ <&camcc CAMCC_IFE_LITE_1_CPHY_RX_CLK>,
+ <&camcc CAMCC_IFE_LITE_1_CSID_CLK>,
+ <&camcc CAMCC_IFE_LITE_2_CLK>,
+ <&camcc CAMCC_IFE_LITE_2_CPHY_RX_CLK>,
+ <&camcc CAMCC_IFE_LITE_2_CSID_CLK>,
+ <&camcc CAMCC_IFE_LITE_3_CLK>,
+ <&camcc CAMCC_IFE_LITE_3_CPHY_RX_CLK>,
+ <&camcc CAMCC_IFE_LITE_3_CSID_CLK>,
+ <&gcc GCC_CAMERA_HF_AXI_CLK>,
+ <&gcc GCC_CAMERA_SF_AXI_CLK>;
+ clock-names = "camnoc_axi",
+ "cpas_ahb",
+ "csiphy0",
+ "csiphy0_timer",
+ "csiphy1",
+ "csiphy1_timer",
+ "csiphy2",
+ "csiphy2_timer",
+ "csiphy3",
+ "csiphy3_timer",
+ "vfe0_axi",
+ "vfe0",
+ "vfe0_cphy_rx",
+ "vfe0_csid",
+ "vfe1_axi",
+ "vfe1",
+ "vfe1_cphy_rx",
+ "vfe1_csid",
+ "vfe2_axi",
+ "vfe2",
+ "vfe2_cphy_rx",
+ "vfe2_csid",
+ "vfe3_axi",
+ "vfe3",
+ "vfe3_cphy_rx",
+ "vfe3_csid",
+ "vfe_lite0",
+ "vfe_lite0_cphy_rx",
+ "vfe_lite0_csid",
+ "vfe_lite1",
+ "vfe_lite1_cphy_rx",
+ "vfe_lite1_csid",
+ "vfe_lite2",
+ "vfe_lite2_cphy_rx",
+ "vfe_lite2_csid",
+ "vfe_lite3",
+ "vfe_lite3_cphy_rx",
+ "vfe_lite3_csid",
+ "gcc_axi_hf",
+ "gcc_axi_sf";
+
+ iommus = <&apps_smmu 0x2000 0x4e0>,
+ <&apps_smmu 0x2020 0x4e0>,
+ <&apps_smmu 0x2040 0x4e0>,
+ <&apps_smmu 0x2060 0x4e0>,
+ <&apps_smmu 0x2080 0x4e0>,
+ <&apps_smmu 0x20e0 0x4e0>,
+ <&apps_smmu 0x20c0 0x4e0>,
+ <&apps_smmu 0x20a0 0x4e0>,
+ <&apps_smmu 0x2400 0x4e0>,
+ <&apps_smmu 0x2420 0x4e0>,
+ <&apps_smmu 0x2440 0x4e0>,
+ <&apps_smmu 0x2460 0x4e0>,
+ <&apps_smmu 0x2480 0x4e0>,
+ <&apps_smmu 0x24e0 0x4e0>,
+ <&apps_smmu 0x24c0 0x4e0>,
+ <&apps_smmu 0x24a0 0x4e0>;
+
+ interconnects = <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_CAMERA_CFG 0>,
+ <&mmss_noc MASTER_CAMNOC_HF 0 &mc_virt SLAVE_EBI1 0>,
+ <&mmss_noc MASTER_CAMNOC_SF 0 &mc_virt SLAVE_EBI1 0>,
+ <&mmss_noc MASTER_CAMNOC_ICP 0 &mc_virt SLAVE_EBI1 0>;
+ interconnect-names = "cam_ahb",
+ "cam_hf_mnoc",
+ "cam_sf_mnoc",
+ "cam_sf_icp_mnoc";
+
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ port@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ port@2 {
+ reg = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ port@3 {
+ reg = <3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+ };
+
camcc: clock-controller@ad00000 {
compatible = "qcom,sc8280xp-camcc";
reg = <0 0x0ad00000 0 0x20000>;
@@ -4011,6 +4415,28 @@
interrupt-controller;
};
+ tsens2: thermal-sensor@c251000 {
+ compatible = "qcom,sc8280xp-tsens", "qcom,tsens-v2";
+ reg = <0 0x0c251000 0 0x1ff>,
+ <0 0x0c224000 0 0x8>;
+ #qcom,sensors = <11>;
+ interrupts-extended = <&pdc 122 IRQ_TYPE_LEVEL_HIGH>,
+ <&pdc 124 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "uplow", "critical";
+ #thermal-sensor-cells = <1>;
+ };
+
+ tsens3: thermal-sensor@c252000 {
+ compatible = "qcom,sc8280xp-tsens", "qcom,tsens-v2";
+ reg = <0 0x0c252000 0 0x1ff>,
+ <0 0x0c225000 0 0x8>;
+ #qcom,sensors = <5>;
+ interrupts-extended = <&pdc 123 IRQ_TYPE_LEVEL_HIGH>,
+ <&pdc 125 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "uplow", "critical";
+ #thermal-sensor-cells = <1>;
+ };
+
tsens0: thermal-sensor@c263000 {
compatible = "qcom,sc8280xp-tsens", "qcom,tsens-v2";
reg = <0 0x0c263000 0 0x1ff>, /* TM */
@@ -4076,6 +4502,150 @@
#interrupt-cells = <2>;
gpio-ranges = <&tlmm 0 0 230>;
wakeup-parent = <&pdc>;
+
+ cci0_default: cci0-default-state {
+ cci0_i2c0_default: cci0-i2c0-default-pins {
+ /* cci_i2c_sda0, cci_i2c_scl0 */
+ pins = "gpio113", "gpio114";
+ function = "cci_i2c";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ cci0_i2c1_default: cci0-i2c1-default-pins {
+ /* cci_i2c_sda1, cci_i2c_scl1 */
+ pins = "gpio115", "gpio116";
+ function = "cci_i2c";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+
+ cci0_sleep: cci0-sleep-state {
+ cci0_i2c0_sleep: cci0-i2c0-sleep-pins {
+ /* cci_i2c_sda0, cci_i2c_scl0 */
+ pins = "gpio113", "gpio114";
+ function = "cci_i2c";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+
+ cci0_i2c1_sleep: cci0-i2c1-sleep-pins {
+ /* cci_i2c_sda1, cci_i2c_scl1 */
+ pins = "gpio115", "gpio116";
+ function = "cci_i2c";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+ };
+
+ cci1_default: cci1-default-state {
+ cci1_i2c0_default: cci1-i2c0-default-pins {
+ /* cci_i2c_sda2, cci_i2c_scl2 */
+ pins = "gpio10","gpio11";
+ function = "cci_i2c";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ cci1_i2c1_default: cci1-i2c1-default-pins {
+ /* cci_i2c_sda3, cci_i2c_scl3 */
+ pins = "gpio123","gpio124";
+ function = "cci_i2c";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+
+ cci1_sleep: cci1-sleep-state {
+ cci1_i2c0_sleep: cci1-i2c0-sleep-pins {
+ /* cci_i2c_sda2, cci_i2c_scl2 */
+ pins = "gpio10","gpio11";
+ function = "cci_i2c";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+
+ cci1_i2c1_sleep: cci1-i2c1-sleep-pins {
+ /* cci_i2c_sda3, cci_i2c_scl3 */
+ pins = "gpio123","gpio124";
+ function = "cci_i2c";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+ };
+
+ cci2_default: cci2-default-state {
+ cci2_i2c0_default: cci2-i2c0-default-pins {
+ /* cci_i2c_sda4, cci_i2c_scl4 */
+ pins = "gpio117","gpio118";
+ function = "cci_i2c";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ cci2_i2c1_default: cci2-i2c1-default-pins {
+ /* cci_i2c_sda5, cci_i2c_scl5 */
+ pins = "gpio12","gpio13";
+ function = "cci_i2c";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+
+ cci2_sleep: cci2-sleep-state {
+ cci2_i2c0_sleep: cci2-i2c0-sleep-pins {
+ /* cci_i2c_sda4, cci_i2c_scl4 */
+ pins = "gpio117","gpio118";
+ function = "cci_i2c";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+
+ cci2_i2c1_sleep: cci2-i2c1-sleep-pins {
+ /* cci_i2c_sda5, cci_i2c_scl5 */
+ pins = "gpio12","gpio13";
+ function = "cci_i2c";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+ };
+
+ cci3_default: cci3-default-state {
+ cci3_i2c0_default: cci3-i2c0-default-pins {
+ /* cci_i2c_sda6, cci_i2c_scl6 */
+ pins = "gpio145","gpio146";
+ function = "cci_i2c";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+
+ cci3_i2c1_default: cci3-i2c1-default-pins {
+ /* cci_i2c_sda7, cci_i2c_scl7 */
+ pins = "gpio164","gpio165";
+ function = "cci_i2c";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+
+ cci3_sleep: cci3-sleep-state {
+ cci3_i2c0_sleep: cci3-i2c0-sleep-pins {
+ /* cci_i2c_sda6, cci_i2c_scl6 */
+ pins = "gpio145","gpio146";
+ function = "cci_i2c";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+
+ cci3_i2c1_sleep: cci3-i2c1-sleep-pins {
+ /* cci_i2c_sda7, cci_i2c_scl7 */
+ pins = "gpio164","gpio165";
+ function = "cci_i2c";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+ };
};
apps_smmu: iommu@15000000 {
@@ -5212,6 +5782,21 @@
};
};
+ gpu-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors = <&tsens2 2>;
+
+ trips {
+ gpu-crit {
+ temperature = <110000>;
+ hysteresis = <1000>;
+ type = "critical";
+ };
+ };
+ };
+
mem-thermal {
polling-delay-passive = <250>;
polling-delay = <1000>;
diff --git a/arch/arm64/boot/dts/qcom/sda660-inforce-ifc6560.dts b/arch/arm64/boot/dts/qcom/sda660-inforce-ifc6560.dts
index 2ed39d402d3f..702ab49bbc59 100644
--- a/arch/arm64/boot/dts/qcom/sda660-inforce-ifc6560.dts
+++ b/arch/arm64/boot/dts/qcom/sda660-inforce-ifc6560.dts
@@ -461,3 +461,8 @@
dr_mode = "peripheral";
extcon = <&extcon_usb>;
};
+
+&usb3_qmpphy {
+ vdda-phy-supply = <&vreg_l1b_0p925>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm450-motorola-ali.dts b/arch/arm64/boot/dts/qcom/sdm450-motorola-ali.dts
index 362be5719dd2..e27f3c5d5bba 100644
--- a/arch/arm64/boot/dts/qcom/sdm450-motorola-ali.dts
+++ b/arch/arm64/boot/dts/qcom/sdm450-motorola-ali.dts
@@ -4,7 +4,7 @@
*/
/dts-v1/;
-#include "msm8953.dtsi"
+#include "sdm450.dtsi"
#include "pm8953.dtsi"
#include "pmi8950.dtsi"
diff --git a/arch/arm64/boot/dts/qcom/sdm450.dtsi b/arch/arm64/boot/dts/qcom/sdm450.dtsi
new file mode 100644
index 000000000000..b222aeb459a3
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm450.dtsi
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/* Copyright (c) 2023, Luca Weiss <luca@z3ntu.xyz> */
+
+#include "msm8953.dtsi"
+
+&gpu_opp_table {
+ /delete-node/ opp-650000000;
+
+ opp-600000000 {
+ opp-hz = /bits/ 64 <600000000>;
+ opp-supported-hw = <0xff>;
+ required-opps = <&rpmpd_opp_turbo>;
+ };
+};
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 87d0293c728d..819a5f8825e7 100644
--- a/arch/arm64/boot/dts/qcom/sdm630-sony-xperia-nile.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm630-sony-xperia-nile.dtsi
@@ -241,6 +241,16 @@
};
};
+&pm660l_wled {
+ status = "okay";
+
+ qcom,switching-freq = <800>;
+ qcom,ovp-millivolt = <29600>;
+ qcom,current-boost-limit = <970>;
+ qcom,current-limit-microamp = <17500>;
+ qcom,num-strings = <2>;
+};
+
&pon_pwrkey {
status = "okay";
};
@@ -658,10 +668,16 @@
};
&usb3 {
+ qcom,select-utmi-as-pipe-clk;
+
status = "okay";
};
&usb3_dwc3 {
+ maximum-speed = "high-speed";
+ phys = <&qusb2phy0>;
+ phy-names = "usb2-phy";
+
dr_mode = "peripheral";
extcon = <&extcon_usb>;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi b/arch/arm64/boot/dts/qcom/sdm630.dtsi
index 513fe5e76b68..f5921b80ef94 100644
--- a/arch/arm64/boot/dts/qcom/sdm630.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi
@@ -13,6 +13,7 @@
#include <dt-bindings/power/qcom-rpmpd.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/thermal/thermal.h>
#include <dt-bindings/soc/qcom,apr.h>
/ {
@@ -1100,6 +1101,7 @@
interconnect-names = "gfx-mem";
operating-points-v2 = <&gpu_sdm630_opp_table>;
+ #cooling-cells = <2>;
status = "disabled";
@@ -1281,12 +1283,16 @@
<&gcc GCC_USB30_MASTER_CLK>;
assigned-clock-rates = <19200000>, <120000000>;
- interrupts = <GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH>,
+ interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "hs_phy_irq", "ss_phy_irq";
+ interrupt-names = "pwr_event",
+ "qusb2_phy",
+ "hs_phy_irq",
+ "ss_phy_irq";
power-domains = <&gcc USB_30_GDSC>;
- qcom,select-utmi-as-pipe-clk;
resets = <&gcc GCC_USB_30_BCR>;
@@ -1297,17 +1303,38 @@
snps,dis_u2_susphy_quirk;
snps,dis_enblslpm_quirk;
- /*
- * SDM630 technically supports USB3 but I
- * haven't seen any devices making use of it.
- */
- maximum-speed = "high-speed";
- phys = <&qusb2phy0>;
- phy-names = "usb2-phy";
+ phys = <&qusb2phy0>, <&usb3_qmpphy>;
+ phy-names = "usb2-phy", "usb3-phy";
snps,hird-threshold = /bits/ 8 <0>;
};
};
+ usb3_qmpphy: phy@c010000 {
+ compatible = "qcom,sdm660-qmp-usb3-phy";
+ reg = <0x0c010000 0x1000>;
+
+ clocks = <&gcc GCC_USB3_PHY_AUX_CLK>,
+ <&gcc GCC_USB3_CLKREF_CLK>,
+ <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>,
+ <&gcc GCC_USB3_PHY_PIPE_CLK>;
+ clock-names = "aux",
+ "ref",
+ "cfg_ahb",
+ "pipe";
+ clock-output-names = "usb3_phy_pipe_clk_src";
+ #clock-cells = <0>;
+ #phy-cells = <0>;
+
+ resets = <&gcc GCC_USB3_PHY_BCR>,
+ <&gcc GCC_USB3PHY_PHY_BCR>;
+ reset-names = "phy",
+ "phy_phy";
+
+ qcom,tcsr-reg = <&tcsr_regs_1 0x6b244>;
+
+ status = "disabled";
+ };
+
qusb2phy0: phy@c012000 {
compatible = "qcom,sdm660-qusb2-phy";
reg = <0x0c012000 0x180>;
@@ -1463,8 +1490,12 @@
<&gcc GCC_USB20_MASTER_CLK>;
assigned-clock-rates = <19200000>, <60000000>;
- interrupts = <GIC_SPI 348 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "hs_phy_irq";
+ interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 348 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "pwr_event",
+ "qusb2_phy",
+ "hs_phy_irq";
qcom,select-utmi-as-pipe-clk;
@@ -2551,6 +2582,13 @@
thermal-sensors = <&tsens 8>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu_alert0>;
+ cooling-device = <&adreno_gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
gpu_alert0: trip-point0 {
temperature = <90000>;
diff --git a/arch/arm64/boot/dts/qcom/sdm632.dtsi b/arch/arm64/boot/dts/qcom/sdm632.dtsi
index 645b9f6a801f..95b025ea260b 100644
--- a/arch/arm64/boot/dts/qcom/sdm632.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm632.dtsi
@@ -79,3 +79,11 @@
compatible = "qcom,kryo250";
capacity-dmips-mhz = <1980>;
};
+
+&gpu_opp_table {
+ opp-725000000 {
+ opp-hz = /bits/ 64 <725000000>;
+ opp-supported-hw = <0xff>;
+ required-opps = <&rpmpd_opp_turbo>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts b/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts
index 3c47410ba94c..7167f75bced3 100644
--- a/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts
+++ b/arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts
@@ -413,10 +413,16 @@
};
&usb3 {
+ qcom,select-utmi-as-pipe-clk;
+
status = "okay";
};
&usb3_dwc3 {
+ maximum-speed = "high-speed";
+ phys = <&qusb2phy0>;
+ phy-names = "usb2-phy";
+
dr_mode = "peripheral";
extcon = <&extcon_usb>;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi
index 4d7b77a23159..80e81c4233b3 100644
--- a/arch/arm64/boot/dts/qcom/sdm670.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi
@@ -1320,12 +1320,16 @@
<&gcc GCC_USB30_PRIM_MASTER_CLK>;
assigned-clock-rates = <19200000>, <150000000>;
- interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
- <&pdc 6 IRQ_TYPE_LEVEL_HIGH>,
+ interrupts-extended = <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <&pdc 9 IRQ_TYPE_EDGE_BOTH>,
<&pdc 8 IRQ_TYPE_EDGE_BOTH>,
- <&pdc 9 IRQ_TYPE_EDGE_BOTH>;
- interrupt-names = "hs_phy_irq", "ss_phy_irq",
- "dm_hs_phy_irq", "dp_hs_phy_irq";
+ <&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>;
diff --git a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
index 0ab5e8f53ac9..e8276db9eabb 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
@@ -852,6 +852,7 @@ ap_ts_i2c: &i2c14 {
pinctrl-names = "default";
pinctrl-0 = <&ec_ap_int_l>;
spi-max-frequency = <3000000>;
+ wakeup-source;
cros_ec_pwm: pwm {
compatible = "google,cros-ec-pwm";
diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
index ab6220456513..1f517328199b 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
@@ -580,7 +580,7 @@
&pcie0 {
status = "okay";
perst-gpios = <&tlmm 35 GPIO_ACTIVE_LOW>;
- enable-gpio = <&tlmm 134 GPIO_ACTIVE_HIGH>;
+ wake-gpios = <&tlmm 134 GPIO_ACTIVE_HIGH>;
vddpe-3v3-supply = <&pcie0_3p3v_dual>;
diff --git a/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi b/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi
index e821103d49c0..46e25c53829a 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi
@@ -508,13 +508,13 @@
};
&q6afedai {
- qi2s@22 {
- reg = <22>;
+ dai@22 {
+ reg = <QUATERNARY_MI2S_RX>;
qcom,sd-lines = <1>;
};
- qi2s@23 {
- reg = <23>;
+ dai@23 {
+ reg = <QUATERNARY_MI2S_TX>;
qcom,sd-lines = <0>;
};
};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts b/arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts
index fbb8655653fb..486ce175e6bc 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts
@@ -60,7 +60,7 @@
};
reserved-memory {
- framebuffer_region@9d400000 {
+ framebuffer@9d400000 {
reg = <0x0 0x9d400000 0x0 (1080 * 2160 * 4)>;
no-map;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index c2244824355a..2f20be99ee7e 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -2639,10 +2639,12 @@
compatible = "qcom,sdm845-qmp-ufs-phy";
reg = <0 0x01d87000 0 0x1000>;
+ clocks = <&rpmhcc RPMH_CXO_CLK>,
+ <&gcc GCC_UFS_PHY_PHY_AUX_CLK>,
+ <&gcc GCC_UFS_MEM_CLKREF_CLK>;
clock-names = "ref",
- "ref_aux";
- clocks = <&gcc GCC_UFS_MEM_CLKREF_CLK>,
- <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
+ "ref_aux",
+ "qref";
resets = <&ufs_mem_hc 0>;
reset-names = "ufsphy";
@@ -3366,8 +3368,8 @@
qcom,qmp = <&aoss_qmp>;
- power-domains = <&rpmhpd SDM845_CX>,
- <&rpmhpd SDM845_MX>;
+ power-domains = <&rpmhpd SDM845_LCX>,
+ <&rpmhpd SDM845_LMX>;
power-domain-names = "lcx", "lmx";
memory-region = <&slpi_mem>;
@@ -4058,12 +4060,16 @@
<&gcc GCC_USB30_PRIM_MASTER_CLK>;
assigned-clock-rates = <19200000>, <150000000>;
- interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
- <&pdc_intc 6 IRQ_TYPE_LEVEL_HIGH>,
+ interrupts-extended = <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <&pdc_intc 9 IRQ_TYPE_EDGE_BOTH>,
<&pdc_intc 8 IRQ_TYPE_EDGE_BOTH>,
- <&pdc_intc 9 IRQ_TYPE_EDGE_BOTH>;
- interrupt-names = "hs_phy_irq", "ss_phy_irq",
- "dm_hs_phy_irq", "dp_hs_phy_irq";
+ <&pdc_intc 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>;
@@ -4109,12 +4115,16 @@
<&gcc GCC_USB30_SEC_MASTER_CLK>;
assigned-clock-rates = <19200000>, <150000000>;
- interrupts-extended = <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
- <&pdc_intc 7 IRQ_TYPE_LEVEL_HIGH>,
+ interrupts-extended = <&intc GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+ <&pdc_intc 11 IRQ_TYPE_EDGE_BOTH>,
<&pdc_intc 10 IRQ_TYPE_EDGE_BOTH>,
- <&pdc_intc 11 IRQ_TYPE_EDGE_BOTH>;
- interrupt-names = "hs_phy_irq", "ss_phy_irq",
- "dm_hs_phy_irq", "dp_hs_phy_irq";
+ <&pdc_intc 7 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_SEC_GDSC>;
@@ -4760,6 +4770,7 @@
operating-points-v2 = <&gpu_opp_table>;
qcom,gmu = <&gmu>;
+ #cooling-cells = <2>;
interconnects = <&mem_noc MASTER_GFX3D 0 &mem_noc SLAVE_EBI1 0>;
interconnect-names = "gfx-mem";
@@ -5568,7 +5579,7 @@
hysteresis = <2000>;
type = "hot";
};
- cluster0_crit: cluster0_crit {
+ cluster0_crit: cluster0-crit {
temperature = <110000>;
hysteresis = <2000>;
type = "critical";
@@ -5588,7 +5599,7 @@
hysteresis = <2000>;
type = "hot";
};
- cluster1_crit: cluster1_crit {
+ cluster1_crit: cluster1-crit {
temperature = <110000>;
hysteresis = <2000>;
type = "critical";
@@ -5602,8 +5613,15 @@
thermal-sensors = <&tsens0 11>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu_top_alert0>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
- gpu1_alert0: trip-point0 {
+ gpu_top_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <2000>;
type = "hot";
@@ -5617,8 +5635,15 @@
thermal-sensors = <&tsens0 12>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu_bottom_alert0>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
- gpu2_alert0: trip-point0 {
+ gpu_bottom_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <2000>;
type = "hot";
diff --git a/arch/arm64/boot/dts/qcom/sm4450.dtsi b/arch/arm64/boot/dts/qcom/sm4450.dtsi
index 3e7ae3bebbe0..603c962661cc 100644
--- a/arch/arm64/boot/dts/qcom/sm4450.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm4450.dtsi
@@ -17,7 +17,7 @@
chosen { };
- clocks{
+ clocks {
xo_board: xo-board {
compatible = "fixed-clock";
clock-frequency = <76800000>;
diff --git a/arch/arm64/boot/dts/qcom/sm6115.dtsi b/arch/arm64/boot/dts/qcom/sm6115.dtsi
index f9849b8befbf..aca0a87092e4 100644
--- a/arch/arm64/boot/dts/qcom/sm6115.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm6115.dtsi
@@ -14,6 +14,7 @@
#include <dt-bindings/interconnect/qcom,sm6115.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/power/qcom-rpmpd.h>
+#include <dt-bindings/thermal/thermal.h>
/ {
interrupt-parent = <&intc>;
@@ -614,6 +615,11 @@
#hwlock-cells = <1>;
};
+ tcsr_regs: syscon@3c0000 {
+ compatible = "qcom,sm6115-tcsr", "syscon";
+ reg = <0x0 0x003c0000 0x0 0x40000>;
+ };
+
tlmm: pinctrl@500000 {
compatible = "qcom,sm6115-tlmm";
reg = <0x0 0x00500000 0x0 0x400000>,
@@ -878,8 +884,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 {
@@ -1194,8 +1223,12 @@
compatible = "qcom,sm6115-qmp-ufs-phy";
reg = <0x0 0x04807000 0x0 0x1000>;
- clocks = <&gcc GCC_UFS_CLKREF_CLK>, <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
- clock-names = "ref", "ref_aux";
+ clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>,
+ <&gcc GCC_UFS_PHY_PHY_AUX_CLK>,
+ <&gcc GCC_UFS_CLKREF_CLK>;
+ clock-names = "ref",
+ "ref_aux",
+ "qref";
resets = <&ufs_mem_hc 0>;
reset-names = "ufsphy";
@@ -1589,9 +1622,14 @@
<&gcc GCC_USB30_PRIM_MASTER_CLK>;
assigned-clock-rates = <19200000>, <66666667>;
- interrupts = <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
+ interrupts = <GIC_SPI 302 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "hs_phy_irq", "ss_phy_irq";
+ interrupt-names = "pwr_event",
+ "qusb2_phy",
+ "hs_phy_irq",
+ "ss_phy_irq";
resets = <&gcc GCC_USB30_PRIM_BCR>;
power-domains = <&gcc GCC_USB30_PRIM_GDSC>;
@@ -1603,7 +1641,6 @@
interconnect-names = "usb-ddr",
"apps-usb";
- qcom,select-utmi-as-pipe-clk;
status = "disabled";
usb_dwc3: usb@4e00000 {
@@ -1618,6 +1655,28 @@
snps,has-lpm-erratum;
snps,hird-threshold = /bits/ 8 <0x10>;
snps,usb3_lpm_capable;
+
+ 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>;
+ };
+ };
+ };
};
};
@@ -1649,6 +1708,7 @@
nvmem-cells = <&gpu_speed_bin>;
nvmem-cell-names = "speed_bin";
+ #cooling-cells = <2>;
status = "disabled";
@@ -3088,7 +3148,7 @@
type = "passive";
};
- cpu4_crit: cpu_crit {
+ cpu4_crit: cpu-crit {
temperature = <110000>;
hysteresis = <1000>;
type = "critical";
@@ -3114,7 +3174,7 @@
type = "passive";
};
- cpu5_crit: cpu_crit {
+ cpu5_crit: cpu-crit {
temperature = <110000>;
hysteresis = <1000>;
type = "critical";
@@ -3140,7 +3200,7 @@
type = "passive";
};
- cpu6_crit: cpu_crit {
+ cpu6_crit: cpu-crit {
temperature = <110000>;
hysteresis = <1000>;
type = "critical";
@@ -3166,7 +3226,7 @@
type = "passive";
};
- cpu7_crit: cpu_crit {
+ cpu7_crit: cpu-crit {
temperature = <110000>;
hysteresis = <1000>;
type = "critical";
@@ -3192,7 +3252,7 @@
type = "passive";
};
- cpu45_crit: cpu_crit {
+ cpu45_crit: cpu-crit {
temperature = <110000>;
hysteresis = <1000>;
type = "critical";
@@ -3218,7 +3278,7 @@
type = "passive";
};
- cpu67_crit: cpu_crit {
+ cpu67_crit: cpu-crit {
temperature = <110000>;
hysteresis = <1000>;
type = "critical";
@@ -3244,7 +3304,7 @@
type = "passive";
};
- cpu0123_crit: cpu_crit {
+ cpu0123_crit: cpu-crit {
temperature = <110000>;
hysteresis = <1000>;
type = "critical";
@@ -3297,8 +3357,15 @@
polling-delay = <0>;
thermal-sensors = <&tsens0 15>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu_alert0>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
- trip-point0 {
+ gpu_alert0: trip-point0 {
temperature = <115000>;
hysteresis = <5000>;
type = "passive";
@@ -3307,7 +3374,7 @@
trip-point1 {
temperature = <125000>;
hysteresis = <1000>;
- type = "passive";
+ type = "critical";
};
};
};
diff --git a/arch/arm64/boot/dts/qcom/sm6125.dtsi b/arch/arm64/boot/dts/qcom/sm6125.dtsi
index 1dd3a4056e26..98ab08356088 100644
--- a/arch/arm64/boot/dts/qcom/sm6125.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm6125.dtsi
@@ -812,10 +812,12 @@
compatible = "qcom,sm6125-qmp-ufs-phy";
reg = <0x04807000 0xdb8>;
- clocks = <&gcc GCC_UFS_MEM_CLKREF_CLK>,
- <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
+ clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>,
+ <&gcc GCC_UFS_PHY_PHY_AUX_CLK>,
+ <&gcc GCC_UFS_MEM_CLKREF_CLK>;
clock-names = "ref",
- "ref_aux";
+ "ref_aux",
+ "qref";
resets = <&ufs_mem_hc 0>;
reset-names = "ufsphy";
@@ -1185,9 +1187,14 @@
<&gcc GCC_USB30_PRIM_MASTER_CLK>;
assigned-clock-rates = <19200000>, <66666667>;
- interrupts = <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
+ interrupts = <GIC_SPI 302 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "hs_phy_irq", "ss_phy_irq";
+ interrupt-names = "pwr_event",
+ "qusb2_phy",
+ "hs_phy_irq",
+ "ss_phy_irq";
power-domains = <&gcc USB30_PRIM_GDSC>;
qcom,select-utmi-as-pipe-clk;
diff --git a/arch/arm64/boot/dts/qcom/sm6350.dtsi b/arch/arm64/boot/dts/qcom/sm6350.dtsi
index 43cffe8e1247..24bcec3366ef 100644
--- a/arch/arm64/boot/dts/qcom/sm6350.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm6350.dtsi
@@ -19,6 +19,7 @@
#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>
/ {
interrupt-parent = <&intc>;
@@ -1189,10 +1190,12 @@
compatible = "qcom,sm6350-qmp-ufs-phy";
reg = <0 0x01d87000 0 0x1000>;
+ clocks = <&rpmhcc RPMH_CXO_CLK>,
+ <&gcc GCC_UFS_PHY_PHY_AUX_CLK>,
+ <&gcc GCC_UFS_MEM_CLKREF_CLK>;
clock-names = "ref",
- "ref_aux";
- clocks = <&gcc GCC_UFS_MEM_CLKREF_CLK>,
- <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
+ "ref_aux",
+ "qref";
resets = <&ufs_mem_hc 0>;
reset-names = "ufsphy";
@@ -1325,10 +1328,11 @@
qcom,gmu = <&gmu>;
nvmem-cells = <&gpu_speed_bin>;
nvmem-cell-names = "speed_bin";
+ #cooling-cells = <2>;
status = "disabled";
- zap-shader {
+ gpu_zap_shader: zap-shader {
memory-region = <&pil_gpu_mem>;
};
@@ -1439,8 +1443,6 @@
operating-points-v2 = <&gmu_opp_table>;
- status = "disabled";
-
gmu_opp_table: opp-table {
compatible = "operating-points-v2";
@@ -1830,12 +1832,15 @@
"mock_utmi";
interrupts-extended = <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
- <&pdc 17 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <&pdc 14 IRQ_TYPE_EDGE_BOTH>,
<&pdc 15 IRQ_TYPE_EDGE_BOTH>,
- <&pdc 14 IRQ_TYPE_EDGE_BOTH>;
-
- interrupt-names = "hs_phy_irq", "ss_phy_irq",
- "dm_hs_phy_irq", "dp_hs_phy_irq";
+ <&pdc 17 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>;
@@ -1966,6 +1971,13 @@
interrupt-controller;
#interrupt-cells = <1>;
+ interconnects = <&mmss_noc MASTER_MDP_PORT0 QCOM_ICC_TAG_ALWAYS
+ &clk_virt SLAVE_EBI_CH0 QCOM_ICC_TAG_ALWAYS>,
+ <&gem_noc MASTER_AMPSS_M0 QCOM_ICC_TAG_ACTIVE_ONLY
+ &config_noc SLAVE_DISPLAY_CFG QCOM_ICC_TAG_ACTIVE_ONLY>;
+ interconnect-names = "mdp0-mem",
+ "cpu-cfg";
+
clocks = <&gcc GCC_DISP_AHB_CLK>,
<&gcc GCC_DISP_AXI_CLK>,
<&dispcc DISP_CC_MDSS_MDP_CLK>;
@@ -2698,6 +2710,569 @@
};
};
+ thermal-zones {
+ aoss0-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors = <&tsens0 0>;
+
+ trips {
+ aoss0-crit {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ aoss1-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors = <&tsens1 0>;
+
+ trips {
+ aoss1-crit {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ audio-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors = <&tsens1 2>;
+
+ trips {
+ audio-crit {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ camera-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors = <&tsens1 5>;
+
+ trips {
+ camera-crit {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpu0-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors = <&tsens0 1>;
+
+ trips {
+ cpu0_alert0: trip-point0 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu0-crit {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu0_alert0>;
+ cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ cpu1-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors = <&tsens0 2>;
+
+ trips {
+ cpu1_alert0: trip-point0 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu1-crit {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu1_alert0>;
+ cooling-device = <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ cpu2-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors = <&tsens0 3>;
+
+ trips {
+ cpu2_alert0: trip-point0 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu2-crit {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu2_alert0>;
+ cooling-device = <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ cpu3-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors = <&tsens0 4>;
+
+ trips {
+ cpu3_alert0: trip-point0 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu3-crit {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu3_alert0>;
+ cooling-device = <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ cpu4-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors = <&tsens0 5>;
+
+ trips {
+ cpu4_alert0: trip-point0 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu4-crit {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu4_alert0>;
+ cooling-device = <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ cpu5-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors = <&tsens0 6>;
+
+ trips {
+ cpu5_alert0: trip-point0 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu5-crit {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu5_alert0>;
+ cooling-device = <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ cpu6-left-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors = <&tsens0 9>;
+
+ trips {
+ cpu6_left_alert0: trip-point0 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu6-left-crit {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu6_left_alert0>;
+ cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ cpu6-right-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors = <&tsens0 10>;
+
+ trips {
+ cpu6_right_alert0: trip-point0 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu6-right-crit {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu6_right_alert0>;
+ cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ cpu7-left-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors = <&tsens0 11>;
+
+ trips {
+ cpu7_left_alert0: trip-point0 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu7-left-crit {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu7_left_alert0>;
+ cooling-device = <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ cpu7-right-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors = <&tsens0 12>;
+
+ trips {
+ cpu7_right_alert0: trip-point0 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu7-right-crit {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu7_right_alert0>;
+ cooling-device = <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ cpuss0-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors = <&tsens0 7>;
+
+ trips {
+ cpuss0-crit {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ cpuss1-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors = <&tsens0 8>;
+
+ trips {
+ cpuss1-crit {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ cwlan-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors = <&tsens1 1>;
+
+ trips {
+ cwlan-crit {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ ddr-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors = <&tsens1 3>;
+
+ trips {
+ ddr-crit {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ gpuss0-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors = <&tsens0 13>;
+
+ trips {
+ gpuss0_alert0: trip-point0 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ gpuss0-crit {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&gpuss0_alert0>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ gpuss1-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors = <&tsens0 14>;
+
+ trips {
+ gpuss1_alert0: trip-point0 {
+ temperature = <95000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ gpuss1-crit {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&gpuss1_alert0>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ modem-core0-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors = <&tsens1 6>;
+
+ trips {
+ modem-core0-crit {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ modem-core1-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors = <&tsens1 7>;
+
+ trips {
+ modem-core1-crit {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ modem-scl-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors = <&tsens1 9>;
+
+ trips {
+ modem-scl-crit {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ modem-vec-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors = <&tsens1 8>;
+
+ trips {
+ modem-vec-crit {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ npu-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors = <&tsens1 10>;
+
+ trips {
+ npu-crit {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ q6-hvx-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors = <&tsens1 4>;
+
+ trips {
+ q6-hvx-crit {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+
+ video-thermal {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+
+ thermal-sensors = <&tsens1 11>;
+
+ trips {
+ video-crit {
+ temperature = <125000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
+ };
+ };
+
timer {
compatible = "arm,armv8-timer";
clock-frequency = <19200000>;
diff --git a/arch/arm64/boot/dts/qcom/sm6375.dtsi b/arch/arm64/boot/dts/qcom/sm6375.dtsi
index 7ac8bf26dda3..4386f8a9c636 100644
--- a/arch/arm64/boot/dts/qcom/sm6375.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm6375.dtsi
@@ -1431,13 +1431,15 @@
assigned-clock-rates = <19200000>, <133333333>;
interrupts-extended = <&intc GIC_SPI 302 IRQ_TYPE_LEVEL_HIGH>,
- <&mpm 12 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH>,
+ <&mpm 94 IRQ_TYPE_EDGE_BOTH>,
<&mpm 93 IRQ_TYPE_EDGE_BOTH>,
- <&mpm 94 IRQ_TYPE_EDGE_BOTH>;
- interrupt-names = "hs_phy_irq",
- "ss_phy_irq",
+ <&mpm 12 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";
power-domains = <&gcc USB30_PRIM_GDSC>;
diff --git a/arch/arm64/boot/dts/qcom/sm7125-xiaomi-common.dtsi b/arch/arm64/boot/dts/qcom/sm7125-xiaomi-common.dtsi
index e55cd83c19b8..29289fa41b13 100644
--- a/arch/arm64/boot/dts/qcom/sm7125-xiaomi-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm7125-xiaomi-common.dtsi
@@ -152,6 +152,9 @@
regulator-min-microvolt = <824000>;
regulator-max-microvolt = <928000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
};
vreg_l5a_2p7: ldo5 {
@@ -188,6 +191,9 @@
regulator-min-microvolt = <1696000>;
regulator-max-microvolt = <1952000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
};
vreg_l13a_1p8: ldo13 {
@@ -230,6 +236,9 @@
regulator-min-microvolt = <2696000>;
regulator-max-microvolt = <3304000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
};
};
@@ -258,6 +267,9 @@
regulator-min-microvolt = <1144000>;
regulator-max-microvolt = <1304000>;
regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
};
vreg_l4c_1p8: ldo4 {
@@ -398,6 +410,20 @@
};
};
+&ufs_mem_hc {
+ vcc-supply = <&vreg_l19a_3p0>;
+ vcc-max-microamp = <600000>;
+ vccq2-supply = <&vreg_l12a_1p8>;
+ vccq2-max-microamp = <600000>;
+ status = "okay";
+};
+
+&ufs_mem_phy {
+ vdda-phy-supply = <&vreg_l4a_0p88>;
+ vdda-pll-supply = <&vreg_l3c_1p23>;
+ status = "okay";
+};
+
&usb_1 {
qcom,select-utmi-as-pipe-clk;
status = "okay";
diff --git a/arch/arm64/boot/dts/qcom/sm7125-xiaomi-curtana.dts b/arch/arm64/boot/dts/qcom/sm7125-xiaomi-curtana.dts
new file mode 100644
index 000000000000..12f517a8492c
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sm7125-xiaomi-curtana.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023, Joe Mason <buddyjojo06@outlook.com>
+ */
+
+/dts-v1/;
+
+#include "sm7125-xiaomi-common.dtsi"
+
+/ {
+ model = "Xiaomi Redmi Note 9S";
+ compatible = "xiaomi,curtana", "qcom,sm7125";
+
+ /* required for bootloader to select correct board */
+ qcom,board-id = <0x20022 1>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts b/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts
index ade619805519..bc67e8c1fe4d 100644
--- a/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts
+++ b/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts
@@ -68,6 +68,14 @@
};
};
+ /* Dummy regulator until PM6150L has LCDB VSP/VSN support */
+ lcdb_dummy: regulator-lcdb-dummy {
+ compatible = "regulator-fixed";
+ regulator-name = "lcdb_dummy";
+ regulator-min-microvolt = <5500000>;
+ regulator-max-microvolt = <5500000>;
+ };
+
reserved-memory {
/*
* The rmtfs memory region in downstream is 'dynamically allocated'
@@ -116,7 +124,7 @@
};
&adsp {
- firmware-name = "qcom/sm7225/fairphone4/adsp.mdt";
+ firmware-name = "qcom/sm7225/fairphone4/adsp.mbn";
status = "okay";
};
@@ -361,7 +369,7 @@
};
&cdsp {
- firmware-name = "qcom/sm7225/fairphone4/cdsp.mdt";
+ firmware-name = "qcom/sm7225/fairphone4/cdsp.mbn";
status = "okay";
};
@@ -373,6 +381,14 @@
status = "okay";
};
+&gpu {
+ status = "okay";
+};
+
+&gpu_zap_shader {
+ firmware-name = "qcom/sm7225/fairphone4/a615_zap.mbn";
+};
+
&i2c0 {
clock-frequency = <400000>;
status = "okay";
@@ -400,12 +416,49 @@
&ipa {
qcom,gsi-loader = "self";
memory-region = <&pil_ipa_fw_mem>;
- firmware-name = "qcom/sm7225/fairphone4/ipa_fws.mdt";
+ firmware-name = "qcom/sm7225/fairphone4/ipa_fws.mbn";
+ status = "okay";
+};
+
+&mdss {
+ status = "okay";
+};
+
+&mdss_dsi0 {
+ vdda-supply = <&vreg_l22a>;
+ status = "okay";
+
+ panel@0 {
+ compatible = "djn,9a-3r063-1102b";
+ reg = <0>;
+
+ backlight = <&pm6150l_wled>;
+ reset-gpios = <&pm6150l_gpios 9 GPIO_ACTIVE_LOW>;
+
+ vdd1-supply = <&vreg_l1e>;
+ vsn-supply = <&lcdb_dummy>;
+ vsp-supply = <&lcdb_dummy>;
+
+ port {
+ panel_in: endpoint {
+ remote-endpoint = <&mdss_dsi0_out>;
+ };
+ };
+ };
+};
+
+&mdss_dsi0_out {
+ data-lanes = <0 1 2 3>;
+ remote-endpoint = <&panel_in>;
+};
+
+&mdss_dsi0_phy {
+ vdds-supply = <&vreg_l18a>;
status = "okay";
};
&mpss {
- firmware-name = "qcom/sm7225/fairphone4/modem.mdt";
+ firmware-name = "qcom/sm7225/fairphone4/modem.mbn";
status = "okay";
};
diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi
index 761a6757dc26..a35c0852b5a1 100644
--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi
@@ -967,7 +967,7 @@
#address-cells = <1>;
#size-cells = <1>;
- gpu_speed_bin: gpu_speed_bin@133 {
+ gpu_speed_bin: gpu-speed-bin@133 {
reg = <0x133 0x1>;
bits = <5 3>;
};
@@ -1843,8 +1843,22 @@
ranges = <0x01000000 0x0 0x00000000 0x0 0x60200000 0x0 0x100000>,
<0x02000000 0x0 0x60300000 0x0 0x60300000 0x0 0x3d00000>;
- interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "msi";
+ interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi0",
+ "msi1",
+ "msi2",
+ "msi3",
+ "msi4",
+ "msi5",
+ "msi6",
+ "msi7";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0x7>;
interrupt-map = <0 0 0 1 &intc 0 149 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
@@ -1858,14 +1872,16 @@
<&gcc GCC_PCIE_0_MSTR_AXI_CLK>,
<&gcc GCC_PCIE_0_SLV_AXI_CLK>,
<&gcc GCC_PCIE_0_SLV_Q2A_AXI_CLK>,
- <&gcc GCC_AGGRE_NOC_PCIE_TBU_CLK>;
+ <&gcc GCC_AGGRE_NOC_PCIE_TBU_CLK>,
+ <&rpmhcc RPMH_CXO_CLK>;
clock-names = "pipe",
"aux",
"cfg",
"bus_master",
"bus_slave",
"slave_q2a",
- "tbu";
+ "tbu",
+ "ref";
iommu-map = <0x0 &apps_smmu 0x1d80 0x1>,
<0x100 &apps_smmu 0x1d81 0x1>;
@@ -1879,7 +1895,7 @@
phy-names = "pciephy";
perst-gpios = <&tlmm 35 GPIO_ACTIVE_HIGH>;
- enable-gpio = <&tlmm 37 GPIO_ACTIVE_HIGH>;
+ wake-gpios = <&tlmm 37 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&pcie0_default_state>;
@@ -1934,8 +1950,22 @@
ranges = <0x01000000 0x0 0x00000000 0x0 0x40200000 0x0 0x100000>,
<0x02000000 0x0 0x40300000 0x0 0x40300000 0x0 0x1fd00000>;
- interrupts = <GIC_SPI 307 IRQ_TYPE_EDGE_RISING>;
- interrupt-names = "msi";
+ interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi0",
+ "msi1",
+ "msi2",
+ "msi3",
+ "msi4",
+ "msi5",
+ "msi6",
+ "msi7";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0x7>;
interrupt-map = <0 0 0 1 &intc 0 434 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
@@ -1949,14 +1979,16 @@
<&gcc GCC_PCIE_1_MSTR_AXI_CLK>,
<&gcc GCC_PCIE_1_SLV_AXI_CLK>,
<&gcc GCC_PCIE_1_SLV_Q2A_AXI_CLK>,
- <&gcc GCC_AGGRE_NOC_PCIE_TBU_CLK>;
+ <&gcc GCC_AGGRE_NOC_PCIE_TBU_CLK>,
+ <&rpmhcc RPMH_CXO_CLK>;
clock-names = "pipe",
"aux",
"cfg",
"bus_master",
"bus_slave",
"slave_q2a",
- "tbu";
+ "tbu",
+ "ref";
assigned-clocks = <&gcc GCC_PCIE_1_AUX_CLK>;
assigned-clock-rates = <19200000>;
@@ -2063,10 +2095,12 @@
compatible = "qcom,sm8150-qmp-ufs-phy";
reg = <0 0x01d87000 0 0x1000>;
+ clocks = <&rpmhcc RPMH_CXO_CLK>,
+ <&gcc GCC_UFS_PHY_PHY_AUX_CLK>,
+ <&gcc GCC_UFS_MEM_CLKREF_CLK>;
clock-names = "ref",
- "ref_aux";
- clocks = <&gcc GCC_UFS_MEM_CLKREF_CLK>,
- <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
+ "ref_aux",
+ "qref";
power-domains = <&gcc UFS_PHY_GDSC>;
@@ -2198,6 +2232,7 @@
nvmem-cells = <&gpu_speed_bin>;
nvmem-cell-names = "speed_bin";
+ #cooling-cells = <2>;
status = "disabled";
@@ -2428,7 +2463,7 @@
bias-disable;
};
- qup_spi6_default: qup-spi6_default-state {
+ qup_spi6_default: qup-spi6-default-state {
pins = "gpio4", "gpio5", "gpio6", "gpio7";
function = "qup6";
drive-strength = <6>;
@@ -2442,7 +2477,7 @@
bias-disable;
};
- qup_spi7_default: qup-spi7_default-state {
+ qup_spi7_default: qup-spi7-default-state {
pins = "gpio98", "gpio99", "gpio100", "gpio101";
function = "qup7";
drive-strength = <6>;
@@ -3573,12 +3608,16 @@
<&gcc GCC_USB30_PRIM_MASTER_CLK>;
assigned-clock-rates = <19200000>, <200000000>;
- interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
- <&pdc 6 IRQ_TYPE_LEVEL_HIGH>,
+ interrupts-extended = <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <&pdc 9 IRQ_TYPE_EDGE_BOTH>,
<&pdc 8 IRQ_TYPE_EDGE_BOTH>,
- <&pdc 9 IRQ_TYPE_EDGE_BOTH>;
- interrupt-names = "hs_phy_irq", "ss_phy_irq",
- "dm_hs_phy_irq", "dp_hs_phy_irq";
+ <&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>;
@@ -3645,12 +3684,16 @@
<&gcc GCC_USB30_SEC_MASTER_CLK>;
assigned-clock-rates = <19200000>, <200000000>;
- interrupts-extended = <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
- <&pdc 7 IRQ_TYPE_LEVEL_HIGH>,
+ interrupts-extended = <&intc GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+ <&pdc 11 IRQ_TYPE_EDGE_BOTH>,
<&pdc 10 IRQ_TYPE_EDGE_BOTH>,
- <&pdc 11 IRQ_TYPE_EDGE_BOTH>;
- interrupt-names = "hs_phy_irq", "ss_phy_irq",
- "dm_hs_phy_irq", "dp_hs_phy_irq";
+ <&pdc 7 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_SEC_GDSC>;
@@ -5067,7 +5110,7 @@
hysteresis = <2000>;
type = "hot";
};
- cluster0_crit: cluster0_crit {
+ cluster0_crit: cluster0-crit {
temperature = <110000>;
hysteresis = <2000>;
type = "critical";
@@ -5087,7 +5130,7 @@
hysteresis = <2000>;
type = "hot";
};
- cluster1_crit: cluster1_crit {
+ cluster1_crit: cluster1-crit {
temperature = <110000>;
hysteresis = <2000>;
type = "critical";
@@ -5101,8 +5144,15 @@
thermal-sensors = <&tsens0 15>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu_top_alert0>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
- gpu1_alert0: trip-point0 {
+ gpu_top_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <2000>;
type = "hot";
@@ -5281,8 +5331,15 @@
thermal-sensors = <&tsens1 11>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu_bottom_alert0>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
- gpu2_alert0: trip-point0 {
+ gpu_bottom_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <2000>;
type = "hot";
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 946365f15a59..6f54f50a70b0 100644
--- a/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: BSD-3-Clause
/*
- * Copyright (c) 2022, 2023 Jianhua Lu <lujianhua000@gmail.com>
+ * Copyright (c) 2022-2024 Jianhua Lu <lujianhua000@gmail.com>
*/
#include <dt-bindings/arm/qcom,ids.h>
@@ -551,6 +551,7 @@
vddio-supply = <&vreg_l14a_1p88>;
reset-gpios = <&tlmm 75 GPIO_ACTIVE_LOW>;
backlight = <&backlight>;
+ rotation = <90>;
status = "disabled";
diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi
index 760501c1301a..39bd8f0eba1e 100644
--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
@@ -975,7 +975,7 @@
#address-cells = <1>;
#size-cells = <1>;
- gpu_speed_bin: gpu_speed_bin@19b {
+ gpu_speed_bin: gpu-speed-bin@19b {
reg = <0x19b 0x1>;
bits = <5 3>;
};
@@ -2152,8 +2152,14 @@
<GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "msi0", "msi1", "msi2", "msi3",
- "msi4", "msi5", "msi6", "msi7";
+ interrupt-names = "msi0",
+ "msi1",
+ "msi2",
+ "msi3",
+ "msi4",
+ "msi5",
+ "msi6",
+ "msi7";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0x7>;
interrupt-map = <0 0 0 1 &intc 0 149 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
@@ -2248,8 +2254,22 @@
ranges = <0x01000000 0x0 0x00000000 0x0 0x40200000 0x0 0x100000>,
<0x02000000 0x0 0x40300000 0x0 0x40300000 0x0 0x1fd00000>;
- interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "msi";
+ interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi0",
+ "msi1",
+ "msi2",
+ "msi3",
+ "msi4",
+ "msi5",
+ "msi6",
+ "msi7";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0x7>;
interrupt-map = <0 0 0 1 &intc 0 434 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
@@ -2349,8 +2369,22 @@
ranges = <0x01000000 0x0 0x00000000 0x0 0x64200000 0x0 0x100000>,
<0x02000000 0x0 0x64300000 0x0 0x64300000 0x0 0x3d00000>;
- interrupts = <GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "msi";
+ interrupts = <GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 278 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 288 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 289 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi0",
+ "msi1",
+ "msi2",
+ "msi3",
+ "msi4",
+ "msi5",
+ "msi6",
+ "msi7";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0x7>;
interrupt-map = <0 0 0 1 &intc 0 290 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
@@ -2506,10 +2540,12 @@
compatible = "qcom,sm8250-qmp-ufs-phy";
reg = <0 0x01d87000 0 0x1000>;
- clock-names = "ref",
- "ref_aux";
clocks = <&rpmhcc RPMH_CXO_CLK>,
- <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
+ <&gcc GCC_UFS_PHY_PHY_AUX_CLK>,
+ <&gcc GCC_UFS_1X_CLKREF_EN>;
+ clock-names = "ref",
+ "ref_aux",
+ "qref";
resets = <&ufs_mem_hc 0>;
reset-names = "ufsphy";
@@ -2888,6 +2924,7 @@
nvmem-cells = <&gpu_speed_bin>;
nvmem-cell-names = "speed_bin";
+ #cooling-cells = <2>;
status = "disabled";
@@ -4128,14 +4165,16 @@
<&gcc GCC_USB30_PRIM_MASTER_CLK>;
assigned-clock-rates = <19200000>, <200000000>;
- 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_BOTH>,
<&pdc 15 IRQ_TYPE_EDGE_BOTH>,
- <&pdc 14 IRQ_TYPE_EDGE_BOTH>;
- 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";
power-domains = <&gcc USB30_PRIM_GDSC>;
wakeup-source;
@@ -4197,14 +4236,16 @@
<&gcc GCC_USB30_SEC_MASTER_CLK>;
assigned-clock-rates = <19200000>, <200000000>;
- interrupts-extended = <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
- <&pdc 16 IRQ_TYPE_LEVEL_HIGH>,
+ interrupts-extended = <&intc GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+ <&pdc 12 IRQ_TYPE_EDGE_BOTH>,
<&pdc 13 IRQ_TYPE_EDGE_BOTH>,
- <&pdc 12 IRQ_TYPE_EDGE_BOTH>;
- interrupt-names = "hs_phy_irq",
- "ss_phy_irq",
+ <&pdc 16 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";
power-domains = <&gcc USB30_SEC_GDSC>;
wakeup-source;
@@ -6757,7 +6798,7 @@
hysteresis = <2000>;
type = "hot";
};
- cluster0_crit: cluster0_crit {
+ cluster0_crit: cluster0-crit {
temperature = <110000>;
hysteresis = <2000>;
type = "critical";
@@ -6777,7 +6818,7 @@
hysteresis = <2000>;
type = "hot";
};
- cluster1_crit: cluster1_crit {
+ cluster1_crit: cluster1-crit {
temperature = <110000>;
hysteresis = <2000>;
type = "critical";
@@ -6791,8 +6832,15 @@
thermal-sensors = <&tsens0 15>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu_top_alert0>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
- gpu1_alert0: trip-point0 {
+ gpu_top_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <2000>;
type = "hot";
@@ -6926,8 +6974,15 @@
thermal-sensors = <&tsens1 8>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu_bottom_alert0>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
- gpu2_alert0: trip-point0 {
+ gpu_bottom_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <2000>;
type = "hot";
diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi
index e78c83a897c2..a5e7dbbd8c6c 100644
--- a/arch/arm64/boot/dts/qcom/sm8350.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi
@@ -1526,8 +1526,14 @@
<GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "msi0", "msi1", "msi2", "msi3",
- "msi4", "msi5", "msi6", "msi7";
+ interrupt-names = "msi0",
+ "msi1",
+ "msi2",
+ "msi3",
+ "msi4",
+ "msi5",
+ "msi6",
+ "msi7";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0x7>;
interrupt-map = <0 0 0 1 &intc 0 149 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
@@ -1611,8 +1617,22 @@
ranges = <0x01000000 0x0 0x00000000 0x0 0x40200000 0x0 0x100000>,
<0x02000000 0x0 0x40300000 0x0 0x40300000 0x0 0x1fd00000>;
- interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "msi";
+ interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi0",
+ "msi1",
+ "msi2",
+ "msi3",
+ "msi4",
+ "msi5",
+ "msi6",
+ "msi7";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0x7>;
interrupt-map = <0 0 0 1 &intc 0 434 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
@@ -1726,10 +1746,12 @@
compatible = "qcom,sm8350-qmp-ufs-phy";
reg = <0 0x01d87000 0 0x1000>;
- clock-names = "ref",
- "ref_aux";
clocks = <&rpmhcc RPMH_CXO_CLK>,
- <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
+ <&gcc GCC_UFS_PHY_PHY_AUX_CLK>,
+ <&gcc GCC_UFS_1_CLKREF_EN>;
+ clock-names = "ref",
+ "ref_aux",
+ "qref";
resets = <&ufs_mem_hc 0>;
reset-names = "ufsphy";
@@ -1847,6 +1869,7 @@
operating-points-v2 = <&gpu_opp_table>;
qcom,gmu = <&gmu>;
+ #cooling-cells = <2>;
status = "disabled";
@@ -2312,14 +2335,16 @@
<&gcc GCC_USB30_PRIM_MASTER_CLK>;
assigned-clock-rates = <19200000>, <200000000>;
- 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_BOTH>,
<&pdc 15 IRQ_TYPE_EDGE_BOTH>,
- <&pdc 14 IRQ_TYPE_EDGE_BOTH>;
- 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";
power-domains = <&gcc USB30_PRIM_GDSC>;
@@ -2385,14 +2410,16 @@
<&gcc GCC_USB30_SEC_MASTER_CLK>;
assigned-clock-rates = <19200000>, <200000000>;
- interrupts-extended = <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
- <&pdc 16 IRQ_TYPE_LEVEL_HIGH>,
+ interrupts-extended = <&intc GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+ <&pdc 12 IRQ_TYPE_EDGE_BOTH>,
<&pdc 13 IRQ_TYPE_EDGE_BOTH>,
- <&pdc 12 IRQ_TYPE_EDGE_BOTH>;
- interrupt-names = "hs_phy_irq",
- "ss_phy_irq",
+ <&pdc 16 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";
power-domains = <&gcc USB30_SEC_GDSC>;
@@ -4165,7 +4192,7 @@
hysteresis = <2000>;
type = "hot";
};
- cluster0_crit: cluster0_crit {
+ cluster0_crit: cluster0-crit {
temperature = <110000>;
hysteresis = <2000>;
type = "critical";
@@ -4185,7 +4212,7 @@
hysteresis = <2000>;
type = "hot";
};
- cluster1_crit: cluster1_crit {
+ cluster1_crit: cluster1-crit {
temperature = <110000>;
hysteresis = <2000>;
type = "critical";
@@ -4214,8 +4241,15 @@
thermal-sensors = <&tsens1 1>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu_top_alert0>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
- gpu1_alert0: trip-point0 {
+ gpu_top_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <1000>;
type = "hot";
@@ -4229,8 +4263,15 @@
thermal-sensors = <&tsens1 2>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu_bottom_alert0>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
- gpu2_alert0: trip-point0 {
+ gpu_bottom_alert0: trip-point0 {
temperature = <90000>;
hysteresis = <1000>;
type = "hot";
diff --git a/arch/arm64/boot/dts/qcom/sm8450-hdk.dts b/arch/arm64/boot/dts/qcom/sm8450-hdk.dts
index a20d5d76af35..0786cff07b89 100644
--- a/arch/arm64/boot/dts/qcom/sm8450-hdk.dts
+++ b/arch/arm64/boot/dts/qcom/sm8450-hdk.dts
@@ -938,8 +938,8 @@
"TX DMIC3", "MIC BIAS1",
"TX SWR_INPUT0", "ADC1_OUTPUT",
"TX SWR_INPUT1", "ADC2_OUTPUT",
- "TX SWR_INPUT2", "ADC3_OUTPUT",
- "TX SWR_INPUT3", "ADC4_OUTPUT";
+ "TX SWR_INPUT0", "ADC3_OUTPUT",
+ "TX SWR_INPUT1", "ADC4_OUTPUT";
wcd-playback-dai-link {
link-name = "WCD Playback";
@@ -1147,7 +1147,7 @@
};
&vamacro {
- pinctrl-0 = <&dmic01_default>, <&dmic02_default>;
+ pinctrl-0 = <&dmic01_default>, <&dmic23_default>;
pinctrl-names = "default";
vdd-micb-supply = <&vreg_s10b_1p8>;
qcom,dmic-sample-rate = <600000>;
diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi
index 01e4dfc4babd..b86be34a912b 100644
--- a/arch/arm64/boot/dts/qcom/sm8450.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi
@@ -1028,6 +1028,12 @@
pinctrl-names = "default";
pinctrl-0 = <&qup_uart20_default>;
interrupts = <GIC_SPI 587 IRQ_TYPE_LEVEL_HIGH>;
+ interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
+ &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
+ <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+ &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "qup-core",
+ "qup-config";
status = "disabled";
};
@@ -1420,6 +1426,12 @@
pinctrl-names = "default";
pinctrl-0 = <&qup_uart7_tx>, <&qup_uart7_rx>;
interrupts = <GIC_SPI 608 IRQ_TYPE_LEVEL_HIGH>;
+ interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
+ &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
+ <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+ &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "qup-core",
+ "qup-config";
status = "disabled";
};
};
@@ -1772,8 +1784,22 @@
msi-map = <0x0 &gic_its 0x5981 0x1>,
<0x100 &gic_its 0x5980 0x1>;
msi-map-mask = <0xff00>;
- interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "msi";
+ interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi0",
+ "msi1",
+ "msi2",
+ "msi3",
+ "msi4",
+ "msi5",
+ "msi6",
+ "msi7";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0x7>;
interrupt-map = <0 0 0 1 &intc 0 0 0 149 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
@@ -1881,8 +1907,22 @@
msi-map = <0x0 &gic_its 0x5a01 0x1>,
<0x100 &gic_its 0x5a00 0x1>;
msi-map-mask = <0xff00>;
- interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "msi";
+ interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi0",
+ "msi1",
+ "msi2",
+ "msi3",
+ "msi4",
+ "msi5",
+ "msi6",
+ "msi7";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0x7>;
interrupt-map = <0 0 0 1 &intc 0 0 0 434 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
@@ -2038,6 +2078,7 @@
operating-points-v2 = <&gpu_opp_table>;
qcom,gmu = <&gmu>;
+ #cooling-cells = <2>;
status = "disabled";
@@ -3934,7 +3975,7 @@
};
};
- dmic02_default: dmic02-default-state {
+ dmic23_default: dmic23-default-state {
clk-pins {
pins = "gpio8";
function = "dmic2_clk";
@@ -4485,13 +4526,15 @@
assigned-clock-rates = <19200000>, <200000000>;
interrupts-extended = <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
- <&pdc 17 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <&pdc 14 IRQ_TYPE_EDGE_BOTH>,
<&pdc 15 IRQ_TYPE_EDGE_BOTH>,
- <&pdc 14 IRQ_TYPE_EDGE_BOTH>;
- 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";
power-domains = <&gcc USB30_PRIM_GDSC>;
@@ -4890,6 +4933,13 @@
polling-delay = <0>;
thermal-sensors = <&tsens0 14>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu_top_alert0>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
thermal-engine-config {
temperature = <125000>;
@@ -4909,7 +4959,7 @@
type = "passive";
};
- gpu0_tj_cfg: tj-cfg {
+ gpu_top_alert0: trip-point0 {
temperature = <95000>;
hysteresis = <5000>;
type = "passive";
@@ -4922,6 +4972,13 @@
polling-delay = <0>;
thermal-sensors = <&tsens0 15>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu_bottom_alert0>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
thermal-engine-config {
temperature = <125000>;
@@ -4941,7 +4998,7 @@
type = "passive";
};
- gpu1_tj_cfg: tj-cfg {
+ gpu_bottom_alert0: trip-point0 {
temperature = <95000>;
hysteresis = <5000>;
type = "passive";
diff --git a/arch/arm64/boot/dts/qcom/sm8550-hdk.dts b/arch/arm64/boot/dts/qcom/sm8550-hdk.dts
new file mode 100644
index 000000000000..12d60a0ee095
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sm8550-hdk.dts
@@ -0,0 +1,1306 @@
+// 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 "sm8550.dtsi"
+#include "pm8010.dtsi"
+#include "pm8550.dtsi"
+#include "pm8550b.dtsi"
+#define PMK8550VE_SID 5
+#include "pm8550ve.dtsi"
+#include "pm8550vs.dtsi"
+#include "pmk8550.dtsi"
+#include "pmr735d_a.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SM8550 HDK";
+ compatible = "qcom,sm8550-hdk", "qcom,sm8550";
+ chassis-type = "embedded";
+
+ aliases {
+ serial0 = &uart7;
+ serial1 = &uart14;
+ };
+
+ 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 108 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";
+ };
+
+ 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 = <&tlmm 159 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "bluetooth-power";
+ default-state = "off";
+ };
+
+ led-1 {
+ function = LED_FUNCTION_INDICATOR;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&tlmm 160 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ panic-indicator;
+ };
+
+ led-2 {
+ function = LED_FUNCTION_WLAN;
+ color = <LED_COLOR_ID_ORANGE>;
+ gpios = <&tlmm 162 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "phy0tx";
+ default-state = "off";
+ };
+ };
+
+ 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 = <&usb_dp_qmpphy_out>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ pmic_glink_sbu: endpoint {
+ remote-endpoint = <&fsa4480_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 152 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 6 GPIO_ACTIVE_HIGH>;
+
+ enable-active-high;
+ };
+
+ 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>;
+ };
+
+ sound {
+ compatible = "qcom,sm8550-sndcard", "qcom,sm8450-sndcard";
+ model = "SM8550-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_INPUT1", "ADC4_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 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>;
+ };
+ };
+
+ va-dai-link {
+ link-name = "VA Capture";
+
+ cpu {
+ sound-dai = <&q6apmbedai TX_CODEC_DMA_TX_3>;
+ };
+
+ codec {
+ sound-dai = <&lpass_vamacro 0>;
+ };
+
+ platform {
+ sound-dai = <&q6apm>;
+ };
+ };
+ };
+};
+
+&apps_rsc {
+ regulators-0 {
+ compatible = "qcom,pm8550-rpmh-regulators";
+
+ vdd-bob1-supply = <&vph_pwr>;
+ vdd-bob2-supply = <&vph_pwr>;
+ 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>;
+
+ 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>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ 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>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ 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_s4g_1p25>;
+ vdd-l2-supply = <&vreg_s4e_0p95>;
+ vdd-l3-supply = <&vreg_s4e_0p95>;
+
+ qcom,pmic-id = "c";
+
+ vreg_l3c_0p9: ldo3 {
+ regulator-name = "vreg_l3c_0p9";
+ 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-2 {
+ compatible = "qcom,pm8550vs-rpmh-regulators";
+
+ vdd-l1-supply = <&vreg_s4e_0p95>;
+ vdd-l2-supply = <&vreg_s4e_0p95>;
+ vdd-l3-supply = <&vreg_s4e_0p95>;
+
+ 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>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+
+ /* ldo2 supplies SM8550 VDD_LPI_MX */
+ };
+
+ regulators-3 {
+ compatible = "qcom,pm8550vs-rpmh-regulators";
+
+ vdd-l1-supply = <&vreg_s4e_0p95>;
+ vdd-l2-supply = <&vreg_s4e_0p95>;
+ vdd-l3-supply = <&vreg_s4g_1p25>;
+ vdd-s4-supply = <&vph_pwr>;
+ vdd-s5-supply = <&vph_pwr>;
+
+ qcom,pmic-id = "e";
+
+ 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 = <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>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ 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>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ 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>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-4 {
+ compatible = "qcom,pm8550ve-rpmh-regulators";
+
+ vdd-l1-supply = <&vreg_s4e_0p95>;
+ vdd-l2-supply = <&vreg_s4e_0p95>;
+ vdd-l3-supply = <&vreg_s4e_0p95>;
+ vdd-s4-supply = <&vph_pwr>;
+
+ 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>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ 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>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ 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>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ RPMH_REGULATOR_MODE_HPM>;
+ };
+ };
+
+ regulators-5 {
+ compatible = "qcom,pm8550vs-rpmh-regulators";
+
+ vdd-l1-supply = <&vreg_s4g_1p25>;
+ vdd-l2-supply = <&vreg_s4g_1p25>;
+ vdd-l3-supply = <&vreg_s4g_1p25>;
+ 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 = "g";
+
+ 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 = <800000>;
+ regulator-max-microvolt = <1000000>;
+ 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 = <1200000>;
+ regulator-max-microvolt = <1352000>;
+ 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 = <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_l3g_1p2: ldo3 {
+ regulator-name = "vreg_l3g_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-6 {
+ compatible = "qcom,pm8010-rpmh-regulators";
+
+ vdd-l1-l2-supply = <&vreg_s4g_1p25>;
+ vdd-l3-l4-supply = <&vreg_bob2>;
+ vdd-l5-supply = <&vreg_s6g_1p86>;
+ vdd-l6-supply = <&vreg_s6g_1p86>;
+ vdd-l7-supply = <&vreg_bob1>;
+
+ 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>;
+ 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_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";
+
+ vdd-l1-l2-supply = <&vreg_s4g_1p25>;
+ vdd-l3-l4-supply = <&vreg_bob2>;
+ vdd-l5-supply = <&vreg_s6g_1p86>;
+ vdd-l6-supply = <&vreg_bob1>;
+ vdd-l7-supply = <&vreg_bob1>;
+
+ 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>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ 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>;
+ regulator-allow-set-load;
+ regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+ 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>;
+ };
+ };
+};
+
+&i2c0 {
+ clock-frequency = <400000>;
+ status = "okay";
+
+ lt9611_codec: hdmi-bridge@2b {
+ compatible = "lontium,lt9611uxc";
+ reg = <0x2b>;
+
+ interrupts-extended = <&tlmm 8 IRQ_TYPE_EDGE_FALLING>;
+
+ reset-gpios = <&tlmm 7 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>;
+ };
+ };
+ };
+ };
+};
+
+&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>;
+ };
+ };
+ };
+};
+
+&i2c_master_hub_0 {
+ status = "okay";
+};
+
+&ipa {
+ qcom,gsi-loader = "self";
+ memory-region = <&ipa_fw_mem>;
+ firmware-name = "qcom/sm8550/ipa_fws.mbn";
+ status = "okay";
+};
+
+&gpi_dma1 {
+ status = "okay";
+};
+
+&gpu {
+ status = "okay";
+
+ zap-shader {
+ firmware-name = "qcom/sm8550/a740_zap.mbn";
+ };
+};
+
+&lpass_tlmm {
+ spkr_1_sd_n_active: spkr-1-sd-n-active-state {
+ pins = "gpio17";
+ function = "gpio";
+ drive-strength = <16>;
+ bias-disable;
+ output-low;
+ };
+
+ spkr_2_sd_n_active: spkr-2-sd-n-active-state {
+ pins = "gpio18";
+ function = "gpio";
+ drive-strength = <16>;
+ bias-disable;
+ output-low;
+ };
+};
+
+&mdss {
+ status = "okay";
+};
+
+&mdss_dsi0 {
+ vdda-supply = <&vreg_l3e_1p2>;
+ status = "okay";
+};
+
+&mdss_dsi0_out {
+ remote-endpoint = <&lt9611_a>;
+ data-lanes = <0 1 2 3>;
+};
+
+&mdss_dsi0_phy {
+ vdds-supply = <&vreg_l1e_0p88>;
+ status = "okay";
+};
+
+&mdss_dp0 {
+ status = "okay";
+};
+
+&mdss_dp0_out {
+ remote-endpoint = <&usb_dp_qmpphy_dp_in>;
+ 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";
+};
+
+&pcie0_phy {
+ vdda-phy-supply = <&vreg_l1e_0p88>;
+ vdda-pll-supply = <&vreg_l3e_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_l3c_0p9>;
+ vdda-pll-supply = <&vreg_l3e_1p2>;
+ vdda-qref-supply = <&vreg_l1e_0p88>;
+
+ status = "okay";
+};
+
+&pcie_1_phy_aux_clk {
+ clock-frequency = <1000>;
+};
+
+&pm8550_gpios {
+ sdc2_card_det_n: sdc2-card-det-state {
+ pins = "gpio12";
+ function = "normal";
+ input-enable;
+ output-disable;
+ bias-pull-up;
+ power-source = <1>; /* 1.8 V */
+ };
+
+ volume_up_n: volume-up-n-state {
+ pins = "gpio6";
+ function = "normal";
+ power-source = <1>;
+ bias-pull-up;
+ input-enable;
+ };
+};
+
+/* The RGB signals are routed to 3 separate LEDs on the HDK8550 */
+&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>;
+};
+
+&pon_pwrkey {
+ status = "okay";
+};
+
+&pon_resin {
+ linux,code = <KEY_VOLUMEDOWN>;
+
+ status = "okay";
+};
+
+&qupv3_id_0 {
+ status = "okay";
+};
+
+&qupv3_id_1 {
+ status = "okay";
+};
+
+&remoteproc_adsp {
+ firmware-name = "qcom/sm8550/adsp.mbn",
+ "qcom/sm8550/adsp_dtb.mbn";
+ status = "okay";
+};
+
+&remoteproc_cdsp {
+ firmware-name = "qcom/sm8550/cdsp.mbn",
+ "qcom/sm8550/cdsp_dtb.mbn";
+ status = "okay";
+};
+
+&remoteproc_mpss {
+ firmware-name = "qcom/sm8550/modem.mbn",
+ "qcom/sm8550/modem_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 = <&vreg_l9b_2p9>;
+ vqmmc-supply = <&vreg_l8b_1p8>;
+
+ bus-width = <4>;
+ no-sdio;
+ no-mmc;
+
+ 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 17 GPIO_ACTIVE_LOW>;
+
+ vdd-1p8-supply = <&vreg_l15b_1p8>;
+ vdd-io-supply = <&vreg_l15b_1p8>;
+
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "SpkrLeft";
+ };
+
+ /* 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 = <&lpass_tlmm 18 GPIO_ACTIVE_LOW>;
+
+ vdd-1p8-supply = <&vreg_l15b_1p8>;
+ vdd-io-supply = <&vreg_l15b_1p8>;
+
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "SpkrRight";
+ };
+};
+
+&swr1 {
+ status = "okay";
+
+ /* WCD9385 RX */
+ wcd_rx: codec@0,4 {
+ compatible = "sdw20217010d00";
+ reg = <0 4>;
+
+ /*
+ * WCD9385 RX Port 1 (HPH_L/R) <=> SWR1 Port 1 (HPH_L/R)
+ * WCD9385 RX Port 2 (CLSH) <=> SWR1 Port 2 (CLSH)
+ * WCD9385 RX Port 3 (COMP_L/R) <=> SWR1 Port 3 (COMP_L/R)
+ * WCD9385 RX Port 4 (LO) <=> SWR1 Port 4 (LO)
+ * WCD9385 RX Port 5 (DSD_L/R) <=> SWR1 Port 5 (DSD_L/R)
+ */
+ qcom,rx-port-mapping = <1 2 3 4 5>;
+ };
+};
+
+&swr2 {
+ status = "okay";
+
+ /* WCD9385 TX */
+ wcd_tx: codec@0,3 {
+ compatible = "sdw20217010d00";
+ reg = <0 3>;
+
+ /*
+ * WCD9385 TX Port 1 (ADC1,2) <=> SWR2 Port 2 (TX SWR_INPUT 0,1,2,3)
+ * WCD9385 TX Port 2 (ADC3,4) <=> SWR2 Port 2 (TX SWR_INPUT 0,1,2,3)
+ * WCD9385 TX Port 3 (DMIC0,1,2,3 & MBHC) <=> SWR2 Port 3 (TX SWR_INPUT 4,5,6,7)
+ * WCD9385 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>;
+
+ bt_default: bt-default-state {
+ bt-en-pins {
+ pins = "gpio81";
+ function = "gpio";
+ drive-strength = <16>;
+ bias-disable;
+ };
+
+ sw-ctrl-pins {
+ pins = "gpio82";
+ function = "gpio";
+ bias-pull-down;
+ };
+ };
+
+ lt9611_irq_pin: lt9611-irq-state {
+ pins = "gpio8";
+ function = "gpio";
+ bias-disable;
+ };
+
+ lt9611_rst_pin: lt9611-rst-state {
+ pins = "gpio7";
+ function = "gpio";
+ output-high;
+ };
+
+ wcd_default: wcd-reset-n-active-state {
+ pins = "gpio108";
+ function = "gpio";
+ drive-strength = <16>;
+ bias-disable;
+ output-low;
+ };
+};
+
+&uart7 {
+ status = "okay";
+};
+
+&uart14 {
+ status = "okay";
+
+ bluetooth {
+ compatible = "qcom,wcn7850-bt";
+
+ vddio-supply = <&vreg_l15b_1p8>;
+ vddaon-supply = <&vreg_s4e_0p95>;
+ vdddig-supply = <&vreg_s4e_0p95>;
+ vddrfa0p8-supply = <&vreg_s4e_0p95>;
+ vddrfa1p2-supply = <&vreg_s4g_1p25>;
+ vddrfa1p9-supply = <&vreg_s6g_1p86>;
+
+ max-speed = <3200000>;
+
+ enable-gpios = <&tlmm 81 GPIO_ACTIVE_HIGH>;
+ swctrl-gpios = <&tlmm 82 GPIO_ACTIVE_HIGH>;
+
+ pinctrl-0 = <&bt_default>;
+ pinctrl-names = "default";
+ };
+};
+
+&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 {
+ 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>;
+
+ phys = <&pm8550b_eusb2_repeater>;
+
+ status = "okay";
+};
+
+&usb_dp_qmpphy {
+ 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 c1135ad5fa69..3d4ad5aac70f 100644
--- a/arch/arm64/boot/dts/qcom/sm8550-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/sm8550-mtp.dts
@@ -106,14 +106,21 @@
"SpkrRight IN", "WSA_SPK2 OUT",
"IN1_HPHL", "HPHL_OUT",
"IN2_HPHR", "HPHR_OUT",
+ "AMIC1", "MIC BIAS1",
"AMIC2", "MIC BIAS2",
+ "AMIC3", "MIC BIAS3",
+ "AMIC4", "MIC BIAS3",
+ "AMIC5", "MIC BIAS4",
"VA DMIC0", "MIC BIAS1",
"VA DMIC1", "MIC BIAS1",
"VA DMIC2", "MIC BIAS3",
"TX DMIC0", "MIC BIAS1",
"TX DMIC1", "MIC BIAS2",
"TX DMIC2", "MIC BIAS3",
- "TX SWR_ADC1", "ADC2_OUTPUT";
+ "TX SWR_INPUT0", "ADC1_OUTPUT",
+ "TX SWR_INPUT1", "ADC2_OUTPUT",
+ "TX SWR_INPUT0", "ADC3_OUTPUT",
+ "TX SWR_INPUT1", "ADC4_OUTPUT";
wcd-playback-dai-link {
link-name = "WCD Playback";
@@ -874,7 +881,7 @@
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>;
};
};
diff --git a/arch/arm64/boot/dts/qcom/sm8550-qrd.dts b/arch/arm64/boot/dts/qcom/sm8550-qrd.dts
index d401d63e5c4d..92f015017418 100644
--- a/arch/arm64/boot/dts/qcom/sm8550-qrd.dts
+++ b/arch/arm64/boot/dts/qcom/sm8550-qrd.dts
@@ -124,14 +124,21 @@
"SpkrRight IN", "WSA_SPK2 OUT",
"IN1_HPHL", "HPHL_OUT",
"IN2_HPHR", "HPHR_OUT",
+ "AMIC1", "MIC BIAS1",
"AMIC2", "MIC BIAS2",
+ "AMIC3", "MIC BIAS3",
+ "AMIC4", "MIC BIAS3",
+ "AMIC5", "MIC BIAS4",
"VA DMIC0", "MIC BIAS1",
"VA DMIC1", "MIC BIAS1",
"VA DMIC2", "MIC BIAS3",
"TX DMIC0", "MIC BIAS1",
"TX DMIC1", "MIC BIAS2",
"TX DMIC2", "MIC BIAS3",
- "TX SWR_ADC1", "ADC2_OUTPUT";
+ "TX SWR_INPUT0", "ADC1_OUTPUT",
+ "TX SWR_INPUT1", "ADC2_OUTPUT",
+ "TX SWR_INPUT0", "ADC3_OUTPUT",
+ "TX SWR_INPUT1", "ADC4_OUTPUT";
wcd-playback-dai-link {
link-name = "WCD Playback";
@@ -724,6 +731,10 @@
<&usb_dp_qmpphy QMP_USB43DP_USB3_PIPE_CLK>;
};
+&gpi_dma1 {
+ status = "okay";
+};
+
&gpu {
status = "okay";
@@ -960,6 +971,30 @@
};
};
+&spi4 {
+ status = "okay";
+
+ touchscreen@0 {
+ compatible = "goodix,gt9916";
+ reg = <0>;
+
+ interrupt-parent = <&tlmm>;
+ interrupts = <25 IRQ_TYPE_LEVEL_LOW>;
+
+ reset-gpios = <&tlmm 24 GPIO_ACTIVE_LOW>;
+
+ avdd-supply = <&vreg_l14b_3p2>;
+
+ spi-max-frequency = <1000000>;
+
+ touchscreen-size-x = <1080>;
+ touchscreen-size-y = <2400>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&ts_irq>, <&ts_reset>;
+ };
+};
+
&swr1 {
status = "okay";
@@ -978,7 +1013,7 @@
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>;
};
};
@@ -1028,6 +1063,20 @@
bias-pull-down;
};
+ ts_irq: ts-irq-state {
+ pins = "gpio25";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-pull-up;
+ };
+
+ ts_reset: ts-reset-state {
+ pins = "gpio24";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-pull-up;
+ };
+
wcd_default: wcd-reset-n-active-state {
pins = "gpio108";
function = "gpio";
diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi
index ee1ba5a8c8fc..3904348075f6 100644
--- a/arch/arm64/boot/dts/qcom/sm8550.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi
@@ -1713,9 +1713,22 @@
linux,pci-domain = <0>;
num-lanes = <2>;
- interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "msi";
-
+ interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi0",
+ "msi1",
+ "msi2",
+ "msi3",
+ "msi4",
+ "msi5",
+ "msi6",
+ "msi7";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0x7>;
interrupt-map = <0 0 0 1 &intc 0 0 0 149 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
@@ -1742,6 +1755,9 @@
<&gem_noc MASTER_APPSS_PROC 0 &cnoc_main SLAVE_PCIE_0 0>;
interconnect-names = "pcie-mem", "cpu-pcie";
+ /* Entries are reversed due to the unusual ITS DeviceID encoding */
+ msi-map = <0x0 &gic_its 0x1401 0x1>,
+ <0x100 &gic_its 0x1400 0x1>;
iommu-map = <0x0 &apps_smmu 0x1400 0x1>,
<0x100 &apps_smmu 0x1401 0x1>;
@@ -1804,9 +1820,22 @@
linux,pci-domain = <1>;
num-lanes = <2>;
- interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "msi";
-
+ interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi0",
+ "msi1",
+ "msi2",
+ "msi3",
+ "msi4",
+ "msi5",
+ "msi6",
+ "msi7";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0x7>;
interrupt-map = <0 0 0 1 &intc 0 0 0 434 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
@@ -1838,6 +1867,9 @@
<&gem_noc MASTER_APPSS_PROC 0 &cnoc_main SLAVE_PCIE_1 0>;
interconnect-names = "pcie-mem", "cpu-pcie";
+ /* Entries are reversed due to the unusual ITS DeviceID encoding */
+ msi-map = <0x0 &gic_its 0x1481 0x1>,
+ <0x100 &gic_its 0x1480 0x1>;
iommu-map = <0x0 &apps_smmu 0x1480 0x1>,
<0x100 &apps_smmu 0x1481 0x1>;
@@ -1907,9 +1939,12 @@
ufs_mem_phy: phy@1d80000 {
compatible = "qcom,sm8550-qmp-ufs-phy";
reg = <0x0 0x01d80000 0x0 0x2000>;
- clocks = <&tcsr TCSR_UFS_CLKREF_EN>,
- <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
- clock-names = "ref", "ref_aux";
+ clocks = <&rpmhcc RPMH_CXO_CLK>,
+ <&gcc GCC_UFS_PHY_PHY_AUX_CLK>,
+ <&tcsr TCSR_UFS_CLKREF_EN>;
+ clock-names = "ref",
+ "ref_aux",
+ "qref";
power-domains = <&gcc UFS_MEM_PHY_GDSC>;
@@ -1940,6 +1975,7 @@
iommus = <&apps_smmu 0x60 0x0>;
dma-coherent;
+ operating-points-v2 = <&ufs_opp_table>;
interconnects = <&aggre1_noc MASTER_UFS_MEM 0 &mc_virt SLAVE_EBI1 0>,
<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_UFS_MEM_CFG 0>;
@@ -1960,18 +1996,49 @@
<&gcc GCC_UFS_PHY_TX_SYMBOL_0_CLK>,
<&gcc GCC_UFS_PHY_RX_SYMBOL_0_CLK>,
<&gcc GCC_UFS_PHY_RX_SYMBOL_1_CLK>;
- freq-table-hz =
- <75000000 300000000>,
- <0 0>,
- <0 0>,
- <75000000 300000000>,
- <100000000 403000000>,
- <0 0>,
- <0 0>,
- <0 0>;
qcom,ice = <&ice>;
status = "disabled";
+
+ ufs_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-75000000 {
+ opp-hz = /bits/ 64 <75000000>,
+ /bits/ 64 <0>,
+ /bits/ 64 <0>,
+ /bits/ 64 <75000000>,
+ /bits/ 64 <0>,
+ /bits/ 64 <0>,
+ /bits/ 64 <0>,
+ /bits/ 64 <0>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ };
+
+ opp-150000000 {
+ opp-hz = /bits/ 64 <150000000>,
+ /bits/ 64 <0>,
+ /bits/ 64 <0>,
+ /bits/ 64 <150000000>,
+ /bits/ 64 <0>,
+ /bits/ 64 <0>,
+ /bits/ 64 <0>,
+ /bits/ 64 <0>;
+ required-opps = <&rpmhpd_opp_svs>;
+ };
+
+ opp-300000000 {
+ opp-hz = /bits/ 64 <300000000>,
+ /bits/ 64 <0>,
+ /bits/ 64 <0>,
+ /bits/ 64 <300000000>,
+ /bits/ 64 <0>,
+ /bits/ 64 <0>,
+ /bits/ 64 <0>,
+ /bits/ 64 <0>;
+ required-opps = <&rpmhpd_opp_nom>;
+ };
+ };
};
ice: crypto@1d88000 {
@@ -2012,6 +2079,7 @@
operating-points-v2 = <&gpu_opp_table>;
qcom,gmu = <&gmu>;
+ #cooling-cells = <2>;
status = "disabled";
@@ -2507,7 +2575,7 @@
};
};
- dmic02_default: dmic02-default-state {
+ dmic23_default: dmic23-default-state {
clk-pins {
pins = "gpio8";
function = "dmic2_clk";
@@ -3133,13 +3201,15 @@
assigned-clock-rates = <19200000>, <200000000>;
interrupts-extended = <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
- <&pdc 17 IRQ_TYPE_LEVEL_HIGH>,
+ <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+ <&pdc 14 IRQ_TYPE_EDGE_BOTH>,
<&pdc 15 IRQ_TYPE_EDGE_BOTH>,
- <&pdc 14 IRQ_TYPE_EDGE_BOTH>;
- 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";
power-domains = <&gcc USB30_PRIM_GDSC>;
required-opps = <&rpmhpd_opp_nom>;
@@ -3248,7 +3318,7 @@
spmi_bus: spmi@c400000 {
compatible = "qcom,spmi-pmic-arb";
reg = <0 0x0c400000 0 0x3000>,
- <0 0x0c500000 0 0x4000000>,
+ <0 0x0c500000 0 0x400000>,
<0 0x0c440000 0 0x80000>,
<0 0x0c4c0000 0 0x20000>,
<0 0x0c42d000 0 0x4000>;
@@ -4254,6 +4324,7 @@
reg = <3>;
iommus = <&apps_smmu 0x1003 0x80>,
<&apps_smmu 0x1063 0x0>;
+ dma-coherent;
};
compute-cb@4 {
@@ -4261,6 +4332,7 @@
reg = <4>;
iommus = <&apps_smmu 0x1004 0x80>,
<&apps_smmu 0x1064 0x0>;
+ dma-coherent;
};
compute-cb@5 {
@@ -4268,6 +4340,7 @@
reg = <5>;
iommus = <&apps_smmu 0x1005 0x80>,
<&apps_smmu 0x1065 0x0>;
+ dma-coherent;
};
compute-cb@6 {
@@ -4275,6 +4348,7 @@
reg = <6>;
iommus = <&apps_smmu 0x1006 0x80>,
<&apps_smmu 0x1066 0x0>;
+ dma-coherent;
};
compute-cb@7 {
@@ -4282,6 +4356,7 @@
reg = <7>;
iommus = <&apps_smmu 0x1007 0x80>,
<&apps_smmu 0x1067 0x0>;
+ dma-coherent;
};
};
@@ -4388,6 +4463,7 @@
iommus = <&apps_smmu 0x1961 0x0>,
<&apps_smmu 0x0c01 0x20>,
<&apps_smmu 0x19c1 0x10>;
+ dma-coherent;
};
compute-cb@2 {
@@ -4396,6 +4472,7 @@
iommus = <&apps_smmu 0x1962 0x0>,
<&apps_smmu 0x0c02 0x20>,
<&apps_smmu 0x19c2 0x10>;
+ dma-coherent;
};
compute-cb@3 {
@@ -4404,6 +4481,7 @@
iommus = <&apps_smmu 0x1963 0x0>,
<&apps_smmu 0x0c03 0x20>,
<&apps_smmu 0x19c3 0x10>;
+ dma-coherent;
};
compute-cb@4 {
@@ -4412,6 +4490,7 @@
iommus = <&apps_smmu 0x1964 0x0>,
<&apps_smmu 0x0c04 0x20>,
<&apps_smmu 0x19c4 0x10>;
+ dma-coherent;
};
compute-cb@5 {
@@ -4420,6 +4499,7 @@
iommus = <&apps_smmu 0x1965 0x0>,
<&apps_smmu 0x0c05 0x20>,
<&apps_smmu 0x19c5 0x10>;
+ dma-coherent;
};
compute-cb@6 {
@@ -4428,6 +4508,7 @@
iommus = <&apps_smmu 0x1966 0x0>,
<&apps_smmu 0x0c06 0x20>,
<&apps_smmu 0x19c6 0x10>;
+ dma-coherent;
};
compute-cb@7 {
@@ -4436,6 +4517,7 @@
iommus = <&apps_smmu 0x1967 0x0>,
<&apps_smmu 0x0c07 0x20>,
<&apps_smmu 0x19c7 0x10>;
+ dma-coherent;
};
compute-cb@8 {
@@ -4444,6 +4526,7 @@
iommus = <&apps_smmu 0x1968 0x0>,
<&apps_smmu 0x0c08 0x20>,
<&apps_smmu 0x19c8 0x10>;
+ dma-coherent;
};
/* note: secure cb9 in downstream */
@@ -5304,6 +5387,13 @@
polling-delay = <0>;
thermal-sensors = <&tsens2 1>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu0_junction_config>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
thermal-engine-config {
temperature = <125000>;
@@ -5336,6 +5426,13 @@
polling-delay = <0>;
thermal-sensors = <&tsens2 2>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu1_junction_config>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
thermal-engine-config {
temperature = <125000>;
@@ -5368,6 +5465,13 @@
polling-delay = <0>;
thermal-sensors = <&tsens2 3>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu2_junction_config>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
thermal-engine-config {
temperature = <125000>;
@@ -5400,6 +5504,13 @@
polling-delay = <0>;
thermal-sensors = <&tsens2 4>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu3_junction_config>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
thermal-engine-config {
temperature = <125000>;
@@ -5432,6 +5543,13 @@
polling-delay = <0>;
thermal-sensors = <&tsens2 5>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu4_junction_config>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
thermal-engine-config {
temperature = <125000>;
@@ -5464,6 +5582,13 @@
polling-delay = <0>;
thermal-sensors = <&tsens2 6>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu5_junction_config>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
thermal-engine-config {
temperature = <125000>;
@@ -5496,6 +5621,13 @@
polling-delay = <0>;
thermal-sensors = <&tsens2 7>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu6_junction_config>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
thermal-engine-config {
temperature = <125000>;
@@ -5528,6 +5660,13 @@
polling-delay = <0>;
thermal-sensors = <&tsens2 8>;
+ cooling-maps {
+ map0 {
+ trip = <&gpu7_junction_config>;
+ cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
trips {
thermal-engine-config {
temperature = <125000>;
diff --git a/arch/arm64/boot/dts/qcom/sm8650-mtp.dts b/arch/arm64/boot/dts/qcom/sm8650-mtp.dts
index be133a3d5cbe..4450273f9667 100644
--- a/arch/arm64/boot/dts/qcom/sm8650-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/sm8650-mtp.dts
@@ -66,6 +66,29 @@
};
};
+ sound {
+ compatible = "qcom,sm8650-sndcard", "qcom,sm8450-sndcard";
+ model = "SM8650-MTP";
+ audio-routing = "SpkrLeft IN", "WSA_SPK1 OUT",
+ "SpkrRight IN", "WSA_SPK2 OUT";
+
+ 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";
@@ -428,6 +451,138 @@
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 {
diff --git a/arch/arm64/boot/dts/qcom/sm8650-qrd.dts b/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
index b9151c2ddf2e..b07cac2e5bc8 100644
--- a/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
+++ b/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
@@ -77,9 +77,83 @@
reg = <1>;
pmic_glink_ss_in: endpoint {
- remote-endpoint = <&usb_1_dwc3_ss>;
+ remote-endpoint = <&redriver_ss_out>;
};
};
+
+ port@2 {
+ reg = <2>;
+
+ pmic_glink_sbu: endpoint {
+ remote-endpoint = <&wcd_usbss_sbu_mux>;
+ };
+ };
+ };
+ };
+ };
+
+ sound {
+ compatible = "qcom,sm8650-sndcard", "qcom,sm8450-sndcard";
+ model = "SM8650-QRD";
+ 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",
+ "AMIC3", "MIC BIAS3",
+ "AMIC4", "MIC BIAS3",
+ "AMIC5", "MIC BIAS4",
+ "TX SWR_INPUT0", "ADC1_OUTPUT",
+ "TX SWR_INPUT1", "ADC2_OUTPUT",
+ "TX SWR_INPUT2", "ADC3_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 = <&left_spkr>, <&right_spkr>, <&swr0 0>, <&lpass_wsamacro 0>;
+ };
+
+ platform {
+ sound-dai = <&q6apm>;
};
};
};
@@ -94,6 +168,41 @@
regulator-always-on;
regulator-boot-on;
};
+
+ 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>;
+
+ mode-switch;
+ orientation-switch;
+
+ port {
+ wcd_codec_headset_in: endpoint {
+ remote-endpoint = <&wcd_usbss_headset_out>;
+ };
+ };
+ };
};
&apps_rsc {
@@ -436,6 +545,138 @@
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 {
@@ -446,6 +687,78 @@
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>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ wcd_usbss_headset_out: endpoint {
+ remote-endpoint = <&wcd_codec_headset_in>;
+ };
+ };
+ };
+ };
+};
+
+&i2c6 {
+ status = "okay";
+
+ typec-mux@1c {
+ compatible = "onnn,nb7vpq904m";
+ reg = <0x1c>;
+
+ vcc-supply = <&vreg_l15b_1p8>;
+
+ retimer-switch;
+ orientation-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>;
+ };
+ };
+ };
+ };
+};
+
&ipa {
qcom,gsi-loader = "self";
memory-region = <&ipa_fw_mem>;
@@ -453,6 +766,16 @@
status = "okay";
};
+&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";
};
@@ -495,6 +818,15 @@
status = "okay";
};
+&mdss_dp0 {
+ status = "okay";
+};
+
+&mdss_dp0_out {
+ data-lanes = <0 1>;
+ remote-endpoint = <&usb_dp_qmpphy_dp_in>;
+};
+
&mdss_mdp {
status = "okay";
};
@@ -600,6 +932,11 @@
status = "okay";
};
+&qup_i2c3_data_clk {
+ /* Use internal I2C pull-up */
+ bias-pull-up = <2200>;
+};
+
&qupv3_id_0 {
status = "okay";
};
@@ -657,6 +994,74 @@
};
};
+&swr0 {
+ status = "okay";
+
+ /* WSA8845, Speaker Left */
+ left_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, Speaker Right */
+ right_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>;
+ };
+};
+
+&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>;
@@ -704,6 +1109,14 @@
bias-pull-down;
};
+ spkr_2_sd_n_active: spkr-2-sd-n-active-state {
+ pins = "gpio77";
+ function = "gpio";
+ drive-strength = <16>;
+ bias-disable;
+ output-low;
+ };
+
ts_irq: ts-irq-state {
pins = "gpio161";
function = "gpio";
@@ -718,6 +1131,14 @@
drive-strength = <8>;
bias-pull-up;
};
+
+ wcd_default: wcd-reset-n-active-state {
+ pins = "gpio107";
+ function = "gpio";
+ drive-strength = <16>;
+ bias-disable;
+ output-low;
+ };
};
&uart14 {
@@ -787,7 +1208,7 @@
};
&usb_1_dwc3_ss {
- remote-endpoint = <&pmic_glink_ss_in>;
+ remote-endpoint = <&usb_dp_qmpphy_usb_ss_in>;
};
&usb_1_hsphy {
@@ -803,9 +1224,23 @@
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 2df77123a8c7..ba72d8f38420 100644
--- a/arch/arm64/boot/dts/qcom/sm8650.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8650.dtsi
@@ -525,6 +525,11 @@
no-map;
};
+ qlink_logging_mem: qlink-logging@84800000 {
+ reg = <0 0x84800000 0 0x200000>;
+ no-map;
+ };
+
mpss_dsm_mem: mpss-dsm@86b00000 {
reg = <0 0x86b00000 0 0x4900000>;
no-map;
@@ -1228,7 +1233,7 @@
clocks = <&gcc GCC_QUPV3_WRAP2_S6_CLK>;
clock-names = "se";
- interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
+ interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
&clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
&config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>;
@@ -1250,7 +1255,7 @@
clocks = <&gcc GCC_QUPV3_WRAP2_S7_CLK>;
clock-names = "se";
- interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
+ interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
&clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
&config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>;
@@ -2213,8 +2218,22 @@
<0 0x60100000 0 0x100000>;
reg-names = "parf", "dbi", "elbi", "atu", "config";
- interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "msi";
+ interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi0",
+ "msi1",
+ "msi2",
+ "msi3",
+ "msi4",
+ "msi5",
+ "msi6",
+ "msi7";
clocks = <&gcc GCC_PCIE_0_AUX_CLK>,
<&gcc GCC_PCIE_0_CFG_AHB_CLK>,
@@ -2255,6 +2274,11 @@
interrupt-map-mask = <0 0 0 0x7>;
#interrupt-cells = <1>;
+ /* Entries are reversed due to the unusual ITS DeviceID encoding */
+ msi-map = <0x0 &gic_its 0x1401 0x1>,
+ <0x100 &gic_its 0x1400 0x1>;
+ msi-map-mask = <0xff00>;
+
linux,pci-domain = <0>;
num-lanes = <2>;
bus-range = <0 0xff>;
@@ -2317,8 +2341,22 @@
"atu",
"config";
- interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "msi";
+ interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi0",
+ "msi1",
+ "msi2",
+ "msi3",
+ "msi4",
+ "msi5",
+ "msi6",
+ "msi7";
clocks = <&gcc GCC_PCIE_1_AUX_CLK>,
<&gcc GCC_PCIE_1_CFG_AHB_CLK>,
@@ -2364,6 +2402,11 @@
interrupt-map-mask = <0 0 0 0x7>;
#interrupt-cells = <1>;
+ /* Entries are reversed due to the unusual ITS DeviceID encoding */
+ msi-map = <0x0 &gic_its 0x1481 0x1>,
+ <0x100 &gic_its 0x1480 0x1>;
+ msi-map-mask = <0xff00>;
+
linux,pci-domain = <1>;
num-lanes = <2>;
bus-range = <0 0xff>;
@@ -2448,10 +2491,12 @@
compatible = "qcom,sm8650-qmp-ufs-phy";
reg = <0 0x01d80000 0 0x2000>;
- clocks = <&tcsr TCSR_UFS_CLKREF_EN>,
- <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
+ clocks = <&rpmhcc RPMH_CXO_CLK>,
+ <&gcc GCC_UFS_PHY_PHY_AUX_CLK>,
+ <&tcsr TCSR_UFS_CLKREF_EN>;
clock-names = "ref",
- "ref_aux";
+ "ref_aux",
+ "qref";
resets = <&ufs_mem_hc 0>;
reset-names = "ufsphy";
@@ -2627,7 +2672,8 @@
"mss";
memory-region = <&mpss_mem>, <&q6_mpss_dtb_mem>,
- <&mpss_dsm_mem>, <&mpss_dsm_mem_2>;
+ <&mpss_dsm_mem>, <&mpss_dsm_mem_2>,
+ <&qlink_logging_mem>;
qcom,qmp = <&aoss_qmp>;
@@ -2919,7 +2965,7 @@
};
};
- dmic02_default: dmic02-default-state {
+ dmic23_default: dmic23-default-state {
clk-pins {
pins = "gpio8";
function = "dmic2_clk";
@@ -3703,7 +3749,7 @@
spmi_bus: spmi@c400000 {
compatible = "qcom,spmi-pmic-arb";
reg = <0 0x0c400000 0 0x3000>,
- <0 0x0c500000 0 0x4000000>,
+ <0 0x0c500000 0 0x400000>,
<0 0x0c440000 0 0x80000>,
<0 0x0c4c0000 0 0x20000>,
<0 0x0c42d000 0 0x4000>;
@@ -4808,6 +4854,7 @@
iommus = <&apps_smmu 0x1003 0x80>,
<&apps_smmu 0x1043 0x20>;
+ dma-coherent;
};
compute-cb@4 {
@@ -4816,6 +4863,7 @@
iommus = <&apps_smmu 0x1004 0x80>,
<&apps_smmu 0x1044 0x20>;
+ dma-coherent;
};
compute-cb@5 {
@@ -4824,6 +4872,7 @@
iommus = <&apps_smmu 0x1005 0x80>,
<&apps_smmu 0x1045 0x20>;
+ dma-coherent;
};
compute-cb@6 {
@@ -4832,6 +4881,7 @@
iommus = <&apps_smmu 0x1006 0x80>,
<&apps_smmu 0x1046 0x20>;
+ dma-coherent;
};
compute-cb@7 {
@@ -4841,6 +4891,7 @@
iommus = <&apps_smmu 0x1007 0x40>,
<&apps_smmu 0x1067 0x0>,
<&apps_smmu 0x1087 0x0>;
+ dma-coherent;
};
};
@@ -4961,6 +5012,7 @@
iommus = <&apps_smmu 0x1961 0x0>,
<&apps_smmu 0x0c01 0x20>,
<&apps_smmu 0x19c1 0x0>;
+ dma-coherent;
};
compute-cb@2 {
@@ -4970,6 +5022,7 @@
iommus = <&apps_smmu 0x1962 0x0>,
<&apps_smmu 0x0c02 0x20>,
<&apps_smmu 0x19c2 0x0>;
+ dma-coherent;
};
compute-cb@3 {
@@ -4979,6 +5032,7 @@
iommus = <&apps_smmu 0x1963 0x0>,
<&apps_smmu 0x0c03 0x20>,
<&apps_smmu 0x19c3 0x0>;
+ dma-coherent;
};
compute-cb@4 {
@@ -4988,6 +5042,7 @@
iommus = <&apps_smmu 0x1964 0x0>,
<&apps_smmu 0x0c04 0x20>,
<&apps_smmu 0x19c4 0x0>;
+ dma-coherent;
};
compute-cb@5 {
@@ -4997,6 +5052,7 @@
iommus = <&apps_smmu 0x1965 0x0>,
<&apps_smmu 0x0c05 0x20>,
<&apps_smmu 0x19c5 0x0>;
+ dma-coherent;
};
compute-cb@6 {
@@ -5006,6 +5062,7 @@
iommus = <&apps_smmu 0x1966 0x0>,
<&apps_smmu 0x0c06 0x20>,
<&apps_smmu 0x19c6 0x0>;
+ dma-coherent;
};
compute-cb@7 {
@@ -5015,6 +5072,7 @@
iommus = <&apps_smmu 0x1967 0x0>,
<&apps_smmu 0x0c07 0x20>,
<&apps_smmu 0x19c7 0x0>;
+ dma-coherent;
};
compute-cb@8 {
@@ -5024,6 +5082,7 @@
iommus = <&apps_smmu 0x1968 0x0>,
<&apps_smmu 0x0c08 0x20>,
<&apps_smmu 0x19c8 0x0>;
+ dma-coherent;
};
};
};
diff --git a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
index 7532d8eca2de..6a0a54532e5f 100644
--- a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
+++ b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
@@ -18,10 +18,124 @@
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";
};
+ sound {
+ compatible = "qcom,x1e80100-sndcard";
+ model = "X1E80100-CRD";
+ audio-routing = "WooferLeft IN", "WSA WSA_SPK1 OUT",
+ "TwitterLeft IN", "WSA WSA_SPK2 OUT",
+ "WooferRight IN", "WSA2 WSA_SPK2 OUT",
+ "TwitterRight IN", "WSA2 WSA_SPK2 OUT",
+ "IN1_HPHL", "HPHL_OUT",
+ "IN2_HPHR", "HPHR_OUT",
+ "AMIC2", "MIC BIAS2",
+ "VA DMIC0", "MIC BIAS3",
+ "VA DMIC1", "MIC BIAS3",
+ "VA DMIC2", "MIC BIAS1",
+ "VA DMIC3", "MIC BIAS1",
+ "VA DMIC0", "VA MIC BIAS3",
+ "VA DMIC1", "VA MIC BIAS3",
+ "VA DMIC2", "VA MIC BIAS1",
+ "VA DMIC3", "VA MIC BIAS1",
+ "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 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 = <&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";
@@ -401,10 +515,251 @@
};
};
+&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;
+ };
+
+ 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@10 {
+ compatible = "hid-over-i2c";
+ reg = <0x10>;
+
+ 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;
+
+ data-lanes = <0 1 2 3>;
+
+ 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 {
+ 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 {
+ status = "okay";
+};
+
+&pcie6a_phy {
+ vdda-phy-supply = <&vreg_l3j_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/adsp.mbn",
+ "qcom/x1e80100/adsp_dtb.mbn";
+
+ status = "okay";
+};
+
+&remoteproc_cdsp {
+ firmware-name = "qcom/x1e80100/cdsp.mbn",
+ "qcom/x1e80100/cdsp_dtb.mbn";
+
+ status = "okay";
+};
+
+&swr0 {
+ status = "okay";
+
+ /* 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>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "WooferLeft";
+ vdd-1p8-supply = <&vreg_l15b_1p8>;
+ vdd-io-supply = <&vreg_l12b_1p2>;
+ };
+
+ /* WSA8845, Left Tweeter */
+ 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>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "TwitterLeft";
+ 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 = <1 1 2 3>;
+ };
+};
+
+&swr3 {
+ status = "okay";
+
+ /* 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>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "WooferRight";
+ vdd-1p8-supply = <&vreg_l15b_1p8>;
+ vdd-io-supply = <&vreg_l12b_1p2>;
+ };
+
+ /* WSA8845, Right Tweeter */
+ 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>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "TwitterRight";
+ vdd-1p8-supply = <&vreg_l15b_1p8>;
+ vdd-io-supply = <&vreg_l12b_1p2>;
+ };
+};
+
&tlmm {
gpio-reserved-ranges = <34 2>, /* Unused */
<44 4>, /* SPI (TPM) */
@@ -416,9 +771,104 @@
drive-strength = <16>;
bias-disable;
};
+
+ kybd_default: kybd-default-state {
+ pins = "gpio67";
+ function = "gpio";
+ bias-disable;
+ };
+
+ 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>;
+ };
+ };
+
+ wcd_default: wcd-reset-n-active-state {
+ pins = "gpio191";
+ function = "gpio";
+ drive-strength = <16>;
+ bias-disable;
+ output-low;
+ };
};
&uart21 {
compatible = "qcom,geni-debug-uart";
status = "okay";
};
+
+&usb_1_ss0_hsphy {
+ vdd-supply = <&vreg_l2e_0p8>;
+ vdda12-supply = <&vreg_l3e_1p2>;
+
+ status = "okay";
+};
+
+&usb_1_ss0_qmpphy {
+ status = "okay";
+};
+
+&usb_1_ss0 {
+ status = "okay";
+};
+
+&usb_1_ss0_dwc3 {
+ dr_mode = "host";
+ usb-role-switch;
+};
+
+&usb_1_ss1_hsphy {
+ vdd-supply = <&vreg_l2e_0p8>;
+ vdda12-supply = <&vreg_l3e_1p2>;
+
+ status = "okay";
+};
+
+&usb_1_ss1_qmpphy {
+ status = "okay";
+};
+
+&usb_1_ss1 {
+ status = "okay";
+};
+
+&usb_1_ss1_dwc3 {
+ dr_mode = "host";
+ usb-role-switch;
+};
+
+&usb_1_ss2_hsphy {
+ vdd-supply = <&vreg_l2e_0p8>;
+ vdda12-supply = <&vreg_l3e_1p2>;
+
+ status = "okay";
+};
+
+&usb_1_ss2_qmpphy {
+ status = "okay";
+};
+
+&usb_1_ss2 {
+ status = "okay";
+};
+
+&usb_1_ss2_dwc3 {
+ dr_mode = "host";
+ usb-role-switch;
+};
diff --git a/arch/arm64/boot/dts/qcom/x1e80100-qcp.dts b/arch/arm64/boot/dts/qcom/x1e80100-qcp.dts
index a37ad9475c90..e76d29053d79 100644
--- a/arch/arm64/boot/dts/qcom/x1e80100-qcp.dts
+++ b/arch/arm64/boot/dts/qcom/x1e80100-qcp.dts
@@ -5,6 +5,7 @@
/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
#include "x1e80100.dtsi"
@@ -31,6 +32,23 @@
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;
+ };
};
&apps_rsc {
@@ -243,7 +261,7 @@
qcom,pmic-id = "e";
vdd-l2-supply = <&vreg_s1f_0p7>;
- vdd-l3-supply = <&vph_pwr>;
+ vdd-l3-supply = <&vreg_s5j_1p2>;
vreg_l2e_0p8: ldo2 {
regulator-name = "vreg_l2e_0p8";
@@ -349,7 +367,7 @@
qcom,pmic-id = "j";
vdd-l1-supply = <&vreg_s1f_0p7>;
- vdd-l2-supply = <&vph_pwr>;
+ vdd-l2-supply = <&vreg_s5j_1p2>;
vdd-l3-supply = <&vreg_s1f_0p7>;
vdd-s5-supply = <&vph_pwr>;
@@ -383,17 +401,170 @@
};
};
+&mdss {
+ status = "okay";
+};
+
+&mdss_dp3 {
+ compatible = "qcom,x1e80100-dp";
+ /delete-property/ #sound-dai-cells;
+
+ data-lanes = <0 1 2 3>;
+
+ 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 {
+ 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 {
+ status = "okay";
+};
+
+&pcie6a_phy {
+ vdda-phy-supply = <&vreg_l3j_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/adsp.mbn",
+ "qcom/x1e80100/adsp_dtb.mbn";
+
+ status = "okay";
+};
+
+&remoteproc_cdsp {
+ firmware-name = "qcom/x1e80100/cdsp.mbn",
+ "qcom/x1e80100/cdsp_dtb.mbn";
+
+ status = "okay";
+};
+
&tlmm {
gpio-reserved-ranges = <33 3>, /* 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;
+ };
};
&uart21 {
compatible = "qcom,geni-debug-uart";
status = "okay";
};
+
+&usb_1_ss0_hsphy {
+ vdd-supply = <&vreg_l2e_0p8>;
+ vdda12-supply = <&vreg_l3e_1p2>;
+
+ status = "okay";
+};
+
+&usb_1_ss0_qmpphy {
+ status = "okay";
+};
+
+&usb_1_ss0 {
+ status = "okay";
+};
+
+&usb_1_ss0_dwc3 {
+ dr_mode = "host";
+ usb-role-switch;
+};
+
+&usb_1_ss1_hsphy {
+ vdd-supply = <&vreg_l2e_0p8>;
+ vdda12-supply = <&vreg_l3e_1p2>;
+
+ status = "okay";
+};
+
+&usb_1_ss1_qmpphy {
+ status = "okay";
+};
+
+&usb_1_ss1 {
+ status = "okay";
+};
+
+&usb_1_ss1_dwc3 {
+ dr_mode = "host";
+ usb-role-switch;
+};
+
+&usb_1_ss2_hsphy {
+ vdd-supply = <&vreg_l2e_0p8>;
+ vdda12-supply = <&vreg_l3e_1p2>;
+
+ status = "okay";
+};
+
+&usb_1_ss2_qmpphy {
+ status = "okay";
+};
+
+&usb_1_ss2 {
+ status = "okay";
+};
+
+&usb_1_ss2_dwc3 {
+ dr_mode = "host";
+ usb-role-switch;
+};
diff --git a/arch/arm64/boot/dts/qcom/x1e80100.dtsi b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
index 6f75fc342ceb..8e517f76189e 100644
--- a/arch/arm64/boot/dts/qcom/x1e80100.dtsi
+++ b/arch/arm64/boot/dts/qcom/x1e80100.dtsi
@@ -4,14 +4,20 @@
*/
#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-tcsr.h>
#include <dt-bindings/dma/qcom-gpi.h>
#include <dt-bindings/interconnect/qcom,icc.h>
#include <dt-bindings/interconnect/qcom,x1e80100-rpmh.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/mailbox/qcom-ipcc.h>
+#include <dt-bindings/phy/phy-qcom-qmp.h>
#include <dt-bindings/power/qcom,rpmhpd.h>
#include <dt-bindings/power/qcom-rpmpd.h>
+#include <dt-bindings/soc/qcom,gpr.h>
#include <dt-bindings/soc/qcom,rpmh-rsc.h>
+#include <dt-bindings/sound/qcom,q6dsp-lpass-ports.h>
/ {
interrupt-parent = <&intc>;
@@ -395,16 +401,24 @@
CLUSTER_PD0: power-domain-cpu-cluster0 {
#power-domain-cells = <0>;
domain-idle-states = <&CLUSTER_CL4>, <&CLUSTER_CL5>;
+ power-domains = <&SYSTEM_PD>;
};
CLUSTER_PD1: power-domain-cpu-cluster1 {
#power-domain-cells = <0>;
domain-idle-states = <&CLUSTER_CL4>, <&CLUSTER_CL5>;
+ power-domains = <&SYSTEM_PD>;
};
CLUSTER_PD2: power-domain-cpu-cluster2 {
#power-domain-cells = <0>;
domain-idle-states = <&CLUSTER_CL4>, <&CLUSTER_CL5>;
+ power-domains = <&SYSTEM_PD>;
+ };
+
+ SYSTEM_PD: power-domain-system {
+ #power-domain-cells = <0>;
+ /* TODO: system-wide idle states */
};
};
@@ -662,6 +676,58 @@
};
};
+ smp2p-adsp {
+ compatible = "qcom,smp2p";
+
+ interrupts-extended = <&ipcc IPCC_CLIENT_LPASS
+ IPCC_MPROC_SIGNAL_SMP2P
+ IRQ_TYPE_EDGE_RISING>;
+
+ mboxes = <&ipcc IPCC_CLIENT_LPASS
+ IPCC_MPROC_SIGNAL_SMP2P>;
+
+ qcom,smem = <443>, <429>;
+ qcom,local-pid = <0>;
+ qcom,remote-pid = <2>;
+
+ smp2p_adsp_out: master-kernel {
+ qcom,entry-name = "master-kernel";
+ #qcom,smem-state-cells = <1>;
+ };
+
+ smp2p_adsp_in: slave-kernel {
+ qcom,entry-name = "slave-kernel";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+
+ smp2p-cdsp {
+ compatible = "qcom,smp2p";
+
+ interrupts-extended = <&ipcc IPCC_CLIENT_CDSP
+ IPCC_MPROC_SIGNAL_SMP2P
+ IRQ_TYPE_EDGE_RISING>;
+
+ mboxes = <&ipcc IPCC_CLIENT_CDSP
+ IPCC_MPROC_SIGNAL_SMP2P>;
+
+ qcom,smem = <94>, <432>;
+ qcom,local-pid = <0>;
+ qcom,remote-pid = <5>;
+
+ smp2p_cdsp_out: master-kernel {
+ qcom,entry-name = "master-kernel";
+ #qcom,smem-state-cells = <1>;
+ };
+
+ smp2p_cdsp_in: slave-kernel {
+ qcom,entry-name = "slave-kernel";
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+
soc: soc@0 {
compatible = "simple-bus";
@@ -677,13 +743,13 @@
clocks = <&bi_tcxo_div2>,
<&sleep_clk>,
<0>,
+ <&pcie4_phy>,
<0>,
+ <&pcie6a_phy>,
<0>,
- <0>,
- <0>,
- <0>,
- <0>,
- <0>;
+ <&usb_1_ss0_qmpphy QMP_USB43DP_USB3_PIPE_CLK>,
+ <&usb_1_ss1_qmpphy QMP_USB43DP_USB3_PIPE_CLK>,
+ <&usb_1_ss2_qmpphy QMP_USB43DP_USB3_PIPE_CLK>;
power-domains = <&rpmhpd RPMHPD_CX>;
#clock-cells = <1>;
@@ -691,6 +757,17 @@
#power-domain-cells = <1>;
};
+ ipcc: mailbox@408000 {
+ compatible = "qcom,x1e80100-ipcc", "qcom,ipcc";
+ reg = <0 0x00408000 0 0x1000>;
+
+ interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+
+ #mbox-cells = <2>;
+ };
+
gpi_dma2: dma-controller@800000 {
compatible = "qcom,x1e80100-gpi-dma", "qcom,sm6350-gpi-dma";
reg = <0 0x00800000 0 0x60000>;
@@ -1139,7 +1216,7 @@
clocks = <&gcc GCC_QUPV3_WRAP2_S5_CLK>;
clock-names = "se";
- interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
+ interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
&clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
&config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>;
@@ -2428,6 +2505,126 @@
};
};
+ usb_1_ss0_hsphy: phy@fd3000 {
+ compatible = "qcom,x1e80100-snps-eusb2-phy",
+ "qcom,sm8550-snps-eusb2-phy";
+ reg = <0 0x00fd3000 0 0x154>;
+ #phy-cells = <0>;
+
+ clocks = <&tcsr TCSR_USB2_1_CLKREF_EN>;
+ clock-names = "ref";
+
+ resets = <&gcc GCC_QUSB2PHY_PRIM_BCR>;
+
+ status = "disabled";
+ };
+
+ usb_1_ss0_qmpphy: phy@fd5000 {
+ compatible = "qcom,x1e80100-qmp-usb3-dp-phy";
+ reg = <0 0x00fd5000 0 0x4000>;
+
+ clocks = <&gcc GCC_USB3_PRIM_PHY_AUX_CLK>,
+ <&rpmhcc RPMH_CXO_CLK>,
+ <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>,
+ <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>;
+ clock-names = "aux",
+ "ref",
+ "com_aux",
+ "usb3_pipe";
+
+ power-domains = <&gcc GCC_USB_0_PHY_GDSC>;
+
+ resets = <&gcc GCC_USB3_PHY_PRIM_BCR>,
+ <&gcc GCC_USB4_0_DP0_PHY_PRIM_BCR>;
+ reset-names = "phy",
+ "common";
+
+ #clock-cells = <1>;
+ #phy-cells = <1>;
+
+ status = "disabled";
+ };
+
+ usb_1_ss1_hsphy: phy@fd9000 {
+ compatible = "qcom,x1e80100-snps-eusb2-phy",
+ "qcom,sm8550-snps-eusb2-phy";
+ reg = <0 0x00fd9000 0 0x154>;
+ #phy-cells = <0>;
+
+ clocks = <&tcsr TCSR_USB2_1_CLKREF_EN>;
+ clock-names = "ref";
+
+ resets = <&gcc GCC_QUSB2PHY_SEC_BCR>;
+
+ status = "disabled";
+ };
+
+ usb_1_ss1_qmpphy: phy@fda000 {
+ compatible = "qcom,x1e80100-qmp-usb3-dp-phy";
+ reg = <0 0x00fda000 0 0x4000>;
+
+ clocks = <&gcc GCC_USB3_SEC_PHY_AUX_CLK>,
+ <&rpmhcc RPMH_CXO_CLK>,
+ <&gcc GCC_USB3_SEC_PHY_COM_AUX_CLK>,
+ <&gcc GCC_USB3_SEC_PHY_PIPE_CLK>;
+ clock-names = "aux",
+ "ref",
+ "com_aux",
+ "usb3_pipe";
+
+ power-domains = <&gcc GCC_USB_1_PHY_GDSC>;
+
+ resets = <&gcc GCC_USB3_PHY_SEC_BCR>,
+ <&gcc GCC_USB4_1_DP0_PHY_SEC_BCR>;
+ reset-names = "phy",
+ "common";
+
+ #clock-cells = <1>;
+ #phy-cells = <1>;
+
+ status = "disabled";
+ };
+
+ usb_1_ss2_hsphy: phy@fde000 {
+ compatible = "qcom,x1e80100-snps-eusb2-phy",
+ "qcom,sm8550-snps-eusb2-phy";
+ reg = <0 0x00fde000 0 0x154>;
+ #phy-cells = <0>;
+
+ clocks = <&tcsr TCSR_USB2_1_CLKREF_EN>;
+ clock-names = "ref";
+
+ resets = <&gcc GCC_QUSB2PHY_TERT_BCR>;
+
+ status = "disabled";
+ };
+
+ usb_1_ss2_qmpphy: phy@fdf000 {
+ compatible = "qcom,x1e80100-qmp-usb3-dp-phy";
+ reg = <0 0x00fdf000 0 0x4000>;
+
+ clocks = <&gcc GCC_USB3_TERT_PHY_AUX_CLK>,
+ <&rpmhcc RPMH_CXO_CLK>,
+ <&gcc GCC_USB3_TERT_PHY_COM_AUX_CLK>,
+ <&gcc GCC_USB3_TERT_PHY_PIPE_CLK>;
+ clock-names = "aux",
+ "ref",
+ "com_aux",
+ "usb3_pipe";
+
+ power-domains = <&gcc GCC_USB_2_PHY_GDSC>;
+
+ resets = <&gcc GCC_USB3_PHY_TERT_BCR>,
+ <&gcc GCC_USB4_2_DP0_PHY_TERT_BCR>;
+ reset-names = "phy",
+ "common";
+
+ #clock-cells = <1>;
+ #phy-cells = <1>;
+
+ status = "disabled";
+ };
+
cnoc_main: interconnect@1500000 {
compatible = "qcom,x1e80100-cnoc-main";
reg = <0 0x1500000 0 0x14400>;
@@ -2536,12 +2733,258 @@
#interconnect-cells = <2>;
};
+ pcie6a: pci@1bf8000 {
+ device_type = "pci";
+ compatible = "qcom,pcie-x1e80100";
+ reg = <0 0x01bf8000 0 0x3000>,
+ <0 0x70000000 0 0xf1d>,
+ <0 0x70000f20 0 0xa8>,
+ <0 0x70001000 0 0x1000>,
+ <0 0x70100000 0 0x100000>;
+ reg-names = "parf",
+ "dbi",
+ "elbi",
+ "atu",
+ "config";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges = <0x01000000 0 0x00000000 0 0x70200000 0 0x100000>,
+ <0x02000000 0 0x70300000 0 0x70300000 0 0x3d00000>;
+ bus-range = <0 0xff>;
+
+ dma-coherent;
+
+ linux,pci-domain = <7>;
+ num-lanes = <2>;
+
+ interrupts = <GIC_SPI 773 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 774 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 837 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 838 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 839 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 840 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 841 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 842 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi0",
+ "msi1",
+ "msi2",
+ "msi3",
+ "msi4",
+ "msi5",
+ "msi6",
+ "msi7";
+
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0x7>;
+ interrupt-map = <0 0 0 1 &intc 0 0 0 843 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 2 &intc 0 0 0 844 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 3 &intc 0 0 0 845 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 4 &intc 0 0 0 772 IRQ_TYPE_LEVEL_HIGH>;
+
+ clocks = <&gcc GCC_PCIE_6A_AUX_CLK>,
+ <&gcc GCC_PCIE_6A_CFG_AHB_CLK>,
+ <&gcc GCC_PCIE_6A_MSTR_AXI_CLK>,
+ <&gcc GCC_PCIE_6A_SLV_AXI_CLK>,
+ <&gcc GCC_PCIE_6A_SLV_Q2A_AXI_CLK>,
+ <&gcc GCC_CFG_NOC_PCIE_ANOC_SOUTH_AHB_CLK>,
+ <&gcc GCC_CNOC_PCIE_SOUTH_SF_AXI_CLK>;
+ clock-names = "aux",
+ "cfg",
+ "bus_master",
+ "bus_slave",
+ "slave_q2a",
+ "noc_aggr",
+ "cnoc_sf_axi";
+
+ assigned-clocks = <&gcc GCC_PCIE_6A_AUX_CLK>;
+ assigned-clock-rates = <19200000>;
+
+ interconnects = <&pcie_south_anoc MASTER_PCIE_6A QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+ <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+ &cnoc_main SLAVE_PCIE_6A QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "pcie-mem",
+ "cpu-pcie";
+
+ resets = <&gcc GCC_PCIE_6A_BCR>,
+ <&gcc GCC_PCIE_6A_LINK_DOWN_BCR>;
+ reset-names = "pci",
+ "link_down";
+
+ power-domains = <&gcc GCC_PCIE_6A_GDSC>;
+
+ phys = <&pcie6a_phy>;
+ phy-names = "pciephy";
+
+ status = "disabled";
+ };
+
+ pcie6a_phy: phy@1bfc000 {
+ compatible = "qcom,x1e80100-qmp-gen4x2-pcie-phy";
+ reg = <0 0x01bfc000 0 0x2000>;
+
+ clocks = <&gcc GCC_PCIE_6A_PHY_AUX_CLK>,
+ <&gcc GCC_PCIE_6A_CFG_AHB_CLK>,
+ <&rpmhcc RPMH_CXO_CLK>,
+ <&gcc GCC_PCIE_6A_PHY_RCHNG_CLK>,
+ <&gcc GCC_PCIE_6A_PIPE_CLK>;
+ clock-names = "aux",
+ "cfg_ahb",
+ "ref",
+ "rchng",
+ "pipe";
+
+ resets = <&gcc GCC_PCIE_6A_PHY_BCR>,
+ <&gcc GCC_PCIE_6A_NOCSR_COM_PHY_BCR>;
+ reset-names = "phy",
+ "phy_nocsr";
+
+ assigned-clocks = <&gcc GCC_PCIE_6A_PHY_RCHNG_CLK>;
+ assigned-clock-rates = <100000000>;
+
+ power-domains = <&gcc GCC_PCIE_6_PHY_GDSC>;
+
+ #clock-cells = <0>;
+ clock-output-names = "pcie6a_pipe_clk";
+
+ #phy-cells = <0>;
+
+ status = "disabled";
+ };
+
+ pcie4: pci@1c08000 {
+ device_type = "pci";
+ compatible = "qcom,pcie-x1e80100";
+ reg = <0 0x01c08000 0 0x3000>,
+ <0 0x7c000000 0 0xf1d>,
+ <0 0x7c000f40 0 0xa8>,
+ <0 0x7c001000 0 0x1000>,
+ <0 0x7c100000 0 0x100000>,
+ <0 0x01c0b000 0 0x1000>;
+ reg-names = "parf",
+ "dbi",
+ "elbi",
+ "atu",
+ "config",
+ "mhi";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges = <0x01000000 0 0x00000000 0 0x7c200000 0 0x100000>,
+ <0x02000000 0 0x7c300000 0 0x7c300000 0 0x3d00000>;
+ bus-range = <0x00 0xff>;
+
+ dma-coherent;
+
+ linux,pci-domain = <5>;
+ num-lanes = <2>;
+
+ interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "msi0",
+ "msi1",
+ "msi2",
+ "msi3",
+ "msi4",
+ "msi5",
+ "msi6",
+ "msi7";
+
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0x7>;
+ interrupt-map = <0 0 0 1 &intc 0 0 0 149 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 2 &intc 0 0 0 150 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 3 &intc 0 0 0 151 IRQ_TYPE_LEVEL_HIGH>,
+ <0 0 0 4 &intc 0 0 0 152 IRQ_TYPE_LEVEL_HIGH>;
+
+ clocks = <&gcc GCC_PCIE_4_AUX_CLK>,
+ <&gcc GCC_PCIE_4_CFG_AHB_CLK>,
+ <&gcc GCC_PCIE_4_MSTR_AXI_CLK>,
+ <&gcc GCC_PCIE_4_SLV_AXI_CLK>,
+ <&gcc GCC_PCIE_4_SLV_Q2A_AXI_CLK>,
+ <&gcc GCC_CFG_NOC_PCIE_ANOC_NORTH_AHB_CLK>,
+ <&gcc GCC_CNOC_PCIE_NORTH_SF_AXI_CLK>;
+ clock-names = "aux",
+ "cfg",
+ "bus_master",
+ "bus_slave",
+ "slave_q2a",
+ "noc_aggr",
+ "cnoc_sf_axi";
+
+ assigned-clocks = <&gcc GCC_PCIE_4_AUX_CLK>;
+ assigned-clock-rates = <19200000>;
+
+ interconnects = <&pcie_south_anoc MASTER_PCIE_4 QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+ <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+ &cnoc_main SLAVE_PCIE_4 QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "pcie-mem",
+ "cpu-pcie";
+
+ resets = <&gcc GCC_PCIE_4_BCR>,
+ <&gcc GCC_PCIE_4_LINK_DOWN_BCR>;
+ reset-names = "pci",
+ "link_down";
+
+ power-domains = <&gcc GCC_PCIE_4_GDSC>;
+
+ phys = <&pcie4_phy>;
+ phy-names = "pciephy";
+
+ status = "disabled";
+ };
+
+ pcie4_phy: phy@1c0e000 {
+ compatible = "qcom,x1e80100-qmp-gen3x2-pcie-phy";
+ reg = <0 0x01c0e000 0 0x2000>;
+
+ clocks = <&gcc GCC_PCIE_4_AUX_CLK>,
+ <&gcc GCC_PCIE_4_CFG_AHB_CLK>,
+ <&rpmhcc RPMH_CXO_CLK>,
+ <&gcc GCC_PCIE_4_PHY_RCHNG_CLK>,
+ <&gcc GCC_PCIE_4_PIPE_CLK>;
+ clock-names = "aux",
+ "cfg_ahb",
+ "ref",
+ "rchng",
+ "pipe";
+
+ resets = <&gcc GCC_PCIE_4_PHY_BCR>;
+ reset-names = "phy";
+
+ assigned-clocks = <&gcc GCC_PCIE_4_PHY_RCHNG_CLK>;
+ assigned-clock-rates = <100000000>;
+
+ power-domains = <&gcc GCC_PCIE_4_PHY_GDSC>;
+
+ #clock-cells = <0>;
+ clock-output-names = "pcie4_pipe_clk";
+
+ #phy-cells = <0>;
+
+ status = "disabled";
+ };
+
tcsr_mutex: hwlock@1f40000 {
compatible = "qcom,tcsr-mutex";
reg = <0 0x01f40000 0 0x20000>;
#hwlock-cells = <1>;
};
+ tcsr: clock-controller@1fc0000 {
+ compatible = "qcom,x1e80100-tcsr", "syscon";
+ reg = <0 0x01fc0000 0 0x30000>;
+ clocks = <&rpmhcc RPMH_CXO_CLK>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
gem_noc: interconnect@26400000 {
compatible = "qcom,x1e80100-gem-noc";
reg = <0 0x26400000 0 0x311200>;
@@ -2560,6 +3003,331 @@
#interconnect-cells = <2>;
};
+ lpass_wsa2macro: codec@6aa0000 {
+ compatible = "qcom,x1e80100-lpass-wsa-macro", "qcom,sm8550-lpass-wsa-macro";
+ reg = <0 0x06aa0000 0 0x1000>;
+ clocks = <&q6prmcc LPASS_CLK_ID_WSA2_CORE_TX_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+ <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+ <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+ <&lpass_vamacro>;
+ clock-names = "mclk",
+ "macro",
+ "dcodec",
+ "fsgen";
+
+ #clock-cells = <0>;
+ clock-output-names = "wsa2-mclk";
+ #sound-dai-cells = <1>;
+ sound-name-prefix = "WSA2";
+ };
+
+ swr3: soundwire@6ab0000 {
+ compatible = "qcom,soundwire-v2.0.0";
+ reg = <0 0x06ab0000 0 0x10000>;
+ clocks = <&lpass_wsa2macro>;
+ clock-names = "iface";
+ interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>;
+ label = "WSA2";
+
+ pinctrl-0 = <&wsa2_swr_active>;
+ pinctrl-names = "default";
+
+ qcom,din-ports = <4>;
+ qcom,dout-ports = <9>;
+
+ qcom,ports-sinterval = /bits/ 16 <0x07 0x1f 0x3f 0x07 0x1f 0x3f 0xc8 0xff 0xff 0x0f 0x0f 0xff 0x31f>;
+ qcom,ports-offset1 = /bits/ 8 <0x01 0x03 0x05 0x02 0x04 0x15 0x00 0xff 0xff 0x06 0x0d 0xff 0x00>;
+ qcom,ports-offset2 = /bits/ 8 <0xff 0x07 0x1f 0xff 0x07 0x1f 0xff 0xff 0xff 0xff 0xff 0xff 0xff>;
+ qcom,ports-hstart = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0x08 0xff 0xff 0xff 0xff 0xff 0x0f>;
+ qcom,ports-hstop = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0x08 0xff 0xff 0xff 0xff 0xff 0x0f>;
+ qcom,ports-word-length = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0x08 0xff 0xff 0xff 0xff 0xff 0x18>;
+ qcom,ports-block-pack-mode = /bits/ 8 <0x00 0x01 0x01 0x00 0x01 0x01 0x00 0x00 0x00 0x01 0x01 0x00 0x00>;
+ qcom,ports-block-group-count = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>;
+ qcom,ports-lane-control = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>;
+
+ #address-cells = <2>;
+ #size-cells = <0>;
+ #sound-dai-cells = <1>;
+ status = "disabled";
+ };
+
+ lpass_rxmacro: codec@6ac0000 {
+ compatible = "qcom,x1e80100-lpass-rx-macro", "qcom,sm8550-lpass-rx-macro";
+ reg = <0 0x06ac0000 0 0x1000>;
+ clocks = <&q6prmcc LPASS_CLK_ID_RX_CORE_TX_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+ <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+ <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+ <&lpass_vamacro>;
+ clock-names = "mclk",
+ "macro",
+ "dcodec",
+ "fsgen";
+
+ #clock-cells = <0>;
+ clock-output-names = "mclk";
+ #sound-dai-cells = <1>;
+ };
+
+ swr1: soundwire@6ad0000 {
+ compatible = "qcom,soundwire-v2.0.0";
+ reg = <0 0x06ad0000 0 0x10000>;
+ clocks = <&lpass_rxmacro>;
+ clock-names = "iface";
+ interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+ label = "RX";
+
+ pinctrl-0 = <&rx_swr_active>;
+ pinctrl-names = "default";
+
+ qcom,din-ports = <1>;
+ qcom,dout-ports = <11>;
+
+ qcom,ports-sinterval = /bits/ 16 <0x03 0x1f 0x1f 0x07 0x00 0xff 0xff 0xff 0xff 0xff 0xff 0xff>;
+ qcom,ports-offset1 = /bits/ 8 <0x00 0x00 0x0b 0x01 0x00 0xff 0xff 0xff 0xff 0xff 0xff 0xff>;
+ qcom,ports-offset2 = /bits/ 8 <0x00 0x00 0x0b 0x00 0x00 0xff 0xff 0xff 0xff 0xff 0xff 0xff>;
+ 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-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>;
+
+ #address-cells = <2>;
+ #size-cells = <0>;
+ #sound-dai-cells = <1>;
+ status = "disabled";
+ };
+
+ lpass_txmacro: codec@6ae0000 {
+ compatible = "qcom,x1e80100-lpass-tx-macro", "qcom,sm8550-lpass-tx-macro";
+ reg = <0 0x06ae0000 0 0x1000>;
+ clocks = <&q6prmcc LPASS_CLK_ID_TX_CORE_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+ <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+ <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+ <&lpass_vamacro>;
+ clock-names = "mclk",
+ "macro",
+ "dcodec",
+ "fsgen";
+
+ #clock-cells = <0>;
+ clock-output-names = "mclk";
+ #sound-dai-cells = <1>;
+ };
+
+ lpass_wsamacro: codec@6b00000 {
+ compatible = "qcom,x1e80100-lpass-wsa-macro", "qcom,sm8550-lpass-wsa-macro";
+ reg = <0 0x06b00000 0 0x1000>;
+ clocks = <&q6prmcc LPASS_CLK_ID_WSA_CORE_TX_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+ <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+ <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+ <&lpass_vamacro>;
+ clock-names = "mclk",
+ "macro",
+ "dcodec",
+ "fsgen";
+
+ #clock-cells = <0>;
+ clock-output-names = "mclk";
+ #sound-dai-cells = <1>;
+ sound-name-prefix = "WSA";
+ };
+
+ swr0: soundwire@6b10000 {
+ compatible = "qcom,soundwire-v2.0.0";
+ reg = <0 0x06b10000 0 0x10000>;
+ clocks = <&lpass_wsamacro>;
+ clock-names = "iface";
+ interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>;
+ label = "WSA";
+
+ pinctrl-0 = <&wsa_swr_active>;
+ pinctrl-names = "default";
+
+ qcom,din-ports = <4>;
+ qcom,dout-ports = <9>;
+
+ qcom,ports-sinterval = /bits/ 16 <0x07 0x1f 0x3f 0x07 0x1f 0x3f 0xc8 0xff 0xff 0x0f 0x0f 0xff 0x31f>;
+ qcom,ports-offset1 = /bits/ 8 <0x01 0x03 0x05 0x02 0x04 0x15 0x00 0xff 0xff 0x06 0x0d 0xff 0x00>;
+ qcom,ports-offset2 = /bits/ 8 <0xff 0x07 0x1f 0xff 0x07 0x1f 0xff 0xff 0xff 0xff 0xff 0xff 0xff>;
+ qcom,ports-hstart = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0x08 0xff 0xff 0xff 0xff 0xff 0x0f>;
+ qcom,ports-hstop = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0x08 0xff 0xff 0xff 0xff 0xff 0x0f>;
+ qcom,ports-word-length = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0x08 0xff 0xff 0xff 0xff 0xff 0x18>;
+ qcom,ports-block-pack-mode = /bits/ 8 <0x00 0x01 0x01 0x00 0x01 0x01 0x00 0x00 0x00 0x01 0x01 0x00 0x00>;
+ qcom,ports-block-group-count = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>;
+ qcom,ports-lane-control = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>;
+
+ #address-cells = <2>;
+ #size-cells = <0>;
+ #sound-dai-cells = <1>;
+ status = "disabled";
+ };
+
+ swr2: soundwire@6d30000 {
+ compatible = "qcom,soundwire-v2.0.0";
+ reg = <0 0x06d30000 0 0x10000>;
+ clocks = <&lpass_txmacro>;
+ clock-names = "iface";
+ interrupts = <GIC_SPI 496 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 520 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "core", "wakeup";
+ label = "TX";
+
+ pinctrl-0 = <&tx_swr_active>;
+ pinctrl-names = "default";
+
+ qcom,din-ports = <4>;
+ qcom,dout-ports = <1>;
+
+ qcom,ports-sinterval-low = /bits/ 8 <0x00 0x01 0x03 0x03 0x00>;
+ qcom,ports-offset1 = /bits/ 8 <0x00 0x01 0x02 0x00 0x00>;
+ qcom,ports-offset2 = /bits/ 8 <0x00 0x00 0x00 0x00 0xff>;
+ qcom,ports-hstart = /bits/ 8 <0xff 0xff 0xff 0xff 0xff>;
+ qcom,ports-hstop = /bits/ 8 <0xff 0xff 0xff 0xff 0xff>;
+ qcom,ports-word-length = /bits/ 8 <0xff 0xff 0xff 0xff 0xff>;
+ qcom,ports-block-pack-mode = /bits/ 8 <0xff 0xff 0xff 0xff 0xff>;
+ qcom,ports-block-group-count = /bits/ 8 <0xff 0xff 0xff 0xff 0xff>;
+ qcom,ports-lane-control = /bits/ 8 <0xff 0x00 0x00 0x01 0xff>;
+
+ #address-cells = <2>;
+ #size-cells = <0>;
+ #sound-dai-cells = <1>;
+ status = "disabled";
+ };
+
+ lpass_vamacro: codec@6d44000 {
+ compatible = "qcom,x1e80100-lpass-va-macro", "qcom,sm8550-lpass-va-macro";
+ reg = <0 0x06d44000 0 0x1000>;
+ clocks = <&q6prmcc LPASS_CLK_ID_TX_CORE_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+ <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+ <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
+ clock-names = "mclk",
+ "macro",
+ "dcodec";
+
+ #clock-cells = <0>;
+ clock-output-names = "fsgen";
+ #sound-dai-cells = <1>;
+ };
+
+ lpass_tlmm: pinctrl@6e80000 {
+ compatible = "qcom,x1e80100-lpass-lpi-pinctrl", "qcom,sm8550-lpass-lpi-pinctrl";
+ reg = <0 0x06e80000 0 0x20000>,
+ <0 0x07250000 0 0x10000>;
+
+ clocks = <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+ <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
+ clock-names = "core", "audio";
+
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&lpass_tlmm 0 0 23>;
+
+ tx_swr_active: tx-swr-active-state {
+ clk-pins {
+ pins = "gpio0";
+ function = "swr_tx_clk";
+ drive-strength = <2>;
+ slew-rate = <1>;
+ bias-disable;
+ };
+
+ data-pins {
+ pins = "gpio1", "gpio2";
+ function = "swr_tx_data";
+ drive-strength = <2>;
+ slew-rate = <1>;
+ bias-bus-hold;
+ };
+ };
+
+ rx_swr_active: rx-swr-active-state {
+ clk-pins {
+ pins = "gpio3";
+ function = "swr_rx_clk";
+ drive-strength = <2>;
+ slew-rate = <1>;
+ bias-disable;
+ };
+
+ data-pins {
+ pins = "gpio4", "gpio5";
+ function = "swr_rx_data";
+ drive-strength = <2>;
+ slew-rate = <1>;
+ bias-bus-hold;
+ };
+ };
+
+ dmic01_default: dmic01-default-state {
+ clk-pins {
+ pins = "gpio6";
+ function = "dmic1_clk";
+ drive-strength = <8>;
+ output-high;
+ };
+
+ data-pins {
+ pins = "gpio7";
+ function = "dmic1_data";
+ drive-strength = <8>;
+ input-enable;
+ };
+ };
+
+ dmic23_default: dmic23-default-state {
+ clk-pins {
+ pins = "gpio8";
+ function = "dmic2_clk";
+ drive-strength = <8>;
+ output-high;
+ };
+
+ data-pins {
+ pins = "gpio9";
+ function = "dmic2_data";
+ drive-strength = <8>;
+ input-enable;
+ };
+ };
+
+ wsa_swr_active: wsa-swr-active-state {
+ clk-pins {
+ pins = "gpio10";
+ function = "wsa_swr_clk";
+ drive-strength = <2>;
+ slew-rate = <1>;
+ bias-disable;
+ };
+
+ data-pins {
+ pins = "gpio11";
+ function = "wsa_swr_data";
+ drive-strength = <2>;
+ slew-rate = <1>;
+ bias-bus-hold;
+ };
+ };
+
+ wsa2_swr_active: wsa2-swr-active-state {
+ clk-pins {
+ pins = "gpio15";
+ function = "wsa2_swr_clk";
+ drive-strength = <2>;
+ slew-rate = <1>;
+ bias-disable;
+ };
+
+ data-pins {
+ pins = "gpio16";
+ function = "wsa2_swr_data";
+ drive-strength = <2>;
+ slew-rate = <1>;
+ bias-bus-hold;
+ };
+ };
+ };
+
lpass_ag_noc: interconnect@7e40000 {
compatible = "qcom,x1e80100-lpass-ag-noc";
reg = <0 0x7e40000 0 0xE080>;
@@ -2587,6 +3355,849 @@
#interconnect-cells = <2>;
};
+ usb_2_hsphy: phy@88e0000 {
+ compatible = "qcom,x1e80100-snps-eusb2-phy",
+ "qcom,sm8550-snps-eusb2-phy";
+ reg = <0 0x088e0000 0 0x154>;
+ #phy-cells = <0>;
+
+ clocks = <&tcsr TCSR_USB2_2_CLKREF_EN>;
+ clock-names = "ref";
+
+ resets = <&gcc GCC_QUSB2PHY_USB20_HS_BCR>;
+
+ status = "disabled";
+ };
+
+ usb_1_ss2: usb@a0f8800 {
+ compatible = "qcom,x1e80100-dwc3", "qcom,dwc3";
+ reg = <0 0x0a0f8800 0 0x400>;
+
+ clocks = <&gcc GCC_CFG_NOC_USB3_TERT_AXI_CLK>,
+ <&gcc GCC_USB30_TERT_MASTER_CLK>,
+ <&gcc GCC_AGGRE_USB3_TERT_AXI_CLK>,
+ <&gcc GCC_USB30_TERT_SLEEP_CLK>,
+ <&gcc GCC_USB30_TERT_MOCK_UTMI_CLK>,
+ <&gcc GCC_AGGRE_USB_NOC_AXI_CLK>,
+ <&gcc GCC_AGGRE_NOC_USB_NORTH_AXI_CLK>,
+ <&gcc GCC_AGGRE_NOC_USB_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_TERT_MOCK_UTMI_CLK>,
+ <&gcc GCC_USB30_TERT_MASTER_CLK>;
+ assigned-clock-rates = <19200000>,
+ <200000000>;
+
+ interrupts-extended = <&intc GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>,
+ <&pdc 58 IRQ_TYPE_EDGE_BOTH>,
+ <&pdc 57 IRQ_TYPE_EDGE_BOTH>,
+ <&pdc 10 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "pwr_event",
+ "dp_hs_phy_irq",
+ "dm_hs_phy_irq",
+ "ss_phy_irq";
+
+ power-domains = <&gcc GCC_USB30_TERT_GDSC>;
+ required-opps = <&rpmhpd_opp_nom>;
+
+ resets = <&gcc GCC_USB30_TERT_BCR>;
+
+ interconnects = <&usb_south_anoc MASTER_USB3_2 QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+ <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+ &config_noc SLAVE_USB3_2 QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "usb-ddr",
+ "apps-usb";
+
+ wakeup-source;
+
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ status = "disabled";
+
+ usb_1_ss2_dwc3: usb@a000000 {
+ compatible = "snps,dwc3";
+ reg = <0 0x0a000000 0 0xcd00>;
+
+ interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+
+ iommus = <&apps_smmu 0x14a0 0x0>;
+
+ phys = <&usb_1_ss2_hsphy>,
+ <&usb_1_ss2_qmpphy QMP_USB43DP_USB3_PHY>;
+ phy-names = "usb2-phy",
+ "usb3-phy";
+
+ snps,dis_u2_susphy_quirk;
+ snps,dis_enblslpm_quirk;
+ snps,usb3_lpm_capable;
+
+ dma-coherent;
+
+ port {
+ usb_1_ss2_role_switch: endpoint {
+ };
+ };
+ };
+ };
+
+ usb_2: usb@a2f8800 {
+ compatible = "qcom,x1e80100-dwc3", "qcom,dwc3";
+ reg = <0 0x0a2f8800 0 0x400>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ clocks = <&gcc GCC_CFG_NOC_USB2_PRIM_AXI_CLK>,
+ <&gcc GCC_USB20_MASTER_CLK>,
+ <&gcc GCC_AGGRE_USB2_PRIM_AXI_CLK>,
+ <&gcc GCC_USB20_SLEEP_CLK>,
+ <&gcc GCC_USB20_MOCK_UTMI_CLK>,
+ <&gcc GCC_AGGRE_USB_NOC_AXI_CLK>,
+ <&gcc GCC_AGGRE_NOC_USB_NORTH_AXI_CLK>,
+ <&gcc GCC_AGGRE_NOC_USB_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_USB20_MOCK_UTMI_CLK>,
+ <&gcc GCC_USB20_MASTER_CLK>;
+ assigned-clock-rates = <19200000>, <200000000>;
+
+ interrupts-extended = <&intc GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+ <&pdc 50 IRQ_TYPE_EDGE_BOTH>,
+ <&pdc 49 IRQ_TYPE_EDGE_BOTH>;
+ interrupt-names = "pwr_event",
+ "dp_hs_phy_irq",
+ "dm_hs_phy_irq";
+
+ power-domains = <&gcc GCC_USB20_PRIM_GDSC>;
+ required-opps = <&rpmhpd_opp_nom>;
+
+ resets = <&gcc GCC_USB20_PRIM_BCR>;
+
+ interconnects = <&usb_north_anoc MASTER_USB2 QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+ <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+ &config_noc SLAVE_USB2 QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "usb-ddr",
+ "apps-usb";
+
+ wakeup-source;
+
+ status = "disabled";
+
+ usb_2_dwc3: usb@a200000 {
+ compatible = "snps,dwc3";
+ reg = <0 0x0a200000 0 0xcd00>;
+ interrupts = <GIC_SPI 241 IRQ_TYPE_LEVEL_HIGH>;
+ iommus = <&apps_smmu 0x14e0 0x0>;
+ phys = <&usb_2_hsphy>;
+ phy-names = "usb2-phy";
+ maximum-speed = "high-speed";
+
+ port {
+ usb_2_role_switch: endpoint {
+ };
+ };
+ };
+ };
+
+ usb_1_ss0: usb@a6f8800 {
+ compatible = "qcom,x1e80100-dwc3", "qcom,dwc3";
+ reg = <0 0x0a6f8800 0 0x400>;
+
+ clocks = <&gcc GCC_CFG_NOC_USB3_PRIM_AXI_CLK>,
+ <&gcc GCC_USB30_PRIM_MASTER_CLK>,
+ <&gcc GCC_AGGRE_USB3_PRIM_AXI_CLK>,
+ <&gcc GCC_USB30_PRIM_SLEEP_CLK>,
+ <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>,
+ <&gcc GCC_AGGRE_USB_NOC_AXI_CLK>,
+ <&gcc GCC_CFG_NOC_USB_ANOC_NORTH_AHB_CLK>,
+ <&gcc GCC_CFG_NOC_USB_ANOC_SOUTH_AHB_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_PRIM_MOCK_UTMI_CLK>,
+ <&gcc GCC_USB30_PRIM_MASTER_CLK>;
+ assigned-clock-rates = <19200000>,
+ <200000000>;
+
+ interrupts-extended = <&intc GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>,
+ <&pdc 61 IRQ_TYPE_EDGE_BOTH>,
+ <&pdc 15 IRQ_TYPE_EDGE_BOTH>,
+ <&pdc 17 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "pwr_event",
+ "dp_hs_phy_irq",
+ "dm_hs_phy_irq",
+ "ss_phy_irq";
+
+ power-domains = <&gcc GCC_USB30_PRIM_GDSC>;
+ required-opps = <&rpmhpd_opp_nom>;
+
+ resets = <&gcc GCC_USB30_PRIM_BCR>;
+
+ wakeup-source;
+
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ status = "disabled";
+
+ usb_1_ss0_dwc3: usb@a600000 {
+ compatible = "snps,dwc3";
+ reg = <0 0x0a600000 0 0xcd00>;
+
+ interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+
+ iommus = <&apps_smmu 0x1420 0x0>;
+
+ phys = <&usb_1_ss0_hsphy>,
+ <&usb_1_ss0_qmpphy QMP_USB43DP_USB3_PHY>;
+ phy-names = "usb2-phy",
+ "usb3-phy";
+
+ snps,dis_u2_susphy_quirk;
+ snps,dis_enblslpm_quirk;
+ snps,usb3_lpm_capable;
+
+ dma-coherent;
+
+ port {
+ usb_1_ss0_role_switch: endpoint {
+ };
+ };
+ };
+ };
+
+ usb_1_ss1: usb@a8f8800 {
+ compatible = "qcom,x1e80100-dwc3", "qcom,dwc3";
+ reg = <0 0x0a8f8800 0 0x400>;
+
+ clocks = <&gcc GCC_CFG_NOC_USB3_SEC_AXI_CLK>,
+ <&gcc GCC_USB30_SEC_MASTER_CLK>,
+ <&gcc GCC_AGGRE_USB3_SEC_AXI_CLK>,
+ <&gcc GCC_USB30_SEC_SLEEP_CLK>,
+ <&gcc GCC_USB30_SEC_MOCK_UTMI_CLK>,
+ <&gcc GCC_AGGRE_USB_NOC_AXI_CLK>,
+ <&gcc GCC_AGGRE_NOC_USB_NORTH_AXI_CLK>,
+ <&gcc GCC_AGGRE_NOC_USB_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_SEC_MOCK_UTMI_CLK>,
+ <&gcc GCC_USB30_SEC_MASTER_CLK>;
+ assigned-clock-rates = <19200000>,
+ <200000000>;
+
+ interrupts-extended = <&intc GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>,
+ <&pdc 60 IRQ_TYPE_EDGE_BOTH>,
+ <&pdc 11 IRQ_TYPE_EDGE_BOTH>,
+ <&pdc 47 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "pwr_event",
+ "dp_hs_phy_irq",
+ "dm_hs_phy_irq",
+ "ss_phy_irq";
+
+ power-domains = <&gcc GCC_USB30_SEC_GDSC>;
+ required-opps = <&rpmhpd_opp_nom>;
+
+ resets = <&gcc GCC_USB30_SEC_BCR>;
+
+ interconnects = <&usb_south_anoc MASTER_USB3_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_USB3_1 QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "usb-ddr",
+ "apps-usb";
+
+ wakeup-source;
+
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ status = "disabled";
+
+ usb_1_ss1_dwc3: usb@a800000 {
+ compatible = "snps,dwc3";
+ reg = <0 0x0a800000 0 0xcd00>;
+
+ interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+
+ iommus = <&apps_smmu 0x1460 0x0>;
+
+ phys = <&usb_1_ss1_hsphy>,
+ <&usb_1_ss1_qmpphy QMP_USB43DP_USB3_PHY>;
+ phy-names = "usb2-phy",
+ "usb3-phy";
+
+ snps,dis_u2_susphy_quirk;
+ snps,dis_enblslpm_quirk;
+ snps,usb3_lpm_capable;
+
+ dma-coherent;
+
+ port {
+ usb_1_ss1_role_switch: endpoint {
+ };
+ };
+ };
+ };
+
+ mdss: display-subsystem@ae00000 {
+ compatible = "qcom,x1e80100-mdss";
+ reg = <0 0x0ae00000 0 0x1000>;
+ reg-names = "mdss";
+
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+
+ clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
+ <&gcc GCC_DISP_HF_AXI_CLK>,
+ <&dispcc DISP_CC_MDSS_MDP_CLK>;
+
+ resets = <&dispcc DISP_CC_MDSS_CORE_BCR>;
+
+ interconnects = <&mmss_noc MASTER_MDP QCOM_ICC_TAG_ALWAYS
+ &gem_noc SLAVE_LLCC QCOM_ICC_TAG_ALWAYS>,
+ <&mc_virt MASTER_LLCC QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+ <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+ &config_noc SLAVE_DISPLAY_CFG QCOM_ICC_TAG_ACTIVE_ONLY>;
+ interconnect-names = "mdp0-mem",
+ "mdp1-mem",
+ "cpu-cfg";
+
+ power-domains = <&dispcc MDSS_GDSC>;
+
+ iommus = <&apps_smmu 0x1c00 0x2>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ status = "disabled";
+
+ mdss_mdp: display-controller@ae01000 {
+ compatible = "qcom,x1e80100-dpu";
+ reg = <0 0x0ae01000 0 0x8f000>,
+ <0 0x0aeb0000 0 0x2008>;
+ reg-names = "mdp",
+ "vbif";
+
+ interrupts-extended = <&mdss 0>;
+
+ clocks = <&gcc GCC_DISP_HF_AXI_CLK>,
+ <&dispcc DISP_CC_MDSS_AHB_CLK>,
+ <&dispcc DISP_CC_MDSS_MDP_LUT_CLK>,
+ <&dispcc DISP_CC_MDSS_MDP_CLK>,
+ <&dispcc DISP_CC_MDSS_VSYNC_CLK>;
+ clock-names = "nrt_bus",
+ "iface",
+ "lut",
+ "core",
+ "vsync";
+
+ operating-points-v2 = <&mdp_opp_table>;
+
+ power-domains = <&rpmhpd RPMHPD_MMCX>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ mdss_intf0_out: endpoint {
+ remote-endpoint = <&mdss_dp0_in>;
+ };
+ };
+
+ port@4 {
+ reg = <4>;
+
+ mdss_intf4_out: endpoint {
+ remote-endpoint = <&mdss_dp1_in>;
+ };
+ };
+
+ port@5 {
+ reg = <5>;
+
+ mdss_intf5_out: endpoint {
+ remote-endpoint = <&mdss_dp3_in>;
+ };
+ };
+
+ port@6 {
+ reg = <6>;
+
+ mdss_intf6_out: endpoint {
+ remote-endpoint = <&mdss_dp2_in>;
+ };
+ };
+ };
+
+ mdp_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-200000000 {
+ opp-hz = /bits/ 64 <200000000>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ };
+
+ opp-325000000 {
+ opp-hz = /bits/ 64 <325000000>;
+ required-opps = <&rpmhpd_opp_svs>;
+ };
+
+ opp-375000000 {
+ opp-hz = /bits/ 64 <375000000>;
+ required-opps = <&rpmhpd_opp_svs_l1>;
+ };
+
+ opp-514000000 {
+ opp-hz = /bits/ 64 <514000000>;
+ required-opps = <&rpmhpd_opp_nom>;
+ };
+
+ opp-575000000 {
+ opp-hz = /bits/ 64 <575000000>;
+ required-opps = <&rpmhpd_opp_nom_l1>;
+ };
+ };
+ };
+
+ mdss_dp0: displayport-controller@ae90000 {
+ compatible = "qcom,x1e80100-dp";
+ reg = <0 0xae90000 0 0x200>,
+ <0 0xae90200 0 0x200>,
+ <0 0xae90400 0 0x600>,
+ <0 0xae91000 0 0x400>,
+ <0 0xae91400 0 0x400>;
+
+ interrupts-extended = <&mdss 12>;
+
+ clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
+ <&dispcc DISP_CC_MDSS_DPTX0_AUX_CLK>,
+ <&dispcc DISP_CC_MDSS_DPTX0_LINK_CLK>,
+ <&dispcc DISP_CC_MDSS_DPTX0_LINK_INTF_CLK>,
+ <&dispcc DISP_CC_MDSS_DPTX0_PIXEL0_CLK>;
+ clock-names = "core_iface",
+ "core_aux",
+ "ctrl_link",
+ "ctrl_link_iface",
+ "stream_pixel";
+
+ assigned-clocks = <&dispcc DISP_CC_MDSS_DPTX0_LINK_CLK_SRC>,
+ <&dispcc DISP_CC_MDSS_DPTX0_PIXEL0_CLK_SRC>;
+ assigned-clock-parents = <&usb_1_ss0_qmpphy QMP_USB43DP_DP_LINK_CLK>,
+ <&usb_1_ss0_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>;
+
+ operating-points-v2 = <&mdss_dp0_opp_table>;
+
+ power-domains = <&rpmhpd RPMHPD_MMCX>;
+
+ phys = <&usb_1_ss0_qmpphy QMP_USB43DP_DP_PHY>;
+ phy-names = "dp";
+
+ #sound-dai-cells = <0>;
+
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ mdss_dp0_in: endpoint {
+ remote-endpoint = <&mdss_intf0_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ mdss_dp0_out: endpoint {
+ };
+ };
+ };
+
+ mdss_dp0_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_dp1: displayport-controller@ae98000 {
+ compatible = "qcom,x1e80100-dp";
+ reg = <0 0xae98000 0 0x200>,
+ <0 0xae98200 0 0x200>,
+ <0 0xae98400 0 0x600>,
+ <0 0xae99000 0 0x400>,
+ <0 0xae99400 0 0x400>;
+
+ interrupts-extended = <&mdss 13>;
+
+ clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
+ <&dispcc DISP_CC_MDSS_DPTX1_AUX_CLK>,
+ <&dispcc DISP_CC_MDSS_DPTX1_LINK_CLK>,
+ <&dispcc DISP_CC_MDSS_DPTX1_LINK_INTF_CLK>,
+ <&dispcc DISP_CC_MDSS_DPTX1_PIXEL0_CLK>;
+ clock-names = "core_iface",
+ "core_aux",
+ "ctrl_link",
+ "ctrl_link_iface",
+ "stream_pixel";
+
+ assigned-clocks = <&dispcc DISP_CC_MDSS_DPTX1_LINK_CLK_SRC>,
+ <&dispcc DISP_CC_MDSS_DPTX1_PIXEL0_CLK_SRC>;
+ assigned-clock-parents = <&usb_1_ss1_qmpphy QMP_USB43DP_DP_LINK_CLK>,
+ <&usb_1_ss1_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>;
+
+ operating-points-v2 = <&mdss_dp1_opp_table>;
+
+ power-domains = <&rpmhpd RPMHPD_MMCX>;
+
+ phys = <&usb_1_ss1_qmpphy QMP_USB43DP_DP_PHY>;
+ phy-names = "dp";
+
+ #sound-dai-cells = <0>;
+
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ mdss_dp1_in: endpoint {
+ remote-endpoint = <&mdss_intf4_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ mdss_dp1_out: endpoint {
+ };
+ };
+ };
+
+ mdss_dp1_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_dp2: displayport-controller@ae9a000 {
+ compatible = "qcom,x1e80100-dp";
+ reg = <0 0xae9a000 0 0x200>,
+ <0 0xae9a200 0 0x200>,
+ <0 0xae9a400 0 0x600>,
+ <0 0xae9b000 0 0x400>,
+ <0 0xae9b400 0 0x400>;
+
+ interrupts-extended = <&mdss 14>;
+
+ clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
+ <&dispcc DISP_CC_MDSS_DPTX2_AUX_CLK>,
+ <&dispcc DISP_CC_MDSS_DPTX2_LINK_CLK>,
+ <&dispcc DISP_CC_MDSS_DPTX2_LINK_INTF_CLK>,
+ <&dispcc DISP_CC_MDSS_DPTX2_PIXEL0_CLK>;
+ clock-names = "core_iface",
+ "core_aux",
+ "ctrl_link",
+ "ctrl_link_iface",
+ "stream_pixel";
+
+ assigned-clocks = <&dispcc DISP_CC_MDSS_DPTX2_LINK_CLK_SRC>,
+ <&dispcc DISP_CC_MDSS_DPTX2_PIXEL0_CLK_SRC>;
+ assigned-clock-parents = <&mdss_dp2_phy 0>,
+ <&mdss_dp2_phy 1>;
+
+ operating-points-v2 = <&mdss_dp2_opp_table>;
+
+ power-domains = <&rpmhpd RPMHPD_MMCX>;
+
+ phys = <&mdss_dp2_phy>;
+ phy-names = "dp";
+
+ #sound-dai-cells = <0>;
+
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ mdss_dp2_in: endpoint {
+ remote-endpoint = <&mdss_intf6_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ };
+ };
+
+ mdss_dp2_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_dp3: displayport-controller@aea0000 {
+ compatible = "qcom,x1e80100-dp";
+ reg = <0 0xaea0000 0 0x200>,
+ <0 0xaea0200 0 0x200>,
+ <0 0xaea0400 0 0x600>,
+ <0 0xaea1000 0 0x400>,
+ <0 0xaea1400 0 0x400>;
+
+ interrupts-extended = <&mdss 15>;
+
+ clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
+ <&dispcc DISP_CC_MDSS_DPTX3_AUX_CLK>,
+ <&dispcc DISP_CC_MDSS_DPTX3_LINK_CLK>,
+ <&dispcc DISP_CC_MDSS_DPTX3_LINK_INTF_CLK>,
+ <&dispcc DISP_CC_MDSS_DPTX3_PIXEL0_CLK>;
+ clock-names = "core_iface",
+ "core_aux",
+ "ctrl_link",
+ "ctrl_link_iface",
+ "stream_pixel";
+
+ assigned-clocks = <&dispcc DISP_CC_MDSS_DPTX3_LINK_CLK_SRC>,
+ <&dispcc DISP_CC_MDSS_DPTX3_PIXEL0_CLK_SRC>;
+ assigned-clock-parents = <&mdss_dp3_phy 0>,
+ <&mdss_dp3_phy 1>;
+
+ operating-points-v2 = <&mdss_dp3_opp_table>;
+
+ power-domains = <&rpmhpd RPMHPD_MMCX>;
+
+ phys = <&mdss_dp3_phy>;
+ phy-names = "dp";
+
+ #sound-dai-cells = <0>;
+
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ mdss_dp3_in: endpoint {
+ remote-endpoint = <&mdss_intf5_out>;
+
+ link-frequencies = /bits/ 64 <8100000000>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ };
+ };
+
+ mdss_dp3_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_dp2_phy: phy@aec2a00 {
+ compatible = "qcom,x1e80100-dp-phy";
+ reg = <0 0x0aec2a00 0 0x19c>,
+ <0 0x0aec2200 0 0xec>,
+ <0 0x0aec2600 0 0xec>,
+ <0 0x0aec2000 0 0x1c8>;
+
+ clocks = <&dispcc DISP_CC_MDSS_DPTX2_AUX_CLK>,
+ <&dispcc DISP_CC_MDSS_AHB_CLK>;
+ clock-names = "aux",
+ "cfg_ahb";
+
+ power-domains = <&rpmhpd RPMHPD_MX>;
+
+ #clock-cells = <1>;
+ #phy-cells = <0>;
+
+ status = "disabled";
+ };
+
+ mdss_dp3_phy: phy@aec5a00 {
+ compatible = "qcom,x1e80100-dp-phy";
+ reg = <0 0x0aec5a00 0 0x19c>,
+ <0 0x0aec5200 0 0xec>,
+ <0 0x0aec5600 0 0xec>,
+ <0 0x0aec5000 0 0x1c8>;
+
+ clocks = <&dispcc DISP_CC_MDSS_DPTX3_AUX_CLK>,
+ <&dispcc DISP_CC_MDSS_AHB_CLK>;
+ clock-names = "aux",
+ "cfg_ahb";
+
+ power-domains = <&rpmhpd RPMHPD_MX>;
+
+ #clock-cells = <1>;
+ #phy-cells = <0>;
+
+ status = "disabled";
+ };
+
+ dispcc: clock-controller@af00000 {
+ compatible = "qcom,x1e80100-dispcc";
+ reg = <0 0x0af00000 0 0x20000>;
+ clocks = <&bi_tcxo_div2>,
+ <&bi_tcxo_ao_div2>,
+ <&gcc GCC_DISP_AHB_CLK>,
+ <&sleep_clk>,
+ <0>, /* dsi0 */
+ <0>,
+ <0>, /* dsi1 */
+ <0>,
+ <&usb_1_ss0_qmpphy QMP_USB43DP_DP_LINK_CLK>, /* dp0 */
+ <&usb_1_ss0_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>,
+ <&usb_1_ss1_qmpphy QMP_USB43DP_DP_LINK_CLK>, /* dp1 */
+ <&usb_1_ss1_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>,
+ <&mdss_dp2_phy 0>, /* dp2 */
+ <&mdss_dp2_phy 1>,
+ <&mdss_dp3_phy 0>, /* dp3 */
+ <&mdss_dp3_phy 1>;
+ power-domains = <&rpmhpd RPMHPD_MMCX>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ #power-domain-cells = <1>;
+ };
+
pdc: interrupt-controller@b220000 {
compatible = "qcom,x1e80100-pdc", "qcom,pdc";
reg = <0 0x0b220000 0 0x30000>, <0 0x174000f0 0 0x64>;
@@ -2599,6 +4210,18 @@
interrupt-controller;
};
+ aoss_qmp: power-management@c300000 {
+ compatible = "qcom,x1e80100-aoss-qmp", "qcom,aoss-qmp";
+ reg = <0 0x0c300000 0 0x400>;
+ 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>;
+ };
+
+
tlmm: pinctrl@f100000 {
compatible = "qcom,x1e80100-tlmm";
reg = <0 0x0f100000 0 0xf00000>;
@@ -3170,7 +4793,7 @@
/* TX, RX */
pins = "gpio86", "gpio87";
function = "qup2_se5";
- drive-strength= <2>;
+ drive-strength = <2>;
bias-disable;
};
};
@@ -3315,7 +4938,6 @@
<0 0x17510000 0 0x10000>,
<0 0x17520000 0 0x10000>;
reg-names = "drv-0", "drv-1", "drv-2";
- qcom,drv-count = <3>;
interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
@@ -3326,6 +4948,7 @@
<WAKE_TCS 2>, <CONTROL_TCS 0>;
label = "apps_rsc";
+ power-domains = <&SYSTEM_PD>;
apps_bcm_voter: bcm-voter {
compatible = "qcom,bcm-voter";
@@ -3514,6 +5137,144 @@
"llcc_broadcast_base";
interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
};
+
+ remoteproc_adsp: remoteproc@30000000 {
+ compatible = "qcom,x1e80100-adsp-pas";
+ reg = <0 0x30000000 0 0x100>;
+
+ interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>,
+ <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>,
+ <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>,
+ <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>,
+ <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "wdog",
+ "fatal",
+ "ready",
+ "handover",
+ "stop-ack";
+
+ clocks = <&rpmhcc RPMH_CXO_CLK>;
+ clock-names = "xo";
+
+ power-domains = <&rpmhpd RPMHPD_LCX>,
+ <&rpmhpd RPMHPD_LMX>;
+ power-domain-names = "lcx",
+ "lmx";
+
+ interconnects = <&lpass_lpicx_noc MASTER_LPASS_PROC QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+
+ memory-region = <&adspslpi_mem>,
+ <&q6_adsp_dtb_mem>;
+
+ qcom,qmp = <&aoss_qmp>;
+
+ qcom,smem-states = <&smp2p_adsp_out 0>;
+ qcom,smem-state-names = "stop";
+
+ status = "disabled";
+
+ glink-edge {
+ interrupts-extended = <&ipcc IPCC_CLIENT_LPASS
+ IPCC_MPROC_SIGNAL_GLINK_QMP
+ IRQ_TYPE_EDGE_RISING>;
+ mboxes = <&ipcc IPCC_CLIENT_LPASS
+ IPCC_MPROC_SIGNAL_GLINK_QMP>;
+
+ label = "lpass";
+ qcom,remote-pid = <2>;
+
+ gpr {
+ compatible = "qcom,gpr";
+ qcom,glink-channels = "adsp_apps";
+ qcom,domain = <GPR_DOMAIN_ID_ADSP>;
+ qcom,intents = <512 20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ q6apm: service@1 {
+ compatible = "qcom,q6apm";
+ reg = <GPR_APM_MODULE_IID>;
+ #sound-dai-cells = <0>;
+ qcom,protection-domain = "avs/audio",
+ "msm/adsp/audio_pd";
+
+ q6apmbedai: bedais {
+ compatible = "qcom,q6apm-lpass-dais";
+ #sound-dai-cells = <1>;
+ };
+
+ q6apmdai: dais {
+ compatible = "qcom,q6apm-dais";
+ iommus = <&apps_smmu 0x1001 0x80>,
+ <&apps_smmu 0x1061 0x0>;
+ };
+ };
+
+ q6prm: service@2 {
+ compatible = "qcom,q6prm";
+ reg = <GPR_PRM_MODULE_IID>;
+ qcom,protection-domain = "avs/audio",
+ "msm/adsp/audio_pd";
+
+ q6prmcc: clock-controller {
+ compatible = "qcom,q6prm-lpass-clocks";
+ #clock-cells = <2>;
+ };
+ };
+ };
+ };
+ };
+
+ remoteproc_cdsp: remoteproc@32300000 {
+ compatible = "qcom,x1e80100-cdsp-pas";
+ reg = <0 0x32300000 0 0x1400000>;
+
+ interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>,
+ <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>,
+ <&smp2p_cdsp_in 1 IRQ_TYPE_EDGE_RISING>,
+ <&smp2p_cdsp_in 2 IRQ_TYPE_EDGE_RISING>,
+ <&smp2p_cdsp_in 3 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "wdog",
+ "fatal",
+ "ready",
+ "handover",
+ "stop-ack";
+
+ clocks = <&rpmhcc RPMH_CXO_CLK>;
+ clock-names = "xo";
+
+ power-domains = <&rpmhpd RPMHPD_CX>,
+ <&rpmhpd RPMHPD_MXC>,
+ <&rpmhpd RPMHPD_NSP>;
+ power-domain-names = "cx",
+ "mxc",
+ "nsp";
+
+ interconnects = <&nsp_noc MASTER_CDSP_PROC QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+
+ memory-region = <&cdsp_mem>,
+ <&q6_cdsp_dtb_mem>;
+
+ qcom,qmp = <&aoss_qmp>;
+
+ qcom,smem-states = <&smp2p_cdsp_out 0>;
+ qcom,smem-state-names = "stop";
+
+ status = "disabled";
+
+ glink-edge {
+ interrupts-extended = <&ipcc IPCC_CLIENT_CDSP
+ IPCC_MPROC_SIGNAL_GLINK_QMP
+ IRQ_TYPE_EDGE_RISING>;
+ mboxes = <&ipcc IPCC_CLIENT_CDSP
+ IPCC_MPROC_SIGNAL_GLINK_QMP>;
+
+ label = "cdsp";
+ qcom,remote-pid = <5>;
+ };
+ };
};
timer {
diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile
index 8ea68d582710..5f3e0e61d78d 100644
--- a/arch/arm64/boot/dts/renesas/Makefile
+++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -82,10 +82,15 @@ dtb-$(CONFIG_ARCH_R8A779F0) += r8a779f0-spider.dtb
dtb-$(CONFIG_ARCH_R8A779F0) += r8a779f4-s4sk.dtb
dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g0-white-hawk.dtb
+dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g0-white-hawk-cpu.dtb
dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g0-white-hawk-ard-audio-da7212.dtbo
r8a779g0-white-hawk-ard-audio-da7212-dtbs := r8a779g0-white-hawk.dtb r8a779g0-white-hawk-ard-audio-da7212.dtbo
dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g0-white-hawk-ard-audio-da7212.dtb
+dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g2-white-hawk-single.dtb
+
+dtb-$(CONFIG_ARCH_R8A779H0) += r8a779h0-gray-hawk-single.dtb
+
dtb-$(CONFIG_ARCH_R8A77951) += r8a779m1-salvator-xs.dtb
r8a779m1-salvator-xs-panel-aa104xd12-dtbs := r8a779m1-salvator-xs.dtb salvator-panel-aa104xd12.dtbo
dtb-$(CONFIG_ARCH_R8A77951) += r8a779m1-salvator-xs-panel-aa104xd12.dtb
@@ -103,7 +108,10 @@ r8a779m5-salvator-xs-panel-aa104xd12-dtbs := r8a779m5-salvator-xs.dtb salvator-p
dtb-$(CONFIG_ARCH_R8A77965) += r8a779m5-salvator-xs-panel-aa104xd12.dtb
dtb-$(CONFIG_ARCH_R9A07G043) += r9a07g043u11-smarc.dtb
+dtb-$(CONFIG_ARCH_R9A07G043) += r9a07g043u11-smarc-cru-csi-ov5645.dtbo
dtb-$(CONFIG_ARCH_R9A07G043) += r9a07g043-smarc-pmod.dtbo
+r9a07g043u11-smarc-cru-csi-ov5645-dtbs := r9a07g043u11-smarc.dtb r9a07g043u11-smarc-cru-csi-ov5645.dtbo
+dtb-$(CONFIG_ARCH_R9A07G043) += r9a07g043u11-smarc-cru-csi-ov5645.dtb
r9a07g043u11-smarc-pmod-dtbs := r9a07g043u11-smarc.dtb r9a07g043-smarc-pmod.dtbo
dtb-$(CONFIG_ARCH_R9A07G043) += r9a07g043u11-smarc-pmod.dtb
diff --git a/arch/arm64/boot/dts/renesas/r8a774a1.dtsi b/arch/arm64/boot/dts/renesas/r8a774a1.dtsi
index 95b0a1f6debf..a8a44fe5e83b 100644
--- a/arch/arm64/boot/dts/renesas/r8a774a1.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a774a1.dtsi
@@ -529,6 +529,7 @@
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 R8A774A1_PD_ALWAYS_ON>;
@@ -541,7 +542,9 @@
reg = <0 0xe6fc0000 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 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 124>;
clock-names = "fck";
power-domains = <&sysc R8A774A1_PD_ALWAYS_ON>;
@@ -554,7 +557,9 @@
reg = <0 0xe6fd0000 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 305 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 123>;
clock-names = "fck";
power-domains = <&sysc R8A774A1_PD_ALWAYS_ON>;
@@ -568,6 +573,7 @@
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 122>;
clock-names = "fck";
power-domains = <&sysc R8A774A1_PD_ALWAYS_ON>;
@@ -581,6 +587,7 @@
interrupts = <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
clocks = <&cpg CPG_MOD 121>;
clock-names = "fck";
power-domains = <&sysc R8A774A1_PD_ALWAYS_ON>;
diff --git a/arch/arm64/boot/dts/renesas/r8a774b1.dtsi b/arch/arm64/boot/dts/renesas/r8a774b1.dtsi
index 786660fcdea4..4fff511e994c 100644
--- a/arch/arm64/boot/dts/renesas/r8a774b1.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a774b1.dtsi
@@ -413,6 +413,7 @@
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 R8A774B1_PD_ALWAYS_ON>;
@@ -425,7 +426,9 @@
reg = <0 0xe6fc0000 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 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 124>;
clock-names = "fck";
power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
@@ -438,7 +441,9 @@
reg = <0 0xe6fd0000 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 305 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 123>;
clock-names = "fck";
power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
@@ -452,6 +457,7 @@
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 122>;
clock-names = "fck";
power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
@@ -465,6 +471,7 @@
interrupts = <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
clocks = <&cpg CPG_MOD 121>;
clock-names = "fck";
power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>;
diff --git a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
index eed94ffed7c1..1ef43d78c3a5 100644
--- a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
@@ -384,6 +384,7 @@
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 R8A774C0_PD_ALWAYS_ON>;
@@ -396,7 +397,9 @@
reg = <0 0xe6fc0000 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 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 124>;
clock-names = "fck";
power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
@@ -409,7 +412,9 @@
reg = <0 0xe6fd0000 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 305 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 123>;
clock-names = "fck";
power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
@@ -423,6 +428,7 @@
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 122>;
clock-names = "fck";
power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
@@ -436,6 +442,7 @@
interrupts = <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
clocks = <&cpg CPG_MOD 121>;
clock-names = "fck";
power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
diff --git a/arch/arm64/boot/dts/renesas/r8a774e1.dtsi b/arch/arm64/boot/dts/renesas/r8a774e1.dtsi
index 175e5d296da6..be55ae83944c 100644
--- a/arch/arm64/boot/dts/renesas/r8a774e1.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a774e1.dtsi
@@ -593,6 +593,7 @@
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 R8A774E1_PD_ALWAYS_ON>;
@@ -605,7 +606,9 @@
reg = <0 0xe6fc0000 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 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 124>;
clock-names = "fck";
power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>;
@@ -618,7 +621,9 @@
reg = <0 0xe6fd0000 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 305 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 123>;
clock-names = "fck";
power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>;
@@ -632,6 +637,7 @@
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 122>;
clock-names = "fck";
power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>;
@@ -645,6 +651,7 @@
interrupts = <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
clocks = <&cpg CPG_MOD 121>;
clock-names = "fck";
power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>;
diff --git a/arch/arm64/boot/dts/renesas/r8a77951.dtsi b/arch/arm64/boot/dts/renesas/r8a77951.dtsi
index a4260d9291ba..bea4edd17d53 100644
--- a/arch/arm64/boot/dts/renesas/r8a77951.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77951.dtsi
@@ -614,6 +614,7 @@
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 R8A7795_PD_ALWAYS_ON>;
@@ -626,7 +627,9 @@
reg = <0 0xe6fc0000 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 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 124>;
clock-names = "fck";
power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
@@ -639,7 +642,9 @@
reg = <0 0xe6fd0000 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 305 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 123>;
clock-names = "fck";
power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
@@ -653,6 +658,7 @@
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 122>;
clock-names = "fck";
power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
@@ -666,6 +672,7 @@
interrupts = <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
clocks = <&cpg CPG_MOD 121>;
clock-names = "fck";
power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
diff --git a/arch/arm64/boot/dts/renesas/r8a77960.dtsi b/arch/arm64/boot/dts/renesas/r8a77960.dtsi
index a631ead171b2..7846fea8e40d 100644
--- a/arch/arm64/boot/dts/renesas/r8a77960.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77960.dtsi
@@ -578,6 +578,7 @@
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 R8A7796_PD_ALWAYS_ON>;
@@ -590,7 +591,9 @@
reg = <0 0xe6fc0000 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 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 124>;
clock-names = "fck";
power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
@@ -603,7 +606,9 @@
reg = <0 0xe6fd0000 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 305 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 123>;
clock-names = "fck";
power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
@@ -617,6 +622,7 @@
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 122>;
clock-names = "fck";
power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
@@ -630,6 +636,7 @@
interrupts = <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
clocks = <&cpg CPG_MOD 121>;
clock-names = "fck";
power-domains = <&sysc R8A7796_PD_ALWAYS_ON>;
diff --git a/arch/arm64/boot/dts/renesas/r8a77961.dtsi b/arch/arm64/boot/dts/renesas/r8a77961.dtsi
index 7254912a241f..58f9286a5ab5 100644
--- a/arch/arm64/boot/dts/renesas/r8a77961.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77961.dtsi
@@ -578,6 +578,7 @@
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 R8A77961_PD_ALWAYS_ON>;
@@ -590,7 +591,9 @@
reg = <0 0xe6fc0000 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 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 124>;
clock-names = "fck";
power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
@@ -603,7 +606,9 @@
reg = <0 0xe6fd0000 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 305 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 123>;
clock-names = "fck";
power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
@@ -617,6 +622,7 @@
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 122>;
clock-names = "fck";
power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
@@ -630,6 +636,7 @@
interrupts = <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
clocks = <&cpg CPG_MOD 121>;
clock-names = "fck";
power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
diff --git a/arch/arm64/boot/dts/renesas/r8a77965.dtsi b/arch/arm64/boot/dts/renesas/r8a77965.dtsi
index e57b9027066e..692940662d38 100644
--- a/arch/arm64/boot/dts/renesas/r8a77965.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77965.dtsi
@@ -449,6 +449,7 @@
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 R8A77965_PD_ALWAYS_ON>;
@@ -461,7 +462,9 @@
reg = <0 0xe6fc0000 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 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 124>;
clock-names = "fck";
power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
@@ -474,7 +477,9 @@
reg = <0 0xe6fd0000 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 305 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 123>;
clock-names = "fck";
power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
@@ -488,6 +493,7 @@
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 122>;
clock-names = "fck";
power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
@@ -501,6 +507,7 @@
interrupts = <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
clocks = <&cpg CPG_MOD 121>;
clock-names = "fck";
power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
index ed6e2e47c604..d2d3cecc76d5 100644
--- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
@@ -328,6 +328,7 @@
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 R8A77970_PD_ALWAYS_ON>;
@@ -340,7 +341,9 @@
reg = <0 0xe6fc0000 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 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 124>;
clock-names = "fck";
power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
@@ -353,7 +356,9 @@
reg = <0 0xe6fd0000 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 305 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 123>;
clock-names = "fck";
power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
@@ -367,6 +372,7 @@
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 122>;
clock-names = "fck";
power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
@@ -380,6 +386,7 @@
interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
clocks = <&cpg CPG_MOD 121>;
clock-names = "fck";
power-domains = <&sysc R8A77970_PD_ALWAYS_ON>;
diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
index 5ed2daaca1f0..c0ba110c74d6 100644
--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
@@ -357,6 +357,7 @@
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 R8A77980_PD_ALWAYS_ON>;
@@ -369,7 +370,9 @@
reg = <0 0xe6fc0000 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 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 124>;
clock-names = "fck";
power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
@@ -382,7 +385,9 @@
reg = <0 0xe6fd0000 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 305 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 123>;
clock-names = "fck";
power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
@@ -395,7 +400,9 @@
reg = <0 0xe6fe0000 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 133 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 122>;
clock-names = "fck";
power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
@@ -408,7 +415,9 @@
reg = <0 0xffc00000 0 0x30>;
interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+ <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 369 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 121>;
clock-names = "fck";
power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
index 8c2b28342387..37063e3f4e1b 100644
--- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
@@ -415,6 +415,7 @@
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 R8A77990_PD_ALWAYS_ON>;
@@ -427,7 +428,9 @@
reg = <0 0xe6fc0000 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 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 124>;
clock-names = "fck";
power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
@@ -440,7 +443,9 @@
reg = <0 0xe6fd0000 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 305 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 123>;
clock-names = "fck";
power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
@@ -454,6 +459,7 @@
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 122>;
clock-names = "fck";
power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
@@ -467,6 +473,7 @@
interrupts = <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
clocks = <&cpg CPG_MOD 121>;
clock-names = "fck";
power-domains = <&sysc R8A77990_PD_ALWAYS_ON>;
diff --git a/arch/arm64/boot/dts/renesas/r8a77995.dtsi b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
index 8cf6473c63d3..89990dd8ebf7 100644
--- a/arch/arm64/boot/dts/renesas/r8a77995.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
@@ -336,6 +336,7 @@
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 R8A77995_PD_ALWAYS_ON>;
@@ -348,7 +349,9 @@
reg = <0 0xe6fc0000 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 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 124>;
clock-names = "fck";
power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
@@ -361,7 +364,9 @@
reg = <0 0xe6fd0000 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 305 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 123>;
clock-names = "fck";
power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
@@ -375,6 +380,7 @@
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 122>;
clock-names = "fck";
power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
@@ -388,6 +394,7 @@
interrupts = <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
clocks = <&cpg CPG_MOD 121>;
clock-names = "fck";
power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
diff --git a/arch/arm64/boot/dts/renesas/r8a779a0.dtsi b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi
index 4e67a0356497..cfa70b441e32 100644
--- a/arch/arm64/boot/dts/renesas/r8a779a0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi
@@ -370,6 +370,7 @@
interrupts = <GIC_SPI 512 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 513 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 514 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
clocks = <&cpg CPG_MOD 713>;
clock-names = "fck";
power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>;
@@ -382,7 +383,9 @@
reg = <0 0xe6fc0000 0 0x30>;
interrupts = <GIC_SPI 504 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 505 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 506 IRQ_TYPE_LEVEL_HIGH>;
+ <GIC_SPI 506 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 507 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 714>;
clock-names = "fck";
power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>;
@@ -395,7 +398,9 @@
reg = <0 0xe6fd0000 0 0x30>;
interrupts = <GIC_SPI 508 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 509 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 510 IRQ_TYPE_LEVEL_HIGH>;
+ <GIC_SPI 510 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 511 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 715>;
clock-names = "fck";
power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>;
@@ -408,7 +413,9 @@
reg = <0 0xe6fe0000 0 0x30>;
interrupts = <GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>;
+ <GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 475 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 716>;
clock-names = "fck";
power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>;
@@ -421,7 +428,9 @@
reg = <0 0xffc00000 0 0x30>;
interrupts = <GIC_SPI 476 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 477 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 478 IRQ_TYPE_LEVEL_HIGH>;
+ <GIC_SPI 478 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 479 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 717>;
clock-names = "fck";
power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>;
@@ -658,7 +667,7 @@
avb0: ethernet@e6800000 {
compatible = "renesas,etheravb-r8a779a0",
"renesas,etheravb-rcar-gen4";
- reg = <0 0xe6800000 0 0x800>;
+ reg = <0 0xe6800000 0 0x1000>;
interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 257 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH>,
@@ -706,7 +715,7 @@
avb1: ethernet@e6810000 {
compatible = "renesas,etheravb-r8a779a0",
"renesas,etheravb-rcar-gen4";
- reg = <0 0xe6810000 0 0x800>;
+ reg = <0 0xe6810000 0 0x1000>;
interrupts = <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm64/boot/dts/renesas/r8a779f0.dtsi b/arch/arm64/boot/dts/renesas/r8a779f0.dtsi
index 7fb4989cce8a..72cf30341fc4 100644
--- a/arch/arm64/boot/dts/renesas/r8a779f0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779f0.dtsi
@@ -501,6 +501,7 @@
interrupts = <GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 475 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 476 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2";
clocks = <&cpg CPG_MOD 713>;
clock-names = "fck";
power-domains = <&sysc R8A779F0_PD_ALWAYS_ON>;
@@ -513,7 +514,9 @@
reg = <0 0xe6fc0000 0 0x30>;
interrupts = <GIC_SPI 477 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 478 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 479 IRQ_TYPE_LEVEL_HIGH>;
+ <GIC_SPI 479 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 480 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 714>;
clock-names = "fck";
power-domains = <&sysc R8A779F0_PD_ALWAYS_ON>;
@@ -526,7 +529,9 @@
reg = <0 0xe6fd0000 0 0x30>;
interrupts = <GIC_SPI 481 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 482 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 483 IRQ_TYPE_LEVEL_HIGH>;
+ <GIC_SPI 483 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 484 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 715>;
clock-names = "fck";
power-domains = <&sysc R8A779F0_PD_ALWAYS_ON>;
@@ -539,7 +544,9 @@
reg = <0 0xe6fe0000 0 0x30>;
interrupts = <GIC_SPI 485 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 487 IRQ_TYPE_LEVEL_HIGH>;
+ <GIC_SPI 487 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 488 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 716>;
clock-names = "fck";
power-domains = <&sysc R8A779F0_PD_ALWAYS_ON>;
@@ -552,7 +559,9 @@
reg = <0 0xffc00000 0 0x30>;
interrupts = <GIC_SPI 489 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 490 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 491 IRQ_TYPE_LEVEL_HIGH>;
+ <GIC_SPI 491 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 492 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
clocks = <&cpg CPG_MOD 717>;
clock-names = "fck";
power-domains = <&sysc R8A779F0_PD_ALWAYS_ON>;
diff --git a/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-cpu.dts b/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-cpu.dts
new file mode 100644
index 000000000000..c8b1bb50a8cf
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-cpu.dts
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the standalone R-Car V4H White Hawk CPU board
+ *
+ * Copyright (C) 2023 Glider bv
+ */
+
+/dts-v1/;
+#include "r8a779g0-white-hawk-cpu.dtsi"
+
+/ {
+ model = "Renesas White Hawk CPU board based on r8a779g0";
+};
diff --git a/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-cpu.dtsi b/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-cpu.dtsi
index 913f70fe6c5c..b1fe1aedc27d 100644
--- a/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-cpu.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-cpu.dtsi
@@ -1,378 +1,14 @@
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/*
- * Device Tree Source for the White Hawk CPU board
+ * Device Tree Source for the R-Car V4H White Hawk CPU board
*
* Copyright (C) 2022 Renesas Electronics Corp.
*/
#include "r8a779g0.dtsi"
-
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/leds/common.h>
+#include "white-hawk-cpu-common.dtsi"
/ {
model = "Renesas White Hawk CPU board";
compatible = "renesas,white-hawk-cpu", "renesas,r8a779g0";
-
- aliases {
- ethernet0 = &avb0;
- serial0 = &hscif0;
- };
-
- chosen {
- bootargs = "ignore_loglevel rw root=/dev/nfs ip=on";
- stdout-path = "serial0:921600n8";
- };
-
- keys {
- compatible = "gpio-keys";
-
- pinctrl-0 = <&keys_pins>;
- pinctrl-names = "default";
-
- key-1 {
- gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
- linux,code = <KEY_1>;
- label = "SW47";
- wakeup-source;
- debounce-interval = <20>;
- };
-
- key-2 {
- gpios = <&gpio5 1 GPIO_ACTIVE_LOW>;
- linux,code = <KEY_2>;
- label = "SW48";
- wakeup-source;
- debounce-interval = <20>;
- };
-
- key-3 {
- gpios = <&gpio5 2 GPIO_ACTIVE_LOW>;
- linux,code = <KEY_3>;
- label = "SW49";
- wakeup-source;
- debounce-interval = <20>;
- };
- };
-
- leds {
- compatible = "gpio-leds";
-
- led-1 {
- gpios = <&gpio7 0 GPIO_ACTIVE_HIGH>;
- color = <LED_COLOR_ID_GREEN>;
- function = LED_FUNCTION_INDICATOR;
- function-enumerator = <1>;
- };
-
- led-2 {
- gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>;
- color = <LED_COLOR_ID_GREEN>;
- function = LED_FUNCTION_INDICATOR;
- function-enumerator = <2>;
- };
-
- led-3 {
- gpios = <&gpio7 2 GPIO_ACTIVE_HIGH>;
- color = <LED_COLOR_ID_GREEN>;
- function = LED_FUNCTION_INDICATOR;
- function-enumerator = <3>;
- };
- };
-
- memory@48000000 {
- device_type = "memory";
- /* first 128MB is reserved for secure area. */
- reg = <0x0 0x48000000 0x0 0x78000000>;
- };
-
- memory@480000000 {
- device_type = "memory";
- reg = <0x4 0x80000000 0x0 0x80000000>;
- };
-
- memory@600000000 {
- device_type = "memory";
- reg = <0x6 0x00000000 0x1 0x00000000>;
- };
-
- mini-dp-con {
- compatible = "dp-connector";
- label = "CN5";
- type = "mini";
-
- port {
- mini_dp_con_in: endpoint {
- remote-endpoint = <&sn65dsi86_out>;
- };
- };
- };
-
- reg_1p2v: regulator-1p2v {
- compatible = "regulator-fixed";
- regulator-name = "fixed-1.2V";
- regulator-min-microvolt = <1200000>;
- regulator-max-microvolt = <1200000>;
- regulator-boot-on;
- regulator-always-on;
- };
-
- reg_1p8v: regulator-1p8v {
- compatible = "regulator-fixed";
- regulator-name = "fixed-1.8V";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- regulator-boot-on;
- regulator-always-on;
- };
-
- reg_3p3v: regulator-3p3v {
- compatible = "regulator-fixed";
- regulator-name = "fixed-3.3V";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- regulator-boot-on;
- regulator-always-on;
- };
-
- sn65dsi86_refclk: clk-x6 {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <38400000>;
- };
-};
-
-&avb0 {
- pinctrl-0 = <&avb0_pins>;
- pinctrl-names = "default";
- phy-handle = <&phy0>;
- 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>;
- };
-};
-
-&dsi0 {
- status = "okay";
-
- ports {
- port@1 {
- dsi0_out: endpoint {
- remote-endpoint = <&sn65dsi86_in>;
- data-lanes = <1 2 3 4>;
- };
- };
- };
-};
-
-&du {
- status = "okay";
-};
-
-&extal_clk {
- clock-frequency = <16666666>;
-};
-
-&extalr_clk {
- clock-frequency = <32768>;
-};
-
-&hscif0 {
- pinctrl-0 = <&hscif0_pins>;
- pinctrl-names = "default";
-
- status = "okay";
-};
-
-&i2c0 {
- pinctrl-0 = <&i2c0_pins>;
- pinctrl-names = "default";
-
- status = "okay";
- clock-frequency = <400000>;
-
- io_expander_a: gpio@20 {
- compatible = "onnn,pca9654";
- reg = <0x20>;
- interrupt-parent = <&gpio0>;
- interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
- eeprom@50 {
- compatible = "rohm,br24g01", "atmel,24c01";
- label = "cpu-board";
- reg = <0x50>;
- pagesize = <8>;
- };
-};
-
-&i2c1 {
- pinctrl-0 = <&i2c1_pins>;
- pinctrl-names = "default";
-
- status = "okay";
- clock-frequency = <400000>;
-
- bridge@2c {
- compatible = "ti,sn65dsi86";
- reg = <0x2c>;
-
- clocks = <&sn65dsi86_refclk>;
- clock-names = "refclk";
-
- interrupt-parent = <&intc_ex>;
- interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
-
- enable-gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>;
-
- vccio-supply = <&reg_1p8v>;
- vpll-supply = <&reg_1p8v>;
- vcca-supply = <&reg_1p2v>;
- vcc-supply = <&reg_1p2v>;
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
- sn65dsi86_in: endpoint {
- remote-endpoint = <&dsi0_out>;
- };
- };
-
- port@1 {
- reg = <1>;
- sn65dsi86_out: endpoint {
- remote-endpoint = <&mini_dp_con_in>;
- };
- };
- };
- };
-};
-
-&mmc0 {
- pinctrl-0 = <&mmc_pins>;
- pinctrl-1 = <&mmc_pins>;
- pinctrl-names = "default", "state_uhs";
-
- vmmc-supply = <&reg_3p3v>;
- vqmmc-supply = <&reg_1p8v>;
- mmc-hs200-1_8v;
- mmc-hs400-1_8v;
- bus-width = <8>;
- no-sd;
- no-sdio;
- non-removable;
- full-pwr-cycle-in-suspend;
- status = "okay";
-};
-
-&pfc {
- pinctrl-0 = <&scif_clk_pins>;
- pinctrl-names = "default";
-
- avb0_pins: avb0 {
- mux {
- groups = "avb0_link", "avb0_mdio", "avb0_rgmii",
- "avb0_txcrefclk";
- function = "avb0";
- };
-
- pins_mdio {
- groups = "avb0_mdio";
- drive-strength = <21>;
- };
-
- pins_mii {
- groups = "avb0_rgmii";
- drive-strength = <21>;
- };
-
- };
- hscif0_pins: hscif0 {
- groups = "hscif0_data";
- function = "hscif0";
- };
-
- i2c0_pins: i2c0 {
- groups = "i2c0";
- function = "i2c0";
- };
-
- i2c1_pins: i2c1 {
- groups = "i2c1";
- function = "i2c1";
- };
-
- keys_pins: keys {
- pins = "GP_5_0", "GP_5_1", "GP_5_2";
- bias-pull-up;
- };
-
- mmc_pins: mmc {
- groups = "mmc_data8", "mmc_ctrl", "mmc_ds";
- function = "mmc";
- power-source = <1800>;
- };
-
- qspi0_pins: qspi0 {
- groups = "qspi0_ctrl", "qspi0_data4";
- function = "qspi0";
- };
-
- scif_clk_pins: scif_clk {
- groups = "scif_clk";
- function = "scif_clk";
- };
-};
-
-&rpc {
- pinctrl-0 = <&qspi0_pins>;
- pinctrl-names = "default";
-
- status = "okay";
-
- flash@0 {
- compatible = "spansion,s25fs512s", "jedec,spi-nor";
- reg = <0>;
- spi-max-frequency = <40000000>;
- spi-rx-bus-width = <4>;
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- boot@0 {
- reg = <0x0 0x1200000>;
- read-only;
- };
- user@1200000 {
- reg = <0x1200000 0x2e00000>;
- };
- };
- };
-};
-
-&rwdt {
- timeout-sec = <60>;
- status = "okay";
-};
-
-&scif_clk {
- clock-frequency = <24000000>;
};
diff --git a/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk.dts b/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk.dts
index eff1ef6e2cc8..784d4e8b204c 100644
--- a/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk.dts
+++ b/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk.dts
@@ -1,69 +1,15 @@
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/*
- * Device Tree Source for the White Hawk CPU and BreakOut boards
+ * Device Tree Source for the R-Car V4H White Hawk CPU and BreakOut boards
*
* Copyright (C) 2022 Renesas Electronics Corp.
*/
/dts-v1/;
#include "r8a779g0-white-hawk-cpu.dtsi"
-#include "r8a779g0-white-hawk-csi-dsi.dtsi"
-#include "r8a779g0-white-hawk-ethernet.dtsi"
+#include "white-hawk-common.dtsi"
/ {
model = "Renesas White Hawk CPU and Breakout boards based on r8a779g0";
compatible = "renesas,white-hawk-breakout", "renesas,white-hawk-cpu", "renesas,r8a779g0";
-
- can_transceiver0: can-phy0 {
- compatible = "nxp,tjr1443";
- #phy-cells = <0>;
- enable-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
- max-bitrate = <5000000>;
- };
-};
-
-&can_clk {
- clock-frequency = <40000000>;
-};
-
-&canfd {
- pinctrl-0 = <&canfd0_pins>, <&canfd1_pins>, <&can_clk_pins>;
- pinctrl-names = "default";
-
- status = "okay";
-
- channel0 {
- status = "okay";
- phys = <&can_transceiver0>;
- };
-
- channel1 {
- status = "okay";
- };
-};
-
-&i2c0 {
- eeprom@51 {
- compatible = "rohm,br24g01", "atmel,24c01";
- label = "breakout-board";
- reg = <0x51>;
- pagesize = <8>;
- };
-};
-
-&pfc {
- can_clk_pins: can-clk {
- groups = "can_clk";
- function = "can_clk";
- };
-
- canfd0_pins: canfd0 {
- groups = "canfd0_data";
- function = "canfd0";
- };
-
- canfd1_pins: canfd1 {
- groups = "canfd1_data";
- function = "canfd1";
- };
};
diff --git a/arch/arm64/boot/dts/renesas/r8a779g0.dtsi b/arch/arm64/boot/dts/renesas/r8a779g0.dtsi
index d3d25e077c5d..9bc542bc6169 100644
--- a/arch/arm64/boot/dts/renesas/r8a779g0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779g0.dtsi
@@ -161,11 +161,6 @@
};
};
- psci {
- compatible = "arm,psci-1.0", "arm,psci-0.2";
- method = "smc";
- };
-
extal_clk: extal {
compatible = "fixed-clock";
#clock-cells = <0>;
@@ -185,13 +180,24 @@
interrupts-extended = <&gic GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
};
- /* External SCIF clock - to be overridden by boards that provide it */
+ psci {
+ compatible = "arm,psci-1.0", "arm,psci-0.2";
+ method = "smc";
+ };
+
+ /* External SCIF clocks - to be overridden by boards that provide them */
scif_clk: scif {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <0>;
};
+ scif_clk2: scif2 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
soc: soc {
compatible = "simple-bus";
interrupt-parent = <&gic>;
@@ -479,6 +485,7 @@
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 R8A779G0_PD_ALWAYS_ON>;
@@ -491,7 +498,9 @@
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 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 R8A779G0_PD_ALWAYS_ON>;
@@ -504,7 +513,9 @@
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 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 R8A779G0_PD_ALWAYS_ON>;
@@ -517,7 +528,9 @@
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 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 R8A779G0_PD_ALWAYS_ON>;
@@ -530,7 +543,9 @@
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 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 R8A779G0_PD_ALWAYS_ON>;
@@ -681,7 +696,7 @@
interrupts = <GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cpg CPG_MOD 516>,
<&cpg CPG_CORE R8A779G0_CLK_SASYNCPERD1>,
- <&scif_clk>;
+ <&scif_clk2>;
clock-names = "fck", "brg_int", "scif_clk";
dmas = <&dmac0 0x35>, <&dmac0 0x34>,
<&dmac1 0x35>, <&dmac1 0x34>;
@@ -761,7 +776,7 @@
avb0: ethernet@e6800000 {
compatible = "renesas,etheravb-r8a779g0",
"renesas,etheravb-rcar-gen4";
- reg = <0 0xe6800000 0 0x800>;
+ reg = <0 0xe6800000 0 0x1000>;
interrupts = <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>,
@@ -808,7 +823,7 @@
avb1: ethernet@e6810000 {
compatible = "renesas,etheravb-r8a779g0",
"renesas,etheravb-rcar-gen4";
- reg = <0 0xe6810000 0 0x800>;
+ reg = <0 0xe6810000 0 0x1000>;
interrupts = <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 362 IRQ_TYPE_LEVEL_HIGH>,
@@ -1057,7 +1072,7 @@
interrupts = <GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cpg CPG_MOD 705>,
<&cpg CPG_CORE R8A779G0_CLK_SASYNCPERD1>,
- <&scif_clk>;
+ <&scif_clk2>;
clock-names = "fck", "brg_int", "scif_clk";
dmas = <&dmac0 0x59>, <&dmac0 0x58>,
<&dmac1 0x59>, <&dmac1 0x58>;
@@ -1777,6 +1792,37 @@
};
};
+ mmc0: mmc@ee140000 {
+ compatible = "renesas,sdhi-r8a779g0",
+ "renesas,rcar-gen4-sdhi";
+ reg = <0 0xee140000 0 0x2000>;
+ interrupts = <GIC_SPI 440 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 706>,
+ <&cpg CPG_CORE R8A779G0_CLK_SD0H>;
+ clock-names = "core", "clkh";
+ power-domains = <&sysc R8A779G0_PD_ALWAYS_ON>;
+ resets = <&cpg 706>;
+ max-frequency = <200000000>;
+ iommus = <&ipmmu_ds0 32>;
+ status = "disabled";
+ };
+
+ rpc: spi@ee200000 {
+ compatible = "renesas,r8a779g0-rpc-if",
+ "renesas,rcar-gen4-rpc-if";
+ reg = <0 0xee200000 0 0x200>,
+ <0 0x08000000 0 0x04000000>,
+ <0 0xee208000 0 0x100>;
+ reg-names = "regs", "dirmap", "wbuf";
+ interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 629>;
+ power-domains = <&sysc R8A779G0_PD_ALWAYS_ON>;
+ resets = <&cpg 629>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
ipmmu_rt0: iommu@ee480000 {
compatible = "renesas,ipmmu-r8a779g0",
"renesas,rcar-gen4-ipmmu-vmsa";
@@ -1886,37 +1932,6 @@
#iommu-cells = <1>;
};
- mmc0: mmc@ee140000 {
- compatible = "renesas,sdhi-r8a779g0",
- "renesas,rcar-gen4-sdhi";
- reg = <0 0xee140000 0 0x2000>;
- interrupts = <GIC_SPI 440 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&cpg CPG_MOD 706>,
- <&cpg CPG_CORE R8A779G0_CLK_SD0H>;
- clock-names = "core", "clkh";
- power-domains = <&sysc R8A779G0_PD_ALWAYS_ON>;
- resets = <&cpg 706>;
- max-frequency = <200000000>;
- iommus = <&ipmmu_ds0 32>;
- status = "disabled";
- };
-
- rpc: spi@ee200000 {
- compatible = "renesas,r8a779g0-rpc-if",
- "renesas,rcar-gen4-rpc-if";
- reg = <0 0xee200000 0 0x200>,
- <0 0x08000000 0 0x04000000>,
- <0 0xee208000 0 0x100>;
- reg-names = "regs", "dirmap", "wbuf";
- interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&cpg CPG_MOD 629>;
- power-domains = <&sysc R8A779G0_PD_ALWAYS_ON>;
- resets = <&cpg 629>;
- #address-cells = <1>;
- #size-cells = <0>;
- status = "disabled";
- };
-
gic: interrupt-controller@f1000000 {
compatible = "arm,gic-v3";
#interrupt-cells = <3>;
diff --git a/arch/arm64/boot/dts/renesas/r8a779g2-white-hawk-single.dts b/arch/arm64/boot/dts/renesas/r8a779g2-white-hawk-single.dts
new file mode 100644
index 000000000000..2f79e5a61248
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779g2-white-hawk-single.dts
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the R-Car V4H ES2.0 White Hawk Single board
+ *
+ * Copyright (C) 2023 Glider bv
+ */
+
+/dts-v1/;
+#include "r8a779g2.dtsi"
+#include "white-hawk-cpu-common.dtsi"
+#include "white-hawk-common.dtsi"
+
+/ {
+ model = "Renesas White Hawk Single board based on r8a779g2";
+ compatible = "renesas,white-hawk-single", "renesas,r8a779g2",
+ "renesas,r8a779g0";
+};
+
+&hscif0 {
+ uart-has-rtscts;
+};
+
+&hscif0_pins {
+ groups = "hscif0_data", "hscif0_ctrl";
+ function = "hscif0";
+};
diff --git a/arch/arm64/boot/dts/renesas/r8a779g2.dtsi b/arch/arm64/boot/dts/renesas/r8a779g2.dtsi
new file mode 100644
index 000000000000..e08f531843e2
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779g2.dtsi
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the R-Car V4H (R8A779G2) SoC
+ *
+ * Copyright (C) 2023 Glider bv
+ */
+
+#include "r8a779g0.dtsi"
+
+/ {
+ compatible = "renesas,r8a779g2", "renesas,r8a779g0";
+};
diff --git a/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts b/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts
new file mode 100644
index 000000000000..bc8616a56c03
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts
@@ -0,0 +1,230 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the R-Car V4M Gray Hawk Single board
+ *
+ * Copyright (C) 2023 Renesas Electronics Corp.
+ * Copyright (C) 2024 Glider bv
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+#include "r8a779h0.dtsi"
+
+/ {
+ model = "Renesas Gray Hawk Single board based on r8a779h0";
+ compatible = "renesas,gray-hawk-single", "renesas,r8a779h0";
+
+ aliases {
+ serial0 = &hscif0;
+ ethernet0 = &avb0;
+ };
+
+ chosen {
+ bootargs = "ignore_loglevel";
+ stdout-path = "serial0:921600n8";
+ };
+
+ memory@48000000 {
+ device_type = "memory";
+ /* first 128MB is reserved for secure area. */
+ reg = <0x0 0x48000000 0x0 0x78000000>;
+ };
+
+ memory@480000000 {
+ device_type = "memory";
+ reg = <0x4 0x80000000 0x1 0x80000000>;
+ };
+
+ reg_1p8v: regulator-1p8v {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_3p3v: regulator-3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+};
+
+&avb0 {
+ pinctrl-0 = <&avb0_pins>;
+ pinctrl-names = "default";
+ phy-handle = <&phy0>;
+ 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>;
+ };
+};
+
+&extal_clk {
+ clock-frequency = <16666666>;
+};
+
+&extalr_clk {
+ clock-frequency = <32768>;
+};
+
+&hscif0 {
+ pinctrl-0 = <&hscif0_pins>;
+ pinctrl-names = "default";
+
+ uart-has-rtscts;
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-0 = <&i2c0_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+ clock-frequency = <400000>;
+
+ eeprom@50 {
+ compatible = "rohm,br24g01", "atmel,24c01";
+ label = "cpu-board";
+ reg = <0x50>;
+ pagesize = <8>;
+ };
+
+ eeprom@51 {
+ compatible = "rohm,br24g01", "atmel,24c01";
+ label = "breakout-board";
+ reg = <0x51>;
+ pagesize = <8>;
+ };
+
+ eeprom@52 {
+ compatible = "rohm,br24g01", "atmel,24c01";
+ label = "csi-dsi-sub-board-id";
+ reg = <0x52>;
+ pagesize = <8>;
+ };
+
+ eeprom@53 {
+ compatible = "rohm,br24g01", "atmel,24c01";
+ label = "ethernet-sub-board-id";
+ reg = <0x53>;
+ pagesize = <8>;
+ };
+};
+
+&mmc0 {
+ pinctrl-0 = <&mmc_pins>;
+ pinctrl-1 = <&mmc_pins>;
+ pinctrl-names = "default", "state_uhs";
+
+ vmmc-supply = <&reg_3p3v>;
+ vqmmc-supply = <&reg_1p8v>;
+ mmc-hs200-1_8v;
+ mmc-hs400-1_8v;
+ bus-width = <8>;
+ no-sd;
+ no-sdio;
+ non-removable;
+ full-pwr-cycle-in-suspend;
+ status = "okay";
+};
+
+&pfc {
+ pinctrl-0 = <&scif_clk_pins>;
+ pinctrl-names = "default";
+
+ avb0_pins: avb0 {
+ mux {
+ groups = "avb0_link", "avb0_mdio", "avb0_rgmii",
+ "avb0_txcrefclk";
+ function = "avb0";
+ };
+
+ pins_mdio {
+ groups = "avb0_mdio";
+ drive-strength = <21>;
+ };
+
+ pins_mii {
+ groups = "avb0_rgmii";
+ drive-strength = <21>;
+ };
+ };
+
+ hscif0_pins: hscif0 {
+ groups = "hscif0_data", "hscif0_ctrl";
+ function = "hscif0";
+ };
+
+ i2c0_pins: i2c0 {
+ groups = "i2c0";
+ function = "i2c0";
+ };
+
+ mmc_pins: mmc {
+ groups = "mmc_data8", "mmc_ctrl", "mmc_ds";
+ function = "mmc";
+ power-source = <1800>;
+ };
+
+ qspi0_pins: qspi0 {
+ groups = "qspi0_ctrl", "qspi0_data4";
+ function = "qspi0";
+ };
+
+ scif_clk_pins: scif-clk {
+ groups = "scif_clk";
+ function = "scif_clk";
+ };
+};
+
+&rpc {
+ pinctrl-0 = <&qspi0_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+
+ flash@0 {
+ compatible = "spansion,s25fs512s", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <40000000>;
+ spi-rx-bus-width = <4>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ boot@0 {
+ reg = <0x0 0x1200000>;
+ read-only;
+ };
+ user@1200000 {
+ reg = <0x1200000 0x2e00000>;
+ };
+ };
+ };
+};
+
+&rwdt {
+ timeout-sec = <60>;
+ status = "okay";
+};
+
+&scif_clk {
+ clock-frequency = <24000000>;
+};
diff --git a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
new file mode 100644
index 000000000000..11885729181b
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
@@ -0,0 +1,664 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the R-Car V4M (R8A779H0) SoC
+ *
+ * Copyright (C) 2023 Renesas Electronics Corp.
+ */
+
+#include <dt-bindings/clock/renesas,r8a779h0-cpg-mssr.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/renesas,r8a779h0-sysc.h>
+
+/ {
+ compatible = "renesas,r8a779h0";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ cluster0_opp: opp-table-0 {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp-500000000 {
+ opp-hz = /bits/ 64 <500000000>;
+ opp-microvolt = <825000>;
+ clock-latency-ns = <500000>;
+ };
+ opp-1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ opp-microvolt = <825000>;
+ clock-latency-ns = <500000>;
+ };
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu-map {
+ cluster0 {
+ core0 {
+ cpu = <&a76_0>;
+ };
+ core1 {
+ cpu = <&a76_1>;
+ };
+ core2 {
+ cpu = <&a76_2>;
+ };
+ core3 {
+ cpu = <&a76_3>;
+ };
+ };
+ };
+
+ a76_0: cpu@0 {
+ compatible = "arm,cortex-a76";
+ reg = <0>;
+ device_type = "cpu";
+ power-domains = <&sysc R8A779H0_PD_A1E0D0C0>;
+ next-level-cache = <&L3_CA76>;
+ enable-method = "psci";
+ cpu-idle-states = <&CPU_SLEEP_0>;
+ clocks = <&cpg CPG_CORE R8A779H0_CLK_ZC0>;
+ operating-points-v2 = <&cluster0_opp>;
+ };
+
+ a76_1: cpu@100 {
+ compatible = "arm,cortex-a76";
+ reg = <0x100>;
+ device_type = "cpu";
+ power-domains = <&sysc R8A779H0_PD_A1E0D0C1>;
+ next-level-cache = <&L3_CA76>;
+ enable-method = "psci";
+ cpu-idle-states = <&CPU_SLEEP_0>;
+ clocks = <&cpg CPG_CORE R8A779H0_CLK_ZC1>;
+ operating-points-v2 = <&cluster0_opp>;
+ };
+
+ a76_2: cpu@200 {
+ compatible = "arm,cortex-a76";
+ reg = <0x200>;
+ device_type = "cpu";
+ power-domains = <&sysc R8A779H0_PD_A1E0D0C2>;
+ next-level-cache = <&L3_CA76>;
+ enable-method = "psci";
+ cpu-idle-states = <&CPU_SLEEP_0>;
+ clocks = <&cpg CPG_CORE R8A779H0_CLK_ZC2>;
+ operating-points-v2 = <&cluster0_opp>;
+ };
+
+ a76_3: cpu@300 {
+ compatible = "arm,cortex-a76";
+ reg = <0x300>;
+ device_type = "cpu";
+ power-domains = <&sysc R8A779H0_PD_A1E0D0C3>;
+ next-level-cache = <&L3_CA76>;
+ enable-method = "psci";
+ cpu-idle-states = <&CPU_SLEEP_0>;
+ clocks = <&cpg CPG_CORE R8A779H0_CLK_ZC3>;
+ operating-points-v2 = <&cluster0_opp>;
+ };
+
+ idle-states {
+ entry-method = "psci";
+
+ CPU_SLEEP_0: cpu-sleep-0 {
+ compatible = "arm,idle-state";
+ arm,psci-suspend-param = <0x0010000>;
+ local-timer-stop;
+ entry-latency-us = <400>;
+ exit-latency-us = <500>;
+ min-residency-us = <4000>;
+ };
+ };
+
+ L3_CA76: cache-controller {
+ compatible = "cache";
+ power-domains = <&sysc R8A779H0_PD_A2E0D0>;
+ cache-unified;
+ cache-level = <3>;
+ };
+ };
+
+ extal_clk: extal-clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overridden by the board */
+ clock-frequency = <0>;
+ };
+
+ extalr_clk: extalr-clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overridden by the board */
+ clock-frequency = <0>;
+ };
+
+ pmu-a76 {
+ compatible = "arm,cortex-a76-pmu";
+ interrupts-extended = <&gic GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ psci {
+ compatible = "arm,psci-1.0", "arm,psci-0.2";
+ method = "smc";
+ };
+
+ /* External SCIF clock - to be overridden by boards that provide it */
+ scif_clk: scif-clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ soc: soc {
+ compatible = "simple-bus";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ rwdt: watchdog@e6020000 {
+ compatible = "renesas,r8a779h0-wdt",
+ "renesas,rcar-gen4-wdt";
+ reg = <0 0xe6020000 0 0x0c>;
+ interrupts = <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 907>;
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 907>;
+ status = "disabled";
+ };
+
+ pfc: pinctrl@e6050000 {
+ compatible = "renesas,pfc-r8a779h0";
+ reg = <0 0xe6050000 0 0x16c>, <0 0xe6050800 0 0x16c>,
+ <0 0xe6058000 0 0x16c>, <0 0xe6058800 0 0x16c>,
+ <0 0xe6060000 0 0x16c>, <0 0xe6060800 0 0x16c>,
+ <0 0xe6061000 0 0x16c>, <0 0xe6061800 0 0x16c>;
+ };
+
+ gpio0: gpio@e6050180 {
+ compatible = "renesas,gpio-r8a779h0",
+ "renesas,rcar-gen4-gpio";
+ reg = <0 0xe6050180 0 0x54>;
+ interrupts = <GIC_SPI 619 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 0 19>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&cpg CPG_MOD 915>;
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 915>;
+ };
+
+ gpio1: gpio@e6050980 {
+ compatible = "renesas,gpio-r8a779h0",
+ "renesas,rcar-gen4-gpio";
+ reg = <0 0xe6050980 0 0x54>;
+ interrupts = <GIC_SPI 623 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 32 30>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&cpg CPG_MOD 915>;
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 915>;
+ };
+
+ gpio2: gpio@e6058180 {
+ compatible = "renesas,gpio-r8a779h0",
+ "renesas,rcar-gen4-gpio";
+ reg = <0 0xe6058180 0 0x54>;
+ interrupts = <GIC_SPI 627 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 64 20>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&cpg CPG_MOD 916>;
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 916>;
+ };
+
+ gpio3: gpio@e6058980 {
+ compatible = "renesas,gpio-r8a779h0",
+ "renesas,rcar-gen4-gpio";
+ reg = <0 0xe6058980 0 0x54>;
+ interrupts = <GIC_SPI 631 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 96 32>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&cpg CPG_MOD 916>;
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 916>;
+ };
+
+ gpio4: gpio@e6060180 {
+ compatible = "renesas,gpio-r8a779h0",
+ "renesas,rcar-gen4-gpio";
+ reg = <0 0xe6060180 0 0x54>;
+ interrupts = <GIC_SPI 635 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 128 25>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&cpg CPG_MOD 917>;
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 917>;
+ };
+
+ gpio5: gpio@e6060980 {
+ compatible = "renesas,gpio-r8a779h0",
+ "renesas,rcar-gen4-gpio";
+ reg = <0 0xe6060980 0 0x54>;
+ interrupts = <GIC_SPI 639 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 160 21>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&cpg CPG_MOD 917>;
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 917>;
+ };
+
+ gpio6: gpio@e6061180 {
+ compatible = "renesas,gpio-r8a779h0",
+ "renesas,rcar-gen4-gpio";
+ reg = <0 0xe6061180 0 0x54>;
+ interrupts = <GIC_SPI 643 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 192 21>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&cpg CPG_MOD 917>;
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 917>;
+ };
+
+ gpio7: gpio@e6061980 {
+ compatible = "renesas,gpio-r8a779h0",
+ "renesas,rcar-gen4-gpio";
+ reg = <0 0xe6061980 0 0x54>;
+ interrupts = <GIC_SPI 647 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pfc 0 224 21>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ clocks = <&cpg CPG_MOD 917>;
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 917>;
+ };
+
+ cpg: clock-controller@e6150000 {
+ compatible = "renesas,r8a779h0-cpg-mssr";
+ reg = <0 0xe6150000 0 0x4000>;
+ clocks = <&extal_clk>, <&extalr_clk>;
+ clock-names = "extal", "extalr";
+ #clock-cells = <2>;
+ #power-domain-cells = <0>;
+ #reset-cells = <1>;
+ };
+
+ rst: reset-controller@e6160000 {
+ compatible = "renesas,r8a779h0-rst";
+ reg = <0 0xe6160000 0 0x4000>;
+ };
+
+ sysc: system-controller@e6180000 {
+ compatible = "renesas,r8a779h0-sysc";
+ reg = <0 0xe6180000 0 0x4000>;
+ #power-domain-cells = <1>;
+ };
+
+ i2c0: i2c@e6500000 {
+ compatible = "renesas,i2c-r8a779h0",
+ "renesas,rcar-gen4-i2c";
+ reg = <0 0xe6500000 0 0x40>;
+ interrupts = <GIC_SPI 610 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 518>;
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 518>;
+ dmas = <&dmac1 0x91>, <&dmac1 0x90>,
+ <&dmac2 0x91>, <&dmac2 0x90>;
+ dma-names = "tx", "rx", "tx", "rx";
+ i2c-scl-internal-delay-ns = <110>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@e6508000 {
+ compatible = "renesas,i2c-r8a779h0",
+ "renesas,rcar-gen4-i2c";
+ reg = <0 0xe6508000 0 0x40>;
+ interrupts = <GIC_SPI 611 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 519>;
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 519>;
+ dmas = <&dmac1 0x93>, <&dmac1 0x92>,
+ <&dmac2 0x93>, <&dmac2 0x92>;
+ dma-names = "tx", "rx", "tx", "rx";
+ i2c-scl-internal-delay-ns = <110>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@e6510000 {
+ compatible = "renesas,i2c-r8a779h0",
+ "renesas,rcar-gen4-i2c";
+ reg = <0 0xe6510000 0 0x40>;
+ interrupts = <GIC_SPI 612 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 520>;
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 520>;
+ dmas = <&dmac1 0x95>, <&dmac1 0x94>,
+ <&dmac2 0x95>, <&dmac2 0x94>;
+ dma-names = "tx", "rx", "tx", "rx";
+ i2c-scl-internal-delay-ns = <110>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@e66d0000 {
+ compatible = "renesas,i2c-r8a779h0",
+ "renesas,rcar-gen4-i2c";
+ reg = <0 0xe66d0000 0 0x40>;
+ interrupts = <GIC_SPI 613 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 521>;
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 521>;
+ dmas = <&dmac1 0x97>, <&dmac1 0x96>,
+ <&dmac2 0x97>, <&dmac2 0x96>;
+ dma-names = "tx", "rx", "tx", "rx";
+ i2c-scl-internal-delay-ns = <110>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ hscif0: serial@e6540000 {
+ compatible = "renesas,hscif-r8a779h0",
+ "renesas,rcar-gen4-hscif", "renesas,hscif";
+ reg = <0 0xe6540000 0 0x60>;
+ interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 514>,
+ <&cpg CPG_CORE R8A779H0_CLK_SASYNCPERD1>,
+ <&scif_clk>;
+ clock-names = "fck", "brg_int", "scif_clk";
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 514>;
+ dmas = <&dmac1 0x31>, <&dmac1 0x30>,
+ <&dmac2 0x31>, <&dmac2 0x30>;
+ dma-names = "tx", "rx", "tx", "rx";
+ status = "disabled";
+ };
+
+ avb0: ethernet@e6800000 {
+ compatible = "renesas,etheravb-r8a779h0",
+ "renesas,etheravb-rcar-gen4";
+ reg = <0 0xe6800000 0 0x1000>;
+ interrupts = <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 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>,
+ <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5", "ch6", "ch7",
+ "ch8", "ch9", "ch10", "ch11",
+ "ch12", "ch13", "ch14", "ch15",
+ "ch16", "ch17", "ch18", "ch19",
+ "ch20", "ch21", "ch22", "ch23",
+ "ch24";
+ clocks = <&cpg CPG_MOD 211>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A779H0_PD_C4>;
+ resets = <&cpg 211>;
+ phy-mode = "rgmii";
+ rx-internal-delay-ps = <0>;
+ tx-internal-delay-ps = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ avb1: ethernet@e6810000 {
+ compatible = "renesas,etheravb-r8a779h0",
+ "renesas,etheravb-rcar-gen4";
+ reg = <0 0xe6810000 0 0x1000>;
+ interrupts = <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 362 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 363 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 364 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 365 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 366 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 367 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 368 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 369 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>,
+ <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 380 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 381 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 382 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5", "ch6", "ch7",
+ "ch8", "ch9", "ch10", "ch11",
+ "ch12", "ch13", "ch14", "ch15",
+ "ch16", "ch17", "ch18", "ch19",
+ "ch20", "ch21", "ch22", "ch23",
+ "ch24";
+ clocks = <&cpg CPG_MOD 212>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A779H0_PD_C4>;
+ resets = <&cpg 212>;
+ phy-mode = "rgmii";
+ rx-internal-delay-ps = <0>;
+ tx-internal-delay-ps = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ avb2: ethernet@e6820000 {
+ compatible = "renesas,etheravb-r8a779h0",
+ "renesas,etheravb-rcar-gen4";
+ reg = <0 0xe6820000 0 0x1000>;
+ interrupts = <GIC_SPI 385 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 387 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 388 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 389 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 390 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 391 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 392 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 393 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 394 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 395 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 396 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 397 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 398 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 399 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 400 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 401 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 402 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 403 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 404 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 405 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 409 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "ch0", "ch1", "ch2", "ch3",
+ "ch4", "ch5", "ch6", "ch7",
+ "ch8", "ch9", "ch10", "ch11",
+ "ch12", "ch13", "ch14", "ch15",
+ "ch16", "ch17", "ch18", "ch19",
+ "ch20", "ch21", "ch22", "ch23",
+ "ch24";
+ clocks = <&cpg CPG_MOD 213>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A779H0_PD_C4>;
+ resets = <&cpg 213>;
+ phy-mode = "rgmii";
+ rx-internal-delay-ps = <0>;
+ tx-internal-delay-ps = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ dmac1: dma-controller@e7350000 {
+ compatible = "renesas,dmac-r8a779h0",
+ "renesas,rcar-gen4-dmac";
+ reg = <0 0xe7350000 0 0x1000>,
+ <0 0xe7300000 0 0x10000>;
+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "error",
+ "ch0", "ch1", "ch2", "ch3", "ch4",
+ "ch5", "ch6", "ch7", "ch8", "ch9",
+ "ch10", "ch11", "ch12", "ch13",
+ "ch14", "ch15";
+ clocks = <&cpg CPG_MOD 709>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 709>;
+ #dma-cells = <1>;
+ dma-channels = <16>;
+ };
+
+ dmac2: dma-controller@e7351000 {
+ compatible = "renesas,dmac-r8a779h0",
+ "renesas,rcar-gen4-dmac";
+ reg = <0 0xe7351000 0 0x1000>,
+ <0 0xe7310000 0 0x10000>;
+ interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "error",
+ "ch0", "ch1", "ch2", "ch3", "ch4",
+ "ch5", "ch6", "ch7";
+ clocks = <&cpg CPG_MOD 710>;
+ clock-names = "fck";
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 710>;
+ #dma-cells = <1>;
+ dma-channels = <8>;
+ };
+
+ mmc0: mmc@ee140000 {
+ compatible = "renesas,sdhi-r8a779h0",
+ "renesas,rcar-gen4-sdhi";
+ reg = <0 0xee140000 0 0x2000>;
+ interrupts = <GIC_SPI 440 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 706>,
+ <&cpg CPG_CORE R8A779H0_CLK_SD0H>;
+ clock-names = "core", "clkh";
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 706>;
+ max-frequency = <200000000>;
+ status = "disabled";
+ };
+
+ rpc: spi@ee200000 {
+ compatible = "renesas,r8a779h0-rpc-if",
+ "renesas,rcar-gen4-rpc-if";
+ reg = <0 0xee200000 0 0x200>,
+ <0 0x08000000 0 0x04000000>,
+ <0 0xee208000 0 0x100>;
+ reg-names = "regs", "dirmap", "wbuf";
+ interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD 629>;
+ power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+ resets = <&cpg 629>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ gic: interrupt-controller@f1000000 {
+ compatible = "arm,gic-v3";
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ interrupt-controller;
+ reg = <0x0 0xf1000000 0 0x20000>,
+ <0x0 0xf1060000 0 0x110000>;
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ prr: chipid@fff00044 {
+ compatible = "renesas,prr";
+ reg = <0 0xfff00044 0 4>;
+ };
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ 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 12 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
diff --git a/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi b/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi
index 2ab231572d95..964b0a475eee 100644
--- a/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi
+++ b/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi
@@ -61,6 +61,75 @@
&soc {
interrupt-parent = <&gic>;
+ cru: video@10830000 {
+ compatible = "renesas,r9a07g043-cru", "renesas,rzg2l-cru";
+ reg = <0 0x10830000 0 0x400>;
+ clocks = <&cpg CPG_MOD R9A07G043_CRU_VCLK>,
+ <&cpg CPG_MOD R9A07G043_CRU_PCLK>,
+ <&cpg CPG_MOD R9A07G043_CRU_ACLK>;
+ clock-names = "video", "apb", "axi";
+ interrupts = <SOC_PERIPHERAL_IRQ(167) IRQ_TYPE_LEVEL_HIGH>,
+ <SOC_PERIPHERAL_IRQ(168) IRQ_TYPE_LEVEL_HIGH>,
+ <SOC_PERIPHERAL_IRQ(169) IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "image_conv", "image_conv_err", "axi_mst_err";
+ resets = <&cpg R9A07G043_CRU_PRESETN>,
+ <&cpg R9A07G043_CRU_ARESETN>;
+ reset-names = "presetn", "aresetn";
+ power-domains = <&cpg>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ reg = <1>;
+ crucsi2: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&csi2cru>;
+ };
+ };
+ };
+ };
+
+ csi2: csi2@10830400 {
+ compatible = "renesas,r9a07g043-csi2", "renesas,rzg2l-csi2";
+ reg = <0 0x10830400 0 0xfc00>;
+ interrupts = <SOC_PERIPHERAL_IRQ(166) IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD R9A07G043_CRU_SYSCLK>,
+ <&cpg CPG_MOD R9A07G043_CRU_VCLK>,
+ <&cpg CPG_MOD R9A07G043_CRU_PCLK>;
+ clock-names = "system", "video", "apb";
+ resets = <&cpg R9A07G043_CRU_PRESETN>,
+ <&cpg R9A07G043_CRU_CMN_RSTB>;
+ reset-names = "presetn", "cmn-rstb";
+ power-domains = <&cpg>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ };
+
+ port@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+
+ csi2cru: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&crucsi2>;
+ };
+ };
+ };
+ };
+
irqc: interrupt-controller@110a0000 {
compatible = "renesas,r9a07g043u-irqc",
"renesas,rzg2l-irqc";
@@ -109,7 +178,13 @@
<SOC_PERIPHERAL_IRQ(473) IRQ_TYPE_LEVEL_HIGH>,
<SOC_PERIPHERAL_IRQ(474) IRQ_TYPE_LEVEL_HIGH>,
<SOC_PERIPHERAL_IRQ(475) IRQ_TYPE_LEVEL_HIGH>,
- <SOC_PERIPHERAL_IRQ(25) IRQ_TYPE_EDGE_RISING>;
+ <SOC_PERIPHERAL_IRQ(25) IRQ_TYPE_EDGE_RISING>,
+ <SOC_PERIPHERAL_IRQ(34) IRQ_TYPE_EDGE_RISING>,
+ <SOC_PERIPHERAL_IRQ(35) IRQ_TYPE_EDGE_RISING>,
+ <SOC_PERIPHERAL_IRQ(36) IRQ_TYPE_EDGE_RISING>,
+ <SOC_PERIPHERAL_IRQ(37) IRQ_TYPE_EDGE_RISING>,
+ <SOC_PERIPHERAL_IRQ(38) IRQ_TYPE_EDGE_RISING>,
+ <SOC_PERIPHERAL_IRQ(39) IRQ_TYPE_EDGE_RISING>;
interrupt-names = "nmi",
"irq0", "irq1", "irq2", "irq3",
"irq4", "irq5", "irq6", "irq7",
@@ -121,7 +196,9 @@
"tint20", "tint21", "tint22", "tint23",
"tint24", "tint25", "tint26", "tint27",
"tint28", "tint29", "tint30", "tint31",
- "bus-err";
+ "bus-err", "ec7tie1-0", "ec7tie2-0",
+ "ec7tiovf-0", "ec7tie1-1", "ec7tie2-1",
+ "ec7tiovf-1";
clocks = <&cpg CPG_MOD R9A07G043_IA55_CLK>,
<&cpg CPG_MOD R9A07G043_IA55_PCLK>;
clock-names = "clk", "pclk";
diff --git a/arch/arm64/boot/dts/renesas/r9a07g043u11-smarc-cru-csi-ov5645.dtso b/arch/arm64/boot/dts/renesas/r9a07g043u11-smarc-cru-csi-ov5645.dtso
new file mode 100644
index 000000000000..b41bb4b31a26
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/r9a07g043u11-smarc-cru-csi-ov5645.dtso
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree overlay for the RZ/G2UL SMARC EVK with OV5645 camera
+ * connected to CSI and CRU enabled.
+ *
+ * Copyright (C) 2024 Renesas Electronics Corp.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/rzg2l-pinctrl.h>
+
+#define OV5645_PARENT_I2C i2c0
+#include "rz-smarc-cru-csi-ov5645.dtsi"
+
+&ov5645 {
+ enable-gpios = <&pinctrl RZG2L_GPIO(4, 4) GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&pinctrl RZG2L_GPIO(0, 1) GPIO_ACTIVE_LOW>;
+};
diff --git a/arch/arm64/boot/dts/renesas/r9a07g044.dtsi b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
index 66f68fc2b241..9f00b75d2bd0 100644
--- a/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
+++ b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
@@ -793,6 +793,22 @@
reset-names = "rst", "arst", "prst";
power-domains = <&cpg>;
status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ dsi0_in: endpoint {
+ remote-endpoint = <&du_out_dsi>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ };
+ };
};
vspd: vsp@10870000 {
@@ -820,6 +836,36 @@
resets = <&cpg R9A07G044_LCDC_RESET_N>;
};
+ du: display@10890000 {
+ compatible = "renesas,r9a07g044-du";
+ reg = <0 0x10890000 0 0x10000>;
+ interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD R9A07G044_LCDC_CLK_A>,
+ <&cpg CPG_MOD R9A07G044_LCDC_CLK_P>,
+ <&cpg CPG_MOD R9A07G044_LCDC_CLK_D>;
+ clock-names = "aclk", "pclk", "vclk";
+ power-domains = <&cpg>;
+ resets = <&cpg R9A07G044_LCDC_RESET_N>;
+ renesas,vsps = <&vspd 0>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ du_out_dsi: endpoint {
+ remote-endpoint = <&dsi0_in>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ };
+ };
+ };
+
cpg: clock-controller@11010000 {
compatible = "renesas,r9a07g044-cpg";
reg = <0 0x11010000 0 0x10000>;
@@ -905,7 +951,27 @@
<GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 475 IRQ_TYPE_LEVEL_HIGH>;
+ <GIC_SPI 475 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 25 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 34 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 35 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 36 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 37 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 38 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 39 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 R9A07G044_IA55_CLK>,
<&cpg CPG_MOD R9A07G044_IA55_PCLK>;
clock-names = "clk", "pclk";
diff --git a/arch/arm64/boot/dts/renesas/r9a07g054.dtsi b/arch/arm64/boot/dts/renesas/r9a07g054.dtsi
index 1f1d481dc783..53d8905f367a 100644
--- a/arch/arm64/boot/dts/renesas/r9a07g054.dtsi
+++ b/arch/arm64/boot/dts/renesas/r9a07g054.dtsi
@@ -798,6 +798,22 @@
reset-names = "rst", "arst", "prst";
power-domains = <&cpg>;
status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ dsi0_in: endpoint {
+ remote-endpoint = <&du_out_dsi>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ };
+ };
};
vspd: vsp@10870000 {
@@ -826,6 +842,37 @@
resets = <&cpg R9A07G054_LCDC_RESET_N>;
};
+ du: display@10890000 {
+ compatible = "renesas,r9a07g054-du",
+ "renesas,r9a07g044-du";
+ reg = <0 0x10890000 0 0x10000>;
+ interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cpg CPG_MOD R9A07G054_LCDC_CLK_A>,
+ <&cpg CPG_MOD R9A07G054_LCDC_CLK_P>,
+ <&cpg CPG_MOD R9A07G054_LCDC_CLK_D>;
+ clock-names = "aclk", "pclk", "vclk";
+ power-domains = <&cpg>;
+ resets = <&cpg R9A07G054_LCDC_RESET_N>;
+ renesas,vsps = <&vspd 0>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ du_out_dsi: endpoint {
+ remote-endpoint = <&dsi0_in>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ };
+ };
+ };
+
cpg: clock-controller@11010000 {
compatible = "renesas,r9a07g054-cpg";
reg = <0 0x11010000 0 0x10000>;
@@ -912,7 +959,27 @@
<GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 475 IRQ_TYPE_LEVEL_HIGH>;
+ <GIC_SPI 475 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 25 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 34 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 35 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 36 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 37 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 38 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 39 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 R9A07G054_IA55_CLK>,
<&cpg CPG_MOD R9A07G054_IA55_PCLK>;
clock-names = "clk", "pclk";
diff --git a/arch/arm64/boot/dts/renesas/r9a08g045.dtsi b/arch/arm64/boot/dts/renesas/r9a08g045.dtsi
index 5facfad96158..f5f3f4f4c8d6 100644
--- a/arch/arm64/boot/dts/renesas/r9a08g045.dtsi
+++ b/arch/arm64/boot/dts/renesas/r9a08g045.dtsi
@@ -42,6 +42,11 @@
clock-frequency = <0>;
};
+ psci {
+ compatible = "arm,psci-1.0", "arm,psci-0.2";
+ method = "smc";
+ };
+
soc: soc {
compatible = "simple-bus";
interrupt-parent = <&gic>;
@@ -152,7 +157,10 @@
<GIC_SPI 458 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 459 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 460 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+ <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "nmi",
"irq0", "irq1", "irq2", "irq3",
"irq4", "irq5", "irq6", "irq7",
@@ -164,7 +172,8 @@
"tint20", "tint21", "tint22", "tint23",
"tint24", "tint25", "tint26", "tint27",
"tint28", "tint29", "tint30", "tint31",
- "bus-err";
+ "bus-err", "ec7tie1-0", "ec7tie2-0",
+ "ec7tiovf-0";
clocks = <&cpg CPG_MOD R9A08G045_IA55_CLK>,
<&cpg CPG_MOD R9A08G045_IA55_PCLK>;
clock-names = "clk", "pclk";
@@ -264,6 +273,20 @@
<0x0 0x12440000 0 0x60000>;
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
};
+
+ wdt0: watchdog@12800800 {
+ compatible = "renesas,r9a08g045-wdt", "renesas,rzg2l-wdt";
+ reg = <0 0x12800800 0 0x400>;
+ clocks = <&cpg CPG_MOD R9A08G045_WDT0_PCLK>,
+ <&cpg CPG_MOD R9A08G045_WDT0_CLK>;
+ clock-names = "pclk", "oscclk";
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "wdt", "perrout";
+ resets = <&cpg R9A08G045_WDT0_PRESETN>;
+ power-domains = <&cpg>;
+ status = "disabled";
+ };
};
timer {
diff --git a/arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi b/arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi
index 37807f1bda4d..887dffe14910 100644
--- a/arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi
+++ b/arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi
@@ -40,17 +40,7 @@
status = "okay";
ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
- dsi0_in: endpoint {
- };
- };
-
port@1 {
- reg = <1>;
dsi0_out: endpoint {
data-lanes = <1 2 3 4>;
remote-endpoint = <&adv7535_in>;
@@ -59,6 +49,10 @@
};
};
+&du {
+ status = "okay";
+};
+
&i2c1 {
adv7535: hdmi@3d {
compatible = "adi,adv7535";
diff --git a/arch/arm64/boot/dts/renesas/rzg2lc-smarc.dtsi b/arch/arm64/boot/dts/renesas/rzg2lc-smarc.dtsi
index 859bc8745e66..f21508640b6e 100644
--- a/arch/arm64/boot/dts/renesas/rzg2lc-smarc.dtsi
+++ b/arch/arm64/boot/dts/renesas/rzg2lc-smarc.dtsi
@@ -56,17 +56,7 @@
status = "okay";
ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
- dsi0_in: endpoint {
- };
- };
-
port@1 {
- reg = <1>;
dsi0_out: endpoint {
data-lanes = <1 2 3 4>;
remote-endpoint = <&adv7535_in>;
@@ -75,6 +65,10 @@
};
};
+&du {
+ status = "okay";
+};
+
&i2c1 {
adv7535: hdmi@3d {
compatible = "adi,adv7535";
diff --git a/arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi b/arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi
index f062d4ad78b7..acac4666ae59 100644
--- a/arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi
+++ b/arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi
@@ -193,12 +193,14 @@
#endif
&pinctrl {
+#if SW_CONFIG3 == SW_ON
eth0-phy-irq-hog {
gpio-hog;
gpios = <RZG2L_GPIO(12, 0) GPIO_ACTIVE_LOW>;
input;
line-name = "eth0-phy-irq";
};
+#endif
eth0_pins: eth0 {
txc {
@@ -234,12 +236,14 @@
};
};
+#if SW_CONFIG3 == SW_ON
eth1-phy-irq-hog {
gpio-hog;
gpios = <RZG2L_GPIO(12, 1) GPIO_ACTIVE_LOW>;
input;
line-name = "eth1-phy-irq";
};
+#endif
eth1_pins: eth1 {
txc {
@@ -336,3 +340,8 @@
};
};
};
+
+&wdt0 {
+ timeout-sec = <60>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi b/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi
index 214520137230..deb2ad37bb2e 100644
--- a/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi
+++ b/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi
@@ -6,6 +6,7 @@
*/
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
#include <dt-bindings/pinctrl/rzg2l-pinctrl.h>
/ {
@@ -14,6 +15,37 @@
mmc1 = &sdhi1;
};
+ keys {
+ compatible = "gpio-keys";
+
+ key-1 {
+ interrupts = <RZG2L_GPIO(18, 0) IRQ_TYPE_EDGE_FALLING>;
+ interrupt-parent = <&pinctrl>;
+ linux,code = <KEY_1>;
+ label = "USER_SW1";
+ wakeup-source;
+ debounce-interval = <20>;
+ };
+
+ key-2 {
+ interrupts = <RZG2L_GPIO(0, 1) IRQ_TYPE_EDGE_FALLING>;
+ interrupt-parent = <&pinctrl>;
+ linux,code = <KEY_2>;
+ label = "USER_SW2";
+ wakeup-source;
+ debounce-interval = <20>;
+ };
+
+ key-3 {
+ interrupts = <RZG2L_GPIO(0, 3) IRQ_TYPE_EDGE_FALLING>;
+ interrupt-parent = <&pinctrl>;
+ linux,code = <KEY_3>;
+ label = "USER_SW3";
+ wakeup-source;
+ debounce-interval = <20>;
+ };
+ };
+
vcc_sdhi1: regulator-vcc-sdhi1 {
compatible = "regulator-fixed";
regulator-name = "SDHI1 Vcc";
@@ -35,6 +67,27 @@
};
&pinctrl {
+ key-1-gpio-hog {
+ gpio-hog;
+ gpios = <RZG2L_GPIO(18, 0) GPIO_ACTIVE_LOW>;
+ input;
+ line-name = "key-1-gpio-irq";
+ };
+
+ key-2-gpio-hog {
+ gpio-hog;
+ gpios = <RZG2L_GPIO(0, 1) GPIO_ACTIVE_LOW>;
+ input;
+ line-name = "key-2-gpio-irq";
+ };
+
+ key-3-gpio-hog {
+ gpio-hog;
+ gpios = <RZG2L_GPIO(0, 3) GPIO_ACTIVE_LOW>;
+ input;
+ line-name = "key-3-gpio-irq";
+ };
+
scif0_pins: scif0 {
pinmux = <RZG2L_PORT_PINMUX(6, 3, 1)>, /* RXD */
<RZG2L_PORT_PINMUX(6, 4, 1)>; /* TXD */
diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
index 50de17e4fb3f..431b37bf5661 100644
--- a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
+++ b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
@@ -32,39 +32,40 @@
};
};
- accel_3v3: regulator-acc-3v3 {
+ reg_t1p8v: regulator-t1p8v {
compatible = "regulator-fixed";
- regulator-name = "accel-3v3";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- };
-
- hdmi_1v8: regulator-hdmi-1v8 {
- compatible = "regulator-fixed";
- regulator-name = "hdmi-1v8";
+ regulator-name = "T1.8V";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
};
- hdmi_3v3: regulator-hdmi-3v3 {
+ pcie_1v5: regulator-pcie-1v5 {
compatible = "regulator-fixed";
- regulator-name = "hdmi-3v3";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
+ regulator-name = "pcie-1v5";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ gpio = <&gpio_exp_77 15 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
};
- snd_3p3v: regulator-snd_3p3v {
+ pcie_3v3: regulator-pcie-3v3 {
compatible = "regulator-fixed";
- regulator-name = "snd-3.3v";
+ regulator-name = "pcie-3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
+ gpio = <&gpio_exp_77 14 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
};
- snd_vcc5v: regulator-snd_vcc5v {
+ reg_5v: regulator-5v {
compatible = "regulator-fixed";
- regulator-name = "snd-vcc5v";
+ regulator-name = "fixed-5V";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ regulator-always-on;
};
wlan_en: regulator-wlan_en {
@@ -157,11 +158,11 @@
pd-gpios = <&gpio_exp_75 5 GPIO_ACTIVE_LOW>;
- avdd-supply = <&hdmi_1v8>;
- dvdd-supply = <&hdmi_1v8>;
- pvdd-supply = <&hdmi_1v8>;
- dvdd-3v-supply = <&hdmi_3v3>;
- bgvdd-supply = <&hdmi_1v8>;
+ avdd-supply = <&reg_t1p8v>;
+ dvdd-supply = <&reg_t1p8v>;
+ pvdd-supply = <&reg_t1p8v>;
+ dvdd-3v-supply = <&reg_3p3v>;
+ bgvdd-supply = <&reg_t1p8v>;
adi,input-depth = <8>;
adi,input-colorspace = "rgb";
@@ -198,8 +199,8 @@
compatible = "st,lsm9ds0-imu";
reg = <0x1d>;
- vdd-supply = <&accel_3v3>;
- vddio-supply = <&accel_3v3>;
+ vdd-supply = <&reg_3p3v>;
+ vddio-supply = <&reg_3p3v>;
};
pcm3168a: audio-codec@44 {
@@ -209,20 +210,20 @@
clocks = <&clksndsel>;
clock-names = "scki";
- VDD1-supply = <&snd_3p3v>;
- VDD2-supply = <&snd_3p3v>;
- VCCAD1-supply = <&snd_vcc5v>;
- VCCAD2-supply = <&snd_vcc5v>;
- VCCDA1-supply = <&snd_vcc5v>;
- VCCDA2-supply = <&snd_vcc5v>;
+ VDD1-supply = <&reg_3p3v>;
+ VDD2-supply = <&reg_3p3v>;
+ VCCAD1-supply = <&reg_5v>;
+ VCCAD2-supply = <&reg_5v>;
+ VCCDA1-supply = <&reg_5v>;
+ VCCDA2-supply = <&reg_5v>;
};
gyroscope@6b {
compatible = "st,lsm9ds0-gyro";
reg = <0x6b>;
- vdd-supply = <&accel_3v3>;
- vddio-supply = <&accel_3v3>;
+ vdd-supply = <&reg_3p3v>;
+ vddio-supply = <&reg_3p3v>;
};
};
};
@@ -348,6 +349,9 @@
&pciec1 {
status = "okay";
+
+ vpcie1v5-supply = <&pcie_1v5>;
+ vpcie3v3-supply = <&pcie_3v3>;
};
&pfc {
@@ -417,6 +421,13 @@
pinctrl-names = "default";
status = "okay";
+
+ gnss {
+ compatible = "u-blox,neo-m8";
+ reset-gpios = <&gpio_exp_75 6 GPIO_ACTIVE_LOW>;
+ vcc-supply = <&reg_3p3v>;
+ current-speed = <9600>;
+ };
};
&sdhi3 {
diff --git a/arch/arm64/boot/dts/renesas/white-hawk-common.dtsi b/arch/arm64/boot/dts/renesas/white-hawk-common.dtsi
new file mode 100644
index 000000000000..c99086edadca
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/white-hawk-common.dtsi
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the common parts shared by the White Hawk BreakOut
+ * and White Hawk Single boards
+ *
+ * Copyright (C) 2022 Renesas Electronics Corp.
+ */
+
+#include "white-hawk-csi-dsi.dtsi"
+#include "white-hawk-ethernet.dtsi"
+
+/ {
+ can_transceiver0: can-phy0 {
+ compatible = "nxp,tjr1443";
+ #phy-cells = <0>;
+ enable-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
+ max-bitrate = <5000000>;
+ };
+};
+
+&can_clk {
+ clock-frequency = <40000000>;
+};
+
+&canfd {
+ pinctrl-0 = <&canfd0_pins>, <&canfd1_pins>, <&can_clk_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+
+ channel0 {
+ status = "okay";
+ phys = <&can_transceiver0>;
+ };
+
+ channel1 {
+ status = "okay";
+ };
+};
+
+&i2c0 {
+ eeprom@51 {
+ compatible = "rohm,br24g01", "atmel,24c01";
+ label = "breakout-board";
+ reg = <0x51>;
+ pagesize = <8>;
+ };
+};
+
+&pfc {
+ can_clk_pins: can-clk {
+ groups = "can_clk";
+ function = "can_clk";
+ };
+
+ canfd0_pins: canfd0 {
+ groups = "canfd0_data";
+ function = "canfd0";
+ };
+
+ canfd1_pins: canfd1 {
+ groups = "canfd1_data";
+ function = "canfd1";
+ };
+};
diff --git a/arch/arm64/boot/dts/renesas/white-hawk-cpu-common.dtsi b/arch/arm64/boot/dts/renesas/white-hawk-cpu-common.dtsi
new file mode 100644
index 000000000000..8ac17370ff36
--- /dev/null
+++ b/arch/arm64/boot/dts/renesas/white-hawk-cpu-common.dtsi
@@ -0,0 +1,375 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Device Tree Source for the common parts shared by the White Hawk CPU and
+ * White Hawk Single boards
+ *
+ * Copyright (C) 2022 Renesas Electronics Corp.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ aliases {
+ ethernet0 = &avb0;
+ serial0 = &hscif0;
+ };
+
+ chosen {
+ bootargs = "ignore_loglevel rw root=/dev/nfs ip=on";
+ stdout-path = "serial0:921600n8";
+ };
+
+ sn65dsi86_refclk: clk-x6 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <38400000>;
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ pinctrl-0 = <&keys_pins>;
+ pinctrl-names = "default";
+
+ key-1 {
+ gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_1>;
+ label = "SW47";
+ wakeup-source;
+ debounce-interval = <20>;
+ };
+
+ key-2 {
+ gpios = <&gpio5 1 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_2>;
+ label = "SW48";
+ wakeup-source;
+ debounce-interval = <20>;
+ };
+
+ key-3 {
+ gpios = <&gpio5 2 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_3>;
+ label = "SW49";
+ wakeup-source;
+ debounce-interval = <20>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-1 {
+ gpios = <&gpio7 0 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_INDICATOR;
+ function-enumerator = <1>;
+ };
+
+ led-2 {
+ gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_INDICATOR;
+ function-enumerator = <2>;
+ };
+
+ led-3 {
+ gpios = <&gpio7 2 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_INDICATOR;
+ function-enumerator = <3>;
+ };
+ };
+
+ memory@48000000 {
+ device_type = "memory";
+ /* first 128MB is reserved for secure area. */
+ reg = <0x0 0x48000000 0x0 0x78000000>;
+ };
+
+ memory@480000000 {
+ device_type = "memory";
+ reg = <0x4 0x80000000 0x0 0x80000000>;
+ };
+
+ memory@600000000 {
+ device_type = "memory";
+ reg = <0x6 0x00000000 0x1 0x00000000>;
+ };
+
+ mini-dp-con {
+ compatible = "dp-connector";
+ label = "CN5";
+ type = "mini";
+
+ port {
+ mini_dp_con_in: endpoint {
+ remote-endpoint = <&sn65dsi86_out>;
+ };
+ };
+ };
+
+ reg_1p2v: regulator-1p2v {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_1p8v: regulator-1p8v {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_3p3v: regulator-3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+};
+
+&avb0 {
+ pinctrl-0 = <&avb0_pins>;
+ pinctrl-names = "default";
+ phy-handle = <&phy0>;
+ 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>;
+ };
+};
+
+&dsi0 {
+ status = "okay";
+
+ ports {
+ port@1 {
+ dsi0_out: endpoint {
+ remote-endpoint = <&sn65dsi86_in>;
+ data-lanes = <1 2 3 4>;
+ };
+ };
+ };
+};
+
+&du {
+ status = "okay";
+};
+
+&extal_clk {
+ clock-frequency = <16666666>;
+};
+
+&extalr_clk {
+ clock-frequency = <32768>;
+};
+
+&hscif0 {
+ pinctrl-0 = <&hscif0_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-0 = <&i2c0_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+ clock-frequency = <400000>;
+
+ io_expander_a: gpio@20 {
+ compatible = "onnn,pca9654";
+ reg = <0x20>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ eeprom@50 {
+ compatible = "rohm,br24g01", "atmel,24c01";
+ label = "cpu-board";
+ reg = <0x50>;
+ pagesize = <8>;
+ };
+};
+
+&i2c1 {
+ pinctrl-0 = <&i2c1_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+ clock-frequency = <400000>;
+
+ bridge@2c {
+ compatible = "ti,sn65dsi86";
+ reg = <0x2c>;
+
+ clocks = <&sn65dsi86_refclk>;
+ clock-names = "refclk";
+
+ interrupt-parent = <&intc_ex>;
+ interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+
+ enable-gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>;
+
+ vccio-supply = <&reg_1p8v>;
+ vpll-supply = <&reg_1p8v>;
+ vcca-supply = <&reg_1p2v>;
+ vcc-supply = <&reg_1p2v>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ sn65dsi86_in: endpoint {
+ remote-endpoint = <&dsi0_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ sn65dsi86_out: endpoint {
+ remote-endpoint = <&mini_dp_con_in>;
+ };
+ };
+ };
+ };
+};
+
+&mmc0 {
+ pinctrl-0 = <&mmc_pins>;
+ pinctrl-1 = <&mmc_pins>;
+ pinctrl-names = "default", "state_uhs";
+
+ vmmc-supply = <&reg_3p3v>;
+ vqmmc-supply = <&reg_1p8v>;
+ mmc-hs200-1_8v;
+ mmc-hs400-1_8v;
+ bus-width = <8>;
+ no-sd;
+ no-sdio;
+ non-removable;
+ full-pwr-cycle-in-suspend;
+ status = "okay";
+};
+
+&pfc {
+ pinctrl-0 = <&scif_clk_pins>;
+ pinctrl-names = "default";
+
+ avb0_pins: avb0 {
+ mux {
+ groups = "avb0_link", "avb0_mdio", "avb0_rgmii",
+ "avb0_txcrefclk";
+ function = "avb0";
+ };
+
+ pins_mdio {
+ groups = "avb0_mdio";
+ drive-strength = <21>;
+ };
+
+ pins_mii {
+ groups = "avb0_rgmii";
+ drive-strength = <21>;
+ };
+
+ };
+
+ hscif0_pins: hscif0 {
+ groups = "hscif0_data";
+ function = "hscif0";
+ };
+
+ i2c0_pins: i2c0 {
+ groups = "i2c0";
+ function = "i2c0";
+ };
+
+ i2c1_pins: i2c1 {
+ groups = "i2c1";
+ function = "i2c1";
+ };
+
+ keys_pins: keys {
+ pins = "GP_5_0", "GP_5_1", "GP_5_2";
+ bias-pull-up;
+ };
+
+ mmc_pins: mmc {
+ groups = "mmc_data8", "mmc_ctrl", "mmc_ds";
+ function = "mmc";
+ power-source = <1800>;
+ };
+
+ qspi0_pins: qspi0 {
+ groups = "qspi0_ctrl", "qspi0_data4";
+ function = "qspi0";
+ };
+
+ scif_clk_pins: scif_clk {
+ groups = "scif_clk";
+ function = "scif_clk";
+ };
+};
+
+&rpc {
+ pinctrl-0 = <&qspi0_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+
+ flash@0 {
+ compatible = "spansion,s25fs512s", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <40000000>;
+ spi-rx-bus-width = <4>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ boot@0 {
+ reg = <0x0 0x1200000>;
+ read-only;
+ };
+ user@1200000 {
+ reg = <0x1200000 0x2e00000>;
+ };
+ };
+ };
+};
+
+&rwdt {
+ timeout-sec = <60>;
+ status = "okay";
+};
+
+&scif_clk {
+ clock-frequency = <24000000>;
+};
diff --git a/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-csi-dsi.dtsi b/arch/arm64/boot/dts/renesas/white-hawk-csi-dsi.dtsi
index f8537f7ea4de..3006b0a64f41 100644
--- a/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-csi-dsi.dtsi
+++ b/arch/arm64/boot/dts/renesas/white-hawk-csi-dsi.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/*
- * Device Tree Source for the R-Car V4H White Hawk CSI/DSI sub-board
+ * Device Tree Source for the White Hawk CSI/DSI sub-board
*
* Copyright (C) 2022 Glider bv
*/
diff --git a/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-ethernet.dtsi b/arch/arm64/boot/dts/renesas/white-hawk-ethernet.dtsi
index 4f411f95c674..a218fda337cf 100644
--- a/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-ethernet.dtsi
+++ b/arch/arm64/boot/dts/renesas/white-hawk-ethernet.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/*
- * Device Tree Source for the R-Car V4H White Hawk RAVB/Ethernet(1000Base-T1)
+ * Device Tree Source for the White Hawk RAVB/Ethernet(1000Base-T1)
* sub-board
*
* Copyright (C) 2022 Glider bv
diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index a7b30e11beaf..f906a868b71a 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -71,6 +71,8 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rockpro64.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire-excavator.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399pro-rock-pi-n10.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-anbernic-rg-arc-d.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-anbernic-rg-arc-s.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-anbernic-rg353p.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-anbernic-rg353ps.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-anbernic-rg353v.dtb
@@ -78,6 +80,9 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-anbernic-rg353vs.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-anbernic-rg503.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
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-pinetab2-v2.0.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-powkiddy-rgb10max3.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-powkiddy-rgb30.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-powkiddy-rk2023.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-powkiddy-x55.dtb
@@ -98,11 +103,13 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-lubancat-2.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
+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) += 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-jaguar.dtb
@@ -110,9 +117,13 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-nanopc-t6.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-orangepi-5-plus.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-quartzpro64.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-rock-5b.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-tiger-haikou.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-toybrick-x0.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-turing-rk1.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-coolpi-4b.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-indiedroid-nova.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-khadas-edge2.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-nanopi-r6s.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-nanopi-r6c.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-rock-5a.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-orangepi-5.dtb
diff --git a/arch/arm64/boot/dts/rockchip/px30-ringneck-haikou.dts b/arch/arm64/boot/dts/rockchip/px30-ringneck-haikou.dts
index 16798eb77077..ae398acdcf45 100644
--- a/arch/arm64/boot/dts/rockchip/px30-ringneck-haikou.dts
+++ b/arch/arm64/boot/dts/rockchip/px30-ringneck-haikou.dts
@@ -227,6 +227,7 @@
&uart5 {
pinctrl-0 = <&uart5_xfer>;
+ rts-gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/rockchip/px30-ringneck.dtsi b/arch/arm64/boot/dts/rockchip/px30-ringneck.dtsi
index 12397755830b..bb1aea82e666 100644
--- a/arch/arm64/boot/dts/rockchip/px30-ringneck.dtsi
+++ b/arch/arm64/boot/dts/rockchip/px30-ringneck.dtsi
@@ -347,6 +347,12 @@
};
};
+&pmu_io_domains {
+ pmuio1-supply = <&vcc_3v3>;
+ pmuio2-supply = <&vcc_3v3>;
+ status = "okay";
+};
+
&saradc {
vref-supply = <&vcc_1v8>;
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 3cda6c627b68..f09d60bbe6c4 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
@@ -148,7 +148,7 @@
assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>;
assigned-clock-parents = <&gmac_clkin>, <&gmac_clkin>;
clock_in_out = "input";
- phy-handle = <&rtl8211e>;
+ phy-handle = <&rtl8211>;
phy-mode = "rgmii";
phy-supply = <&vcc_io>;
pinctrl-names = "default";
@@ -165,7 +165,7 @@
#address-cells = <1>;
#size-cells = <0>;
- rtl8211e: ethernet-phy@1 {
+ rtl8211: ethernet-phy@1 {
reg = <1>;
pinctrl-0 = <&eth_phy_int_pin>, <&eth_phy_reset_pin>;
pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index 7b4c15c4a9c3..b6f045069ee2 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -744,11 +744,20 @@
status = "disabled";
ports {
- hdmi_in: port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ hdmi_in: port@0 {
+ reg = <0>;
+
hdmi_in_vop: endpoint {
remote-endpoint = <&vop_out_hdmi>;
};
};
+
+ hdmi_out: port@1 {
+ reg = <1>;
+ };
};
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
index 9e3aec4440bd..dfb2a0bdea5b 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
@@ -22,9 +22,6 @@
ethernet0 = &gmac;
mmc0 = &sdmmc;
mmc1 = &sdhci;
- spi1 = &spi1;
- spi2 = &spi2;
- spi5 = &spi5;
};
avdd_0v9_s0: avdd-0v9-s0 {
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts b/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts
index e7551449e718..e26e2d86279c 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts
@@ -14,7 +14,7 @@
/ {
model = "Orange Pi RK3399 Board";
- compatible = "rockchip,rk3399-orangepi", "rockchip,rk3399";
+ compatible = "xunlong,rk3399-orangepi", "rockchip,rk3399";
aliases {
ethernet0 = &gmac;
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts b/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
index 18a98c4648ea..2c3984a880af 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
@@ -273,11 +273,12 @@
&uart0 {
pinctrl-names = "default";
- pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
+ pinctrl-0 = <&uart0_xfer>;
status = "okay";
};
&uart2 {
+ rts-gpios = <&gpio2 RK_PC3 GPIO_ACTIVE_HIGH>;
status = "okay";
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4a.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4a.dts
index d5df8939a658..c68f45849c44 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4a.dts
@@ -19,6 +19,6 @@
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <10000000>;
+ spi-max-frequency = <108000000>;
};
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b.dts
index bee6d7588302..6ea3180e57ca 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b.dts
@@ -37,7 +37,7 @@
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <10000000>;
+ spi-max-frequency = <108000000>;
};
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4c.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4c.dts
index de2ebe4cb4f3..5274938bf1b8 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4c.dts
@@ -49,7 +49,7 @@
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
- spi-max-frequency = <10000000>;
+ spi-max-frequency = <108000000>;
};
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index 6e12c5a920ca..9d5f5b083e3c 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -38,6 +38,12 @@
serial2 = &uart2;
serial3 = &uart3;
serial4 = &uart4;
+ spi0 = &spi0;
+ spi1 = &spi1;
+ spi2 = &spi2;
+ spi3 = &spi3;
+ spi4 = &spi4;
+ spi5 = &spi5;
};
cpus {
@@ -45,7 +51,7 @@
#size-cells = <0>;
cpu-map {
- cluster0 {
+ cluster0 { /* Cortex-A53 */
core0 {
cpu = <&cpu_l0>;
};
@@ -60,7 +66,7 @@
};
};
- cluster1 {
+ cluster1 { /* Cortex-A72 */
core0 {
cpu = <&cpu_b0>;
};
@@ -80,6 +86,13 @@
#cooling-cells = <2>; /* min followed by max */
dynamic-power-coefficient = <100>;
cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+ 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_l>;
};
cpu_l1: cpu@1 {
@@ -92,6 +105,13 @@
#cooling-cells = <2>; /* min followed by max */
dynamic-power-coefficient = <100>;
cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+ 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_l>;
};
cpu_l2: cpu@2 {
@@ -104,6 +124,13 @@
#cooling-cells = <2>; /* min followed by max */
dynamic-power-coefficient = <100>;
cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+ 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_l>;
};
cpu_l3: cpu@3 {
@@ -116,6 +143,13 @@
#cooling-cells = <2>; /* min followed by max */
dynamic-power-coefficient = <100>;
cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+ 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_l>;
};
cpu_b0: cpu@100 {
@@ -128,6 +162,13 @@
#cooling-cells = <2>; /* min followed by max */
dynamic-power-coefficient = <436>;
cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+ i-cache-size = <0xC000>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <256>;
+ d-cache-size = <0x8000>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <256>;
+ next-level-cache = <&l2_cache_b>;
thermal-idle {
#cooling-cells = <2>;
@@ -146,6 +187,13 @@
#cooling-cells = <2>; /* min followed by max */
dynamic-power-coefficient = <436>;
cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+ i-cache-size = <0xC000>;
+ i-cache-line-size = <64>;
+ i-cache-sets = <256>;
+ d-cache-size = <0x8000>;
+ d-cache-line-size = <64>;
+ d-cache-sets = <256>;
+ next-level-cache = <&l2_cache_b>;
thermal-idle {
#cooling-cells = <2>;
@@ -154,6 +202,24 @@
};
};
+ l2_cache_l: l2-cache-cluster0 {
+ compatible = "cache";
+ cache-level = <2>;
+ cache-unified;
+ cache-size = <0x80000>;
+ cache-line-size = <64>;
+ cache-sets = <512>;
+ };
+
+ l2_cache_b: l2-cache-cluster1 {
+ compatible = "cache";
+ cache-level = <2>;
+ cache-unified;
+ cache-size = <0x100000>;
+ cache-line-size = <64>;
+ cache-sets = <1024>;
+ };
+
idle-states {
entry-method = "psci";
@@ -1956,6 +2022,7 @@
hdmi: hdmi@ff940000 {
compatible = "rockchip,rk3399-dw-hdmi";
reg = <0x0 0xff940000 0x0 0x20000>;
+ reg-io-width = <4>;
interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH 0>;
clocks = <&cru PCLK_HDMI_CTRL>,
<&cru SCLK_HDMI_SFR>,
@@ -1964,13 +2031,16 @@
<&cru PLL_VPLL>;
clock-names = "iahb", "isfr", "cec", "grf", "ref";
power-domains = <&power RK3399_PD_HDCP>;
- reg-io-width = <4>;
rockchip,grf = <&grf>;
#sound-dai-cells = <0>;
status = "disabled";
ports {
- hdmi_in: port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ hdmi_in: port@0 {
+ reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
@@ -1983,6 +2053,10 @@
remote-endpoint = <&vopl_out_hdmi>;
};
};
+
+ hdmi_out: port@1 {
+ reg = <1>;
+ };
};
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg-arc-d.dts b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg-arc-d.dts
new file mode 100644
index 000000000000..ab83e8a61615
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg-arc-d.dts
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rk3566-anbernic-rg-arc.dtsi"
+
+/ {
+ model = "Anbernic RG ARC-D";
+ compatible = "anbernic,rg-arc-d", "rockchip,rk3566";
+
+ aliases {
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc0;
+ mmc2 = &sdmmc1;
+ mmc3 = &sdmmc2;
+ };
+};
+
+&i2c2 {
+ pinctrl-0 = <&i2c2m1_xfer>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ touchscreen@14 {
+ compatible = "goodix,gt927";
+ reg = <0x14>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <RK_PB1 IRQ_TYPE_EDGE_FALLING>;
+ irq-gpios = <&gpio4 RK_PB1 GPIO_ACTIVE_HIGH>;
+ pinctrl-0 = <&touch_int>;
+ pinctrl-names = "default";
+ reset-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>;
+ touchscreen-inverted-y;
+ touchscreen-size-x = <640>;
+ touchscreen-size-y = <480>;
+ };
+};
+
+&pinctrl {
+ touchscreen {
+ touch_int: touch_int {
+ rockchip,pins = <4 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+};
+
+&sdhci {
+ bus-width = <8>;
+ mmc-hs200-1_8v;
+ non-removable;
+ pinctrl-0 = <&emmc_bus8>, <&emmc_clk>, <&emmc_cmd>,
+ <&emmc_datastrobe>, <&emmc_rstnout>;
+ pinctrl-names = "default";
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&vcc_1v8>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg-arc-s.dts b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg-arc-s.dts
new file mode 100644
index 000000000000..6264a8c78d0b
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg-arc-s.dts
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rk3566-anbernic-rg-arc.dtsi"
+
+/ {
+ model = "Anbernic RG ARC-S";
+ compatible = "anbernic,rg-arc-s", "rockchip,rk3566";
+
+ aliases {
+ mmc1 = &sdmmc0;
+ mmc2 = &sdmmc1;
+ mmc3 = &sdmmc2;
+ };
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg-arc.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg-arc.dtsi
new file mode 100644
index 000000000000..a4a60e4a53d4
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg-arc.dtsi
@@ -0,0 +1,237 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rk3566-anbernic-rgxx3.dtsi"
+
+/ {
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ power-supply = <&vcc_sys>;
+ pwms = <&pwm4 0 25000 0>;
+ };
+
+ battery: battery {
+ compatible = "simple-battery";
+ charge-full-design-microamp-hours = <3472000>;
+ charge-term-current-microamp = <300000>;
+ constant-charge-current-max-microamp = <2000000>;
+ constant-charge-voltage-max-microvolt = <4200000>;
+ factory-internal-resistance-micro-ohms = <117000>;
+ voltage-max-design-microvolt = <4172000>;
+ voltage-min-design-microvolt = <3400000>;
+
+ ocv-capacity-celsius = <20>;
+ ocv-capacity-table-0 = <4172000 100>, <4054000 95>, <3984000 90>, <3926000 85>,
+ <3874000 80>, <3826000 75>, <3783000 70>, <3746000 65>,
+ <3714000 60>, <3683000 55>, <3650000 50>, <3628000 45>,
+ <3612000 40>, <3600000 35>, <3587000 30>, <3571000 25>,
+ <3552000 20>, <3525000 15>, <3492000 10>, <3446000 5>,
+ <3400000 0>;
+ };
+
+ /* Channels reversed for both headphones and speakers. */
+ 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 = <&gpio4 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_8ch>;
+ };
+ };
+
+ spk_amp: audio-amplifier {
+ compatible = "simple-audio-amplifier";
+ enable-gpios = <&gpio4 RK_PC2 GPIO_ACTIVE_HIGH>;
+ pinctrl-0 = <&spk_amp_enable_h>;
+ pinctrl-names = "default";
+ sound-name-prefix = "Speaker Amp";
+ };
+};
+
+&cru {
+ assigned-clocks = <&pmucru CLK_RTC_32K>, <&cru PLL_GPLL>,
+ <&pmucru PLL_PPLL>, <&cru PLL_VPLL>;
+ assigned-clock-rates = <32768>, <1200000000>,
+ <200000000>, <128000000>;
+};
+
+&dsi_dphy0 {
+ status = "okay";
+};
+
+&dsi0 {
+ status = "okay";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ports {
+ dsi0_in: port@0 {
+ reg = <0>;
+ dsi0_in_vp1: endpoint {
+ remote-endpoint = <&vp1_out_dsi0>;
+ };
+ };
+
+ dsi0_out: port@1 {
+ reg = <1>;
+ mipi_out_panel: endpoint {
+ remote-endpoint = <&mipi_in_panel>;
+ };
+ };
+ };
+
+ panel: panel@0 {
+ compatible = "anbernic,rg-arc-panel", "sitronix,st7701";
+ reg = <0>;
+ backlight = <&backlight>;
+ IOVCC-supply = <&vcc3v3_lcd0_n>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcd_rst>;
+ reset-gpios = <&gpio4 RK_PA0 GPIO_ACTIVE_HIGH>;
+ rotation = <90>;
+ VCC-supply = <&vcc3v3_lcd0_n>;
+
+ port {
+ mipi_in_panel: endpoint {
+ remote-endpoint = <&mipi_out_panel>;
+ };
+ };
+ };
+};
+
+/*
+ * Device uses a non-standard six button layout for a gamepad with X,
+ * Y, and Z on the top row of buttons and A, B, and C under the bottom
+ * row.
+ */
+&gpio_keys_control {
+ button-a {
+ gpios = <&gpio3 RK_PC3 GPIO_ACTIVE_LOW>;
+ label = "A";
+ linux,code = <BTN_A>;
+ };
+
+ button-b {
+ gpios = <&gpio3 RK_PC2 GPIO_ACTIVE_LOW>;
+ label = "B";
+ linux,code = <BTN_B>;
+ };
+
+ button-c {
+ gpios = <&gpio3 RK_PA2 GPIO_ACTIVE_LOW>;
+ label = "C";
+ linux,code = <BTN_C>;
+ };
+
+ button-left {
+ gpios = <&gpio3 RK_PA6 GPIO_ACTIVE_LOW>;
+ label = "DPAD-LEFT";
+ linux,code = <BTN_DPAD_LEFT>;
+ };
+
+ button-r1 {
+ gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>;
+ label = "TR";
+ linux,code = <BTN_TR>;
+ };
+
+ button-r2 {
+ gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_LOW>;
+ label = "TR2";
+ linux,code = <BTN_TR2>;
+ };
+
+ button-right {
+ gpios = <&gpio3 RK_PA5 GPIO_ACTIVE_LOW>;
+ label = "DPAD-RIGHT";
+ linux,code = <BTN_DPAD_RIGHT>;
+ };
+
+ button-x {
+ gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>;
+ label = "X";
+ linux,code = <BTN_X>;
+ };
+
+ button-y {
+ gpios = <&gpio3 RK_PC1 GPIO_ACTIVE_LOW>;
+ label = "Y";
+ linux,code = <BTN_Y>;
+ };
+
+ button-z {
+ gpios = <&gpio3 RK_PA1 GPIO_ACTIVE_LOW>;
+ label = "Z";
+ linux,code = <BTN_Z>;
+ };
+};
+
+&pinctrl {
+ audio-amplifier {
+ spk_amp_enable_h: spk-amp-enable-h {
+ rockchip,pins =
+ <4 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ gpio-lcd {
+ lcd_rst: lcd-rst {
+ rockchip,pins =
+ <4 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ headphone {
+ hp_det: hp-det {
+ rockchip,pins =
+ <4 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&pwm4 {
+ status = "okay";
+};
+
+&rk817 {
+ rk817_charger: charger {
+ monitored-battery = <&battery>;
+ rockchip,resistor-sense-micro-ohms = <10000>;
+ rockchip,sleep-enter-current-microamp = <300000>;
+ rockchip,sleep-filter-current-microamp = <100000>;
+ };
+};
+
+&vp1 {
+ vp1_out_dsi0: endpoint@ROCKCHIP_VOP2_EP_MIPI0 {
+ reg = <ROCKCHIP_VOP2_EP_MIPI0>;
+ remote-endpoint = <&dsi0_in_vp1>;
+ };
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353x.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353x.dtsi
index 2a2821f4c580..63a18ff36cea 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353x.dtsi
@@ -8,11 +8,73 @@
#include "rk3566-anbernic-rgxx3.dtsi"
/ {
+ adc-joystick {
+ compatible = "adc-joystick";
+ io-channels = <&adc_mux 0>,
+ <&adc_mux 1>,
+ <&adc_mux 2>,
+ <&adc_mux 3>;
+ pinctrl-0 = <&joy_mux_en>;
+ pinctrl-names = "default";
+ poll-interval = <60>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ axis@0 {
+ reg = <0>;
+ abs-flat = <32>;
+ abs-fuzz = <32>;
+ abs-range = <1023 15>;
+ linux,code = <ABS_X>;
+ };
+
+ axis@1 {
+ reg = <1>;
+ abs-flat = <32>;
+ abs-fuzz = <32>;
+ abs-range = <15 1023>;
+ linux,code = <ABS_RX>;
+ };
+
+ axis@2 {
+ reg = <2>;
+ abs-flat = <32>;
+ abs-fuzz = <32>;
+ abs-range = <15 1023>;
+ linux,code = <ABS_Y>;
+ };
+
+ axis@3 {
+ reg = <3>;
+ abs-flat = <32>;
+ abs-fuzz = <32>;
+ abs-range = <1023 15>;
+ linux,code = <ABS_RY>;
+ };
+ };
+
+ adc_mux: adc-mux {
+ compatible = "io-channel-mux";
+ channels = "left_x", "right_x", "left_y", "right_y";
+ #io-channel-cells = <1>;
+ io-channels = <&saradc 3>;
+ io-channel-names = "parent";
+ mux-controls = <&gpio_mux>;
+ settle-time-us = <100>;
+ };
+
backlight: backlight {
compatible = "pwm-backlight";
power-supply = <&vcc_sys>;
pwms = <&pwm4 0 25000 0>;
};
+
+ gpio_mux: mux-controller {
+ compatible = "gpio-mux";
+ mux-gpios = <&gpio0 RK_PB6 GPIO_ACTIVE_LOW>,
+ <&gpio0 RK_PB7 GPIO_ACTIVE_LOW>;
+ #mux-control-cells = <0>;
+ };
};
&cru {
@@ -83,6 +145,18 @@
linux,code = <BTN_DPAD_RIGHT>;
};
+ button-thumbl {
+ gpios = <&gpio3 RK_PA1 GPIO_ACTIVE_LOW>;
+ label = "THUMBL";
+ linux,code = <BTN_THUMBL>;
+ };
+
+ button-thumbr {
+ gpios = <&gpio3 RK_PA2 GPIO_ACTIVE_LOW>;
+ label = "THUMBR";
+ linux,code = <BTN_THUMBR>;
+ };
+
button-y {
gpios = <&gpio3 RK_PC1 GPIO_ACTIVE_LOW>;
label = "WEST";
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg503.dts b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg503.dts
index c763c7f3b1b3..94e6dd61a2db 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg503.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg503.dts
@@ -17,6 +17,61 @@
mmc2 = &sdmmc2;
};
+ adc-joystick {
+ compatible = "adc-joystick";
+ io-channels = <&adc_mux 0>,
+ <&adc_mux 1>,
+ <&adc_mux 2>,
+ <&adc_mux 3>;
+ pinctrl-0 = <&joy_mux_en>;
+ pinctrl-names = "default";
+ poll-interval = <60>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ axis@0 {
+ reg = <0>;
+ abs-flat = <32>;
+ abs-fuzz = <32>;
+ abs-range = <1023 15>;
+ linux,code = <ABS_X>;
+ };
+
+ axis@1 {
+ reg = <1>;
+ abs-flat = <32>;
+ abs-fuzz = <32>;
+ abs-range = <15 1023>;
+ linux,code = <ABS_RX>;
+ };
+
+ axis@2 {
+ reg = <2>;
+ abs-flat = <32>;
+ abs-fuzz = <32>;
+ abs-range = <15 1023>;
+ linux,code = <ABS_Y>;
+ };
+
+ axis@3 {
+ reg = <3>;
+ abs-flat = <32>;
+ abs-fuzz = <32>;
+ abs-range = <1023 15>;
+ linux,code = <ABS_RY>;
+ };
+ };
+
+ adc_mux: adc-mux {
+ compatible = "io-channel-mux";
+ channels = "left_x", "right_x", "left_y", "right_y";
+ #io-channel-cells = <1>;
+ io-channels = <&saradc 3>;
+ io-channel-names = "parent";
+ mux-controls = <&gpio_mux>;
+ settle-time-us = <100>;
+ };
+
battery: battery {
compatible = "simple-battery";
charge-full-design-microamp-hours = <3472000>;
@@ -36,6 +91,13 @@
<3400000 0>;
};
+ gpio_mux: mux-controller {
+ compatible = "gpio-mux";
+ mux-gpios = <&gpio0 RK_PB6 GPIO_ACTIVE_LOW>,
+ <&gpio0 RK_PB7 GPIO_ACTIVE_LOW>;
+ #mux-control-cells = <0>;
+ };
+
gpio_spi: spi {
compatible = "spi-gpio";
pinctrl-names = "default";
@@ -174,6 +236,18 @@
linux,code = <BTN_DPAD_RIGHT>;
};
+ button-thumbl {
+ gpios = <&gpio3 RK_PA1 GPIO_ACTIVE_LOW>;
+ label = "THUMBL";
+ linux,code = <BTN_THUMBL>;
+ };
+
+ button-thumbr {
+ gpios = <&gpio3 RK_PA2 GPIO_ACTIVE_LOW>;
+ label = "THUMBR";
+ linux,code = <BTN_THUMBR>;
+ };
+
button-y {
gpios = <&gpio3 RK_PC2 GPIO_ACTIVE_LOW>;
label = "WEST";
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rgxx3.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rgxx3.dtsi
index 8cbf3d9a4f22..18b8c2e7befa 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rgxx3.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rgxx3.dtsi
@@ -14,51 +14,6 @@
stdout-path = "serial2:1500000n8";
};
- adc-joystick {
- compatible = "adc-joystick";
- io-channels = <&adc_mux 0>,
- <&adc_mux 1>,
- <&adc_mux 2>,
- <&adc_mux 3>;
- pinctrl-0 = <&joy_mux_en>;
- pinctrl-names = "default";
- poll-interval = <60>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- axis@0 {
- reg = <0>;
- abs-flat = <32>;
- abs-fuzz = <32>;
- abs-range = <1023 15>;
- linux,code = <ABS_X>;
- };
-
- axis@1 {
- reg = <1>;
- abs-flat = <32>;
- abs-fuzz = <32>;
- abs-range = <15 1023>;
- linux,code = <ABS_RX>;
- };
-
- axis@2 {
- reg = <2>;
- abs-flat = <32>;
- abs-fuzz = <32>;
- abs-range = <15 1023>;
- linux,code = <ABS_Y>;
- };
-
- axis@3 {
- reg = <3>;
- abs-flat = <32>;
- abs-fuzz = <32>;
- abs-range = <1023 15>;
- linux,code = <ABS_RY>;
- };
- };
-
adc_keys: adc-keys {
compatible = "adc-keys";
io-channels = <&saradc 0>;
@@ -77,16 +32,6 @@
};
};
- adc_mux: adc-mux {
- compatible = "io-channel-mux";
- channels = "left_x", "right_x", "left_y", "right_y";
- #io-channel-cells = <1>;
- io-channels = <&saradc 3>;
- io-channel-names = "parent";
- mux-controls = <&gpio_mux>;
- settle-time-us = <100>;
- };
-
gpio_keys_control: gpio-keys-control {
compatible = "gpio-keys";
pinctrl-0 = <&btn_pins_ctrl>;
@@ -128,18 +73,6 @@
linux,code = <BTN_START>;
};
- button-thumbl {
- gpios = <&gpio3 RK_PA1 GPIO_ACTIVE_LOW>;
- label = "THUMBL";
- linux,code = <BTN_THUMBL>;
- };
-
- button-thumbr {
- gpios = <&gpio3 RK_PA2 GPIO_ACTIVE_LOW>;
- label = "THUMBR";
- linux,code = <BTN_THUMBR>;
- };
-
button-up {
gpios = <&gpio3 RK_PA3 GPIO_ACTIVE_LOW>;
label = "DPAD-UP";
@@ -172,13 +105,6 @@
};
};
- gpio_mux: mux-controller {
- compatible = "gpio-mux";
- mux-gpios = <&gpio0 RK_PB6 GPIO_ACTIVE_LOW>,
- <&gpio0 RK_PB7 GPIO_ACTIVE_LOW>;
- #mux-control-cells = <0>;
- };
-
hdmi-con {
compatible = "hdmi-connector";
ddc-i2c-bus = <&i2c5>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-pinetab2-v0.1.dts b/arch/arm64/boot/dts/rockchip/rk3566-pinetab2-v0.1.dts
new file mode 100644
index 000000000000..5fe6ca5da9d3
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-pinetab2-v0.1.dts
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include "rk3566-pinetab2.dtsi"
+
+/ {
+ model = "Pine64 PineTab2 v0.1";
+ compatible = "pine64,pinetab2-v0.1", "pine64,pinetab2", "rockchip,rk3566";
+};
+
+&lcd {
+ reset-gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcd_pwren_h &lcd0_rst_l>;
+};
+
+&pinctrl {
+ lcd0 {
+ lcd0_rst_l: lcd0-rst-l {
+ rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&sdmmc1 {
+ vmmc-supply = <&vcc3v3_sys>;
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-pinetab2-v2.0.dts b/arch/arm64/boot/dts/rockchip/rk3566-pinetab2-v2.0.dts
new file mode 100644
index 000000000000..9349541cbbd0
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-pinetab2-v2.0.dts
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include "rk3566-pinetab2.dtsi"
+
+/ {
+ model = "Pine64 PineTab2 v2.0";
+ compatible = "pine64,pinetab2-v2.0", "pine64,pinetab2", "rockchip,rk3566";
+};
+
+&gpio_keys {
+ pinctrl-0 = <&kb_id_det>, <&hall_int_l>;
+
+ event-hall-sensor {
+ debounce-interval = <20>;
+ gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_LOW>;
+ label = "Hall Sensor";
+ linux,code = <SW_LID>;
+ linux,input-type = <EV_SW>;
+ wakeup-event-action = <EV_ACT_DEASSERTED>;
+ wakeup-source;
+ };
+};
+
+&lcd {
+ reset-gpios = <&gpio0 RK_PC6 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcd_pwren_h &lcd0_rst_l>;
+};
+
+&pinctrl {
+ lcd0 {
+ lcd0_rst_l: lcd0-rst-l {
+ rockchip,pins = <0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ hall {
+ hall_int_l: hall-int-l {
+ rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&sdmmc1 {
+ vmmc-supply = <&vcc_sys>;
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-pinetab2.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-pinetab2.dtsi
new file mode 100644
index 000000000000..db40281eafbe
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-pinetab2.dtsi
@@ -0,0 +1,943 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/gpio-keys.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
+#include <dt-bindings/usb/pd.h>
+#include "rk3566.dtsi"
+
+/ {
+ chassis-type = "tablet";
+
+ aliases {
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc0;
+ };
+
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+
+ adc-keys {
+ compatible = "adc-keys";
+ io-channels = <&saradc 0>;
+ io-channel-names = "buttons";
+ keyup-threshold-microvolt = <1800000>;
+ poll-interval = <25>;
+
+ button-vol-up {
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+ press-threshold-microvolt = <297500>;
+ };
+
+ button-vol-down {
+ label = "Volume Down";
+ linux,code = <KEY_VOLUMEDOWN>;
+ press-threshold-microvolt = <1750>;
+ };
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm4 0 25000 0>;
+ brightness-levels = <20 220>;
+ num-interpolated-steps = <200>;
+ default-brightness-level = <100>;
+ power-supply = <&vcc_sys>;
+ };
+
+ battery: battery {
+ compatible = "simple-battery";
+ charge-full-design-microamp-hours = <6000000>;
+ charge-term-current-microamp = <300000>;
+ constant-charge-current-max-microamp = <2000000>;
+ constant-charge-voltage-max-microvolt = <4300000>;
+ voltage-max-design-microvolt = <4350000>;
+ voltage-min-design-microvolt = <3400000>;
+
+ ocv-capacity-celsius = <20>;
+ ocv-capacity-table-0 = <4322000 100>, <4250000 95>, <4192000 90>, <4136000 85>,
+ <4080000 80>, <4022000 75>, <3972000 70>, <3928000 65>,
+ <3885000 60>, <3833000 55>, <3798000 50>, <3780000 45>,
+ <3776000 40>, <3773000 35>, <3755000 30>, <3706000 25>,
+ <3640000 20>, <3589000 15>, <3535000 10>, <3492000 5>,
+ <3400000 0>;
+ };
+
+ gpio_keys: gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&kb_id_det>;
+
+ tablet-mode-switch {
+ debounce-interval = <20>;
+ gpios = <&gpio4 RK_PA4 GPIO_ACTIVE_HIGH>;
+ label = "Tablet Mode";
+ linux,input-type = <EV_SW>;
+ linux,code = <SW_TABLET_MODE>;
+ };
+ };
+
+ hdmi-connector {
+ compatible = "hdmi-connector";
+ type = "d";
+
+ port {
+ hdmi_con_in: endpoint {
+ remote-endpoint = <&hdmi_out_con>;
+ };
+ };
+ };
+
+ led-0 {
+ compatible = "regulator-led";
+ vled-supply = <&vcc5v0_flashled>;
+ color = <LED_COLOR_ID_WHITE>;
+ function = LED_FUNCTION_FLASH;
+ };
+
+ rk817-sound {
+ compatible = "simple-audio-card";
+ pinctrl-names = "default";
+ pinctrl-0 = <&hp_det_l>;
+ simple-audio-card,format = "i2s";
+ simple-audio-card,name = "rk817_ext";
+ simple-audio-card,mclk-fs = <256>;
+
+ simple-audio-card,widgets =
+ "Microphone", "Mic Jack",
+ "Headphone", "Headphones",
+ "Speaker", "Internal Speakers";
+
+ simple-audio-card,routing =
+ "MICR", "Mic Jack",
+ "Headphones", "HPOL",
+ "Headphones", "HPOR",
+ "Internal Speakers", "Speaker Amplifier OUTL",
+ "Internal Speakers", "Speaker Amplifier OUTR",
+ "Speaker Amplifier INL", "HPOL",
+ "Speaker Amplifier INR", "HPOR";
+ simple-audio-card,hp-det-gpio = <&gpio4 RK_PC6 GPIO_ACTIVE_LOW>;
+ simple-audio-card,aux-devs = <&speaker_amp>;
+ simple-audio-card,pin-switches = "Internal Speakers";
+
+ simple-audio-card,cpu {
+ sound-dai = <&i2s1_8ch>;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&rk817>;
+ };
+ };
+
+ speaker_amp: speaker-amplifier {
+ compatible = "simple-audio-amplifier";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spk_ctl>;
+ enable-gpios = <&gpio4 RK_PC2 GPIO_ACTIVE_HIGH>;
+ sound-name-prefix = "Speaker Amplifier";
+ VCC-supply = <&vcc_bat>;
+ };
+
+ vcc_3v3: vcc-3v3-regulator {
+ 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>;
+ };
+
+ vcc3v3_minipcie: vcc3v3-minipcie-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio4 RK_PC3 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie_pwren_h>;
+ regulator-name = "vcc3v3_minipcie";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc_sys>;
+ };
+
+ vcc3v3_sd: vcc3v3-sd-regulator {
+ compatible = "regulator-fixed";
+ gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc_pwren_l>;
+ regulator-name = "vcc3v3_sd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc3v3_sys>;
+ };
+
+ vcc5v0_flashled: vcc5v0-flashled-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&flash_led_en_h>;
+ regulator-name = "vcc5v0_flashled";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v_midu>;
+ };
+
+ vcc5v0_usb_host0: vcc5v0-usb-host0-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio4 RK_PC4 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb_host_pwren1_h>;
+ regulator-name = "vcc5v0_usb_host0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v_midu>;
+ };
+
+ vcc5v0_usb_host2: vcc5v0-usb-host2-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio4 RK_PC5 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb_host_pwren2_h>;
+ regulator-name = "vcc5v0_usb_host2";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v_midu>;
+ };
+
+ vcc_bat: vcc-bat-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_bat";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vcc_sys: vcc-sys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vcc_bat>;
+ };
+
+ vdd1v2_dvp: vdd1v2-dvp-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd1v2_dvp";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ vin-supply = <&vcc_3v3>;
+ };
+};
+
+&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>;
+};
+
+&cru {
+ assigned-clocks = <&pmucru CLK_RTC_32K>, <&cru PLL_GPLL>,
+ <&pmucru PLL_PPLL>, <&cru PLL_VPLL>;
+ assigned-clock-rates = <32768>, <1200000000>, <200000000>, <500000000>;
+ assigned-clock-parents = <&pmucru CLK_RTC32K_FRAC>;
+};
+
+&csi_dphy {
+ status = "okay";
+};
+
+&dsi0 {
+ status = "okay";
+ clock-master;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ lcd: panel@0 {
+ compatible = "boe,th101mb31ig002-28a";
+ reg = <0>;
+ backlight = <&backlight>;
+ enable-gpios = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
+ rotation = <90>;
+ power-supply = <&vcc_3v3>;
+
+ port@0 {
+ panel_in_dsi: endpoint@0 {
+ remote-endpoint = <&dsi0_out_con>;
+ };
+ };
+ };
+};
+
+&dsi0_in {
+ dsi0_in_vp1: endpoint {
+ remote-endpoint = <&vp1_out_dsi0>;
+ };
+};
+
+&dsi0_out {
+ dsi0_out_con: endpoint {
+ remote-endpoint = <&panel_in_dsi>;
+ };
+};
+
+&dsi_dphy0 {
+ status = "okay";
+};
+
+&gpu {
+ mali-supply = <&vdd_gpu_npu>;
+ status = "okay";
+};
+
+&hdmi {
+ avdd-0v9-supply = <&vdda_0v9_p>;
+ avdd-1v8-supply = <&vcc_1v8>;
+ 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 {
+ clock-frequency = <400000>;
+ status = "okay";
+
+ vdd_cpu: regulator@1c {
+ compatible = "tcs,tcs4525";
+ reg = <0x1c>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1150000>;
+ regulator-ramp-delay = <2300>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vcc_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ rk817: pmic@20 {
+ compatible = "rockchip,rk817";
+ reg = <0x20>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
+ assigned-clocks = <&cru I2S1_MCLKOUT_TX>;
+ assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>;
+ clock-names = "mclk";
+ clocks = <&cru I2S1_MCLKOUT_TX>;
+ clock-output-names = "rk808-clkout1", "rk808-clkout2";
+ #clock-cells = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_int_l>, <&i2s1m0_mclk>;
+ rockchip,system-power-controller;
+ #sound-dai-cells = <0>;
+ 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-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-ramp-delay = <6001>;
+ regulator-initial-mode = <0x2>;
+ regulator-name = "vdd_logic";
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_gpu_npu: DCDC_REG2 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-ramp-delay = <6001>;
+ regulator-initial-mode = <0x2>;
+ regulator-name = "vdd_gpu_npu";
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_ddr: DCDC_REG3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-initial-mode = <0x2>;
+ regulator-name = "vcc_ddr";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc3v3_sys: DCDC_REG4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-initial-mode = <0x2>;
+ regulator-name = "vcc3v3_sys";
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcca1v8_pmu: LDO_REG1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcca1v8_pmu";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vdda_0v9_p: LDO_REG2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+ regulator-name = "vdda_0v9_p";
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdda0v9_pmu: LDO_REG3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+ regulator-name = "vdda0v9_pmu";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vccio_acodec: LDO_REG4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vccio_acodec";
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vccio_sd: LDO_REG5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vccio_sd";
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc3v3_pmu: LDO_REG6 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc3v3_pmu";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_1v8: LDO_REG7 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc_1v8";
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc1v8_dvp: LDO_REG8 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc1v8_dvp";
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc2v8_dvp: LDO_REG9 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-name = "vcc2v8_dvp";
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc5v_midu: BOOST {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-name = "boost";
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vbus: OTG_SWITCH {
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-name = "otg_switch";
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+
+ charger {
+ monitored-battery = <&battery>;
+ rockchip,resistor-sense-micro-ohms = <10000>;
+ rockchip,sleep-enter-current-microamp = <300000>;
+ rockchip,sleep-filter-current-microamp = <100000>;
+ };
+ };
+};
+
+&i2c1 {
+ clock-frequency = <400000>;
+ status = "okay";
+
+ touchscreen@5d {
+ compatible = "goodix,gt911";
+ reg = <0x5d>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PB0 IRQ_TYPE_EDGE_FALLING>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&tp_int_l_pmuio2>, <&tp_rst_l_pmuio2>;
+ AVDD28-supply = <&vcc3v3_pmu>;
+ VDDIO-supply = <&vcca1v8_pmu>;
+ irq-gpios = <&gpio0 RK_PB0 GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&gpio0 RK_PC2 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&i2c2 {
+ clock-frequency = <400000>;
+ pinctrl-0 = <&i2c2m1_xfer>;
+ status = "okay";
+
+ vcm@c {
+ compatible = "dongwoon,dw9714";
+ reg = <0x0c>;
+ vcc-supply = <&vcc1v8_dvp>;
+ };
+
+ camera@36 {
+ compatible = "ovti,ov5648";
+ reg = <0x36>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&camerab_pdn_l &camerab_rst_l>;
+
+ clocks = <&cru CLK_CIF_OUT>;
+ assigned-clocks = <&cru CLK_CIF_OUT>;
+ assigned-clock-rates = <24000000>;
+
+ avdd-supply = <&vcc2v8_dvp>;
+ dvdd-supply = <&vdd1v2_dvp>;
+ dovdd-supply = <&vcc1v8_dvp>;
+ powerdown-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_LOW>;
+ reset-gpios = <&gpio4 RK_PB1 GPIO_ACTIVE_LOW>;
+
+ port {
+ endpoint {
+ data-lanes = <1 2>;
+ remote-endpoint = <0>;
+ link-frequencies = /bits/ 64 <210000000 168000000>;
+ };
+ };
+ };
+};
+
+&i2c5 {
+ clock-frequency = <400000>;
+ status = "okay";
+
+ accelerometer@18 {
+ compatible = "silan,sc7a20";
+ reg = <0x18>;
+ interrupt-parent = <&gpio3>;
+ interrupts = <RK_PA2 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&gsensor_int_l>;
+ st,drdy-int-pin = <1>;
+ vdd-supply = <&vcc_1v8>;
+ vddio-supply = <&vcc_1v8>;
+ mount-matrix = "1", "0", "0",
+ "0", "0", "1",
+ "0", "1", "0";
+ };
+};
+
+&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 = <&pcie_reset_h>;
+ reset-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_minipcie>;
+ status = "okay";
+};
+
+&pinctrl {
+ camerab {
+ camerab_pdn_l: camerab-pdn-l {
+ rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ camerab_rst_l: camerab-rst-l {
+ rockchip,pins = <4 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ cameraf {
+ cameraf_pdn_l: cameraf-pdn-l {
+ rockchip,pins = <4 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ cameraf_rst_l: cameraf-rst-l {
+ rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ flash {
+ flash_led_en_h: flash-led-en-h {
+ rockchip,pins = <4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ fspi {
+ fspi_dual_io_pins: fspi-dual-io-pins {
+ rockchip,pins =
+ /* fspi_clk */
+ <1 RK_PD0 1 &pcfg_pull_none>,
+ /* fspi_cs0n */
+ <1 RK_PD3 1 &pcfg_pull_none>,
+ /* fspi_d0 */
+ <1 RK_PD1 1 &pcfg_pull_none>,
+ /* fspi_d1 */
+ <1 RK_PD2 1 &pcfg_pull_none>;
+ };
+ };
+
+ gsensor {
+ gsensor_int_l: gsensor-int-l {
+ rockchip,pins = <3 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ kb {
+ kb_id_det: kb-id-det {
+ rockchip,pins = <4 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ lcd {
+ lcd_pwren_h: lcd-pwren-h {
+ rockchip,pins = <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pcie {
+ pcie_pwren_h: pcie-pwren-h {
+ rockchip,pins = <4 RK_PC3 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>;
+ };
+ };
+
+ sdmmc {
+ sdmmc_pwren_l: sdmmc-pwren-l {
+ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ sound {
+ hp_det_l: hp-det-l {
+ rockchip,pins = <4 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ spk_ctl: spk-ctl {
+ rockchip,pins = <4 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ tp {
+ tp_int_l_pmuio2: tp-int-l-pmuio2 {
+ rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+
+ tp_rst_l_pmuio2: tp-rst-l-pmuio2 {
+ rockchip,pins = <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ usb {
+ usbcc_int_l: usbcc-int-l {
+ rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ usb_host_pwren1_h: usb-host-pwren1-h {
+ rockchip,pins = <4 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ usb_host_pwren2_h: usb-host-pwren2-h {
+ rockchip,pins = <4 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ wifi {
+ host_wake_wl: host-wake-wl {
+ rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ wifi_wake_host_h: wifi-wake-host-h {
+ rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+ };
+};
+
+&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_1v8>;
+ vccio6-supply = <&vcc1v8_dvp>;
+ vccio7-supply = <&vcc_3v3>;
+ status = "okay";
+};
+
+&pwm4 {
+ status = "okay";
+};
+
+&saradc {
+ vref-supply = <&vcc_1v8>;
+ status = "okay";
+};
+
+&sdhci {
+ bus-width = <8>;
+ no-sdio;
+ no-sd;
+ non-removable;
+ max-frequency = <200000000>;
+ mmc-hs200-1_8v;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_bus8
+ &emmc_clk
+ &emmc_cmd
+ &emmc_datastrobe
+ &emmc_rstnout>;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&vcc_1v8>;
+ 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-sdr104;
+ vmmc-supply = <&vcc3v3_sd>;
+ vqmmc-supply = <&vccio_sd>;
+ status = "okay";
+};
+
+&sdmmc1 {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ keep-power-in-suspend;
+ non-removable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc1_bus4
+ &sdmmc1_cmd
+ &sdmmc1_clk>;
+ sd-uhs-sdr104;
+ vqmmc-supply = <&vcca1v8_pmu>;
+ status = "okay";
+};
+
+&sfc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&fspi_dual_io_pins>;
+ status = "okay";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <100000000>;
+ spi-rx-bus-width = <2>;
+ spi-tx-bus-width = <1>;
+ };
+};
+
+&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 {
+ status = "okay";
+};
+
+&usb_host1_xhci {
+ status = "okay";
+};
+
+&usb2phy0 {
+ status = "okay";
+};
+
+&usb2phy0_host {
+ phy-supply = <&vcc5v0_usb_host0>;
+ status = "okay";
+};
+
+&usb2phy0_otg {
+ status = "okay";
+};
+
+&usb2phy1 {
+ status = "okay";
+};
+
+&usb2phy1_otg {
+ phy-supply = <&vcc5v0_usb_host2>;
+ 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>;
+ };
+};
+
+&vp1 {
+ vp1_out_dsi0: endpoint@ROCKCHIP_VOP2_EP_MIPI0 {
+ reg = <ROCKCHIP_VOP2_EP_MIPI0>;
+ remote-endpoint = <&dsi0_in_vp1>;
+ };
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rgb10max3.dts b/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rgb10max3.dts
new file mode 100644
index 000000000000..e5a474e681dd
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rgb10max3.dts
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rk3566-powkiddy-rk2023.dtsi"
+
+/ {
+ model = "Powkiddy RGB10MAX3";
+ compatible = "powkiddy,rgb10max3", "rockchip,rk3566";
+};
+
+&bluetooth {
+ compatible = "realtek,rtl8723ds-bt";
+};
+
+&cru {
+ assigned-clocks = <&pmucru CLK_RTC_32K>, <&cru PLL_GPLL>,
+ <&pmucru PLL_PPLL>, <&cru PLL_VPLL>;
+ assigned-clock-rates = <32768>, <1200000000>,
+ <200000000>, <126400000>;
+};
+
+&dsi0 {
+ panel: panel@0 {
+ compatible = "powkiddy,rgb10max3-panel";
+ reg = <0>;
+ backlight = <&backlight>;
+ iovcc-supply = <&vcc3v3_lcd0_n>;
+ pinctrl-0 = <&lcd_rst>;
+ pinctrl-names = "default";
+ reset-gpios = <&gpio4 RK_PA0 GPIO_ACTIVE_LOW>;
+ rotation = <270>;
+ vcc-supply = <&vcc3v3_lcd0_n>;
+
+ port {
+ mipi_in_panel: endpoint {
+ remote-endpoint = <&mipi_out_panel>;
+ };
+ };
+ };
+};
+
+&green_led {
+ default-state = "on";
+ function = LED_FUNCTION_POWER;
+};
+
+&i2c0 {
+ vdd_cpu: regulator@40 {
+ compatible = "fcs,fan53555";
+ reg = <0x40>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <712500>;
+ regulator-max-microvolt = <1390000>;
+ regulator-name = "vdd_cpu";
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc_sys>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&leds {
+ amber_led: led-2 {
+ color = <LED_COLOR_ID_AMBER>;
+ function = LED_FUNCTION_CHARGING;
+ max-brightness = <255>;
+ pwms = <&pwm0 0 25000 0>;
+ };
+};
+
+&pwm0 {
+ pinctrl-0 = <&pwm0m1_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&red_led {
+ default-state = "off";
+ function = LED_FUNCTION_STATUS;
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rgb30.dts b/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rgb30.dts
index 0ac64f043b80..1f567a14ac84 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rgb30.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rgb30.dts
@@ -37,3 +37,21 @@
};
};
};
+
+&i2c0 {
+ vdd_cpu: regulator@1c {
+ compatible = "tcs,tcs4525";
+ reg = <0x1c>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <712500>;
+ regulator-max-microvolt = <1390000>;
+ regulator-name = "vdd_cpu";
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc_sys>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rk2023.dts b/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rk2023.dts
index ba32d0793dca..bc9933d9e262 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rk2023.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rk2023.dts
@@ -36,3 +36,21 @@
};
};
};
+
+&i2c0 {
+ vdd_cpu: regulator@1c {
+ compatible = "tcs,tcs4525";
+ reg = <0x1c>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <712500>;
+ regulator-max-microvolt = <1390000>;
+ regulator-name = "vdd_cpu";
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc_sys>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rk2023.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rk2023.dtsi
index 0fa8f06f94cd..3ab751a01cb2 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rk2023.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rk2023.dtsi
@@ -614,22 +614,6 @@
rockchip,sleep-filter-current-microamp = <100000>;
};
};
-
- vdd_cpu: regulator@1c {
- compatible = "tcs,tcs4525";
- reg = <0x1c>;
- fcs,suspend-voltage-selector = <1>;
- regulator-always-on;
- regulator-boot-on;
- regulator-min-microvolt = <712500>;
- regulator-max-microvolt = <1390000>;
- regulator-name = "vdd_cpu";
- regulator-ramp-delay = <2300>;
- vin-supply = <&vcc_sys>;
- regulator-state-mem {
- regulator-off-in-suspend;
- };
- };
};
&i2c5 {
@@ -805,7 +789,7 @@
uart-has-rtscts;
status = "okay";
- bluetooth {
+ bluetooth: bluetooth {
compatible = "realtek,rtl8821cs-bt", "realtek,rtl8723bs-bt";
device-wake-gpios = <&gpio4 4 GPIO_ACTIVE_HIGH>;
enable-gpios = <&gpio4 3 GPIO_ACTIVE_HIGH>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts b/arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts
index f9127ddfbb7d..7b5f3904ef61 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts
@@ -13,7 +13,7 @@
/ {
model = "Bananapi-R2 Pro (RK3568) DDR4 Board";
- compatible = "rockchip,rk3568-bpi-r2pro", "rockchip,rk3568";
+ compatible = "sinovoip,rk3568-bpi-r2pro", "rockchip,rk3568";
aliases {
ethernet0 = &gmac0;
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-qnap-ts433.dts b/arch/arm64/boot/dts/rockchip/rk3568-qnap-ts433.dts
new file mode 100644
index 000000000000..6a998166003c
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3568-qnap-ts433.dts
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
+ * Copyright (c) 2024 Uwe Kleine-König
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "rk3568.dtsi"
+
+/ {
+ model = "Qnap TS-433-4G NAS System 4-Bay";
+ compatible = "qnap,ts433", "rockchip,rk3568";
+};
+
+&gmac0 {
+ assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>;
+ assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>, <&cru CLK_MAC0_2TOP>;
+ assigned-clock-rates = <0>, <125000000>;
+ clock_in_out = "output";
+ phy-handle = <&rgmii_phy0>;
+ phy-mode = "rgmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac0_miim
+ &gmac0_tx_bus2
+ &gmac0_rx_bus2
+ &gmac0_rgmii_clk
+ &gmac0_rgmii_bus>;
+ rx_delay = <0x2f>;
+ tx_delay = <0x3c>;
+ status = "okay";
+};
+
+&i2c0 {
+ pmic@20 {
+ compatible = "rockchip,rk809";
+ reg = <0x20>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
+&i2c1 {
+ status = "okay";
+
+ rtc@51 {
+ compatible = "microcrystal,rv8263";
+ reg = <0x51>;
+ wakeup-source;
+ };
+};
+
+&mdio0 {
+ rgmii_phy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x0>;
+ };
+};
+
+&pcie30phy {
+ status = "okay";
+};
+
+&pcie3x1 {
+ /* The downstream dts has: rockchip,bifurcation, XXX: find out what this is about */
+ reset-gpios = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&sdhci {
+ bus-width = <8>;
+ max-frequency = <200000000>;
+ non-removable;
+ status = "okay";
+};
+
+/*
+ * Pins available on CN3 connector at TTL voltage level (3V3).
+ * ,_ _.
+ * |1234| 1=TX 2=VCC
+ * `----' 3=RX 4=GND
+ */
+&uart2 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index c19c0f1b3778..92f96ec01385 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -597,6 +597,7 @@
compatible = "rockchip,rk3568-vpu";
reg = <0x0 0xfdea0000 0x0 0x800>;
interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "vdpu";
clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
clock-names = "aclk", "hclk";
iommus = <&vdpu_mmu>;
@@ -1123,7 +1124,7 @@
dmas = <&dmac1 4>, <&dmac1 5>;
dma-names = "tx", "rx";
resets = <&cru SRST_M_I2S2_2CH>;
- reset-names = "m";
+ reset-names = "tx-m";
rockchip,grf = <&grf>;
pinctrl-names = "default";
pinctrl-0 = <&i2s2m0_sclktx
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-common.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-common.dtsi
new file mode 100644
index 000000000000..c0d4a15323e2
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-common.dtsi
@@ -0,0 +1,466 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Edgeble AI Technologies Pvt. Ltd.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ aliases {
+ mmc0 = &sdhci;
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ led_user: led-0 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_HEARTBEAT;
+ gpios = <&gpio0 RK_PC2 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_user_en>;
+ };
+ };
+
+ 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>;
+ };
+
+ 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>;
+ };
+
+ 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>;
+ };
+};
+
+&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>;
+};
+
+&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;
+ };
+ };
+};
+
+&pinctrl {
+ leds {
+ led_user_en: led_user_en {
+ rockchip,pins = <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&sdhci {
+ bus-width = <8>;
+ no-sdio;
+ no-sd;
+ non-removable;
+ mmc-hs400-1_8v;
+ mmc-hs400-enhanced-strobe;
+ status = "okay";
+};
+
+&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";
+ spi-max-frequency = <1000000>;
+ reg = <0x0>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PA7 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
+ <&rk806_dvs2_null>, <&rk806_dvs3_null>;
+
+ 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_pwrctrl2";
+ 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-name = "vdd_gpu_s0";
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+ regulator-enable-ramp-delay = <400>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 {
+ regulator-name = "vdd_cpu_lit_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_log_s0: dcdc-reg3 {
+ regulator-name = "vdd_log_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <750000>;
+ 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-name = "vdd_vdenc_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_ddr_s0: dcdc-reg5 {
+ regulator-name = "vdd_ddr_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <900000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ vdd2_ddr_s3: dcdc-reg6 {
+ regulator-name = "vdd2_ddr_s3";
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_2v0_pldo_s3: dcdc-reg7 {
+ regulator-name = "vdd_2v0_pldo_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <2000000>;
+ };
+ };
+
+ vcc_3v3_s3: dcdc-reg8 {
+ regulator-name = "vcc_3v3_s3";
+ 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>;
+ };
+ };
+
+ vddq_ddr_s0: dcdc-reg9 {
+ regulator-name = "vddq_ddr_s0";
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s3: dcdc-reg10 {
+ regulator-name = "vcc_1v8_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ avcc_1v8_s0: pldo-reg1 {
+ regulator-name = "avcc_1v8_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s0: pldo-reg2 {
+ regulator-name = "vcc_1v8_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ avdd_1v2_s0: pldo-reg3 {
+ regulator-name = "avdd_1v2_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_3v3_s0: pldo-reg4 {
+ regulator-name = "vcc_3v3_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vccio_sd_s0: pldo-reg5 {
+ regulator-name = "vccio_sd_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ pldo6_s3: pldo-reg6 {
+ regulator-name = "pldo6_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vdd_0v75_s3: nldo-reg1 {
+ regulator-name = "vdd_0v75_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_ddr_pll_s0: nldo-reg2 {
+ regulator-name = "vdd_ddr_pll_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ avdd_0v75_s0: nldo-reg3 {
+ regulator-name = "avdd_0v75_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v85_s0: nldo-reg4 {
+ regulator-name = "vdd_0v85_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v75_s0: nldo-reg5 {
+ regulator-name = "vdd_0v75_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-io.dts b/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-io.dts
index be6a4f4f90f6..46d5e21d4d27 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-io.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-io.dts
@@ -6,18 +6,10 @@
/dts-v1/;
#include "rk3588.dtsi"
#include "rk3588-edgeble-neu6a.dtsi"
+#include "rk3588-edgeble-neu6a-io.dtsi"
/ {
model = "Edgeble Neu6A IO Board";
compatible = "edgeble,neural-compute-module-6a-io",
"edgeble,neural-compute-module-6a", "rockchip,rk3588";
-
- chosen {
- stdout-path = "serial2:1500000n8";
- };
-};
-
-&uart2 {
- pinctrl-0 = <&uart2m0_xfer>;
- 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
new file mode 100644
index 000000000000..963e880ccc12
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-io.dtsi
@@ -0,0 +1,232 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Edgeble AI Technologies Pvt. Ltd.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+
+ vcc3v3_pcie2x1l0: vcc3v3-pcie2x1l0-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_pcie2x1l0";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <5000>;
+ vin-supply = <&vcc_3v3_s3>;
+ };
+
+ vcc3v3_pcie3x2: vcc3v3-pcie3x2-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio2 RK_PC4 GPIO_ACTIVE_HIGH>; /* PCIE_4G_PWEN */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie3x2_vcc3v3_en>;
+ regulator-name = "vcc3v3_pcie3x2";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <5000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc3v3_pcie3x4: vcc3v3-pcie3x4-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio2 RK_PC5 GPIO_ACTIVE_HIGH>; /* PCIE30x4_PWREN_H */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie3x4_vcc3v3_en>;
+ regulator-name = "vcc3v3_pcie3x4";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <5000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc5v0_host: vcc5v0-host-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio3 RK_PC7 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc5v0_host_en>;
+ regulator-name = "vcc5v0_host";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ vin-supply = <&vcc5v0_sys>;
+ };
+};
+
+&combphy0_ps {
+ status = "okay";
+};
+
+&combphy1_ps {
+ status = "okay";
+};
+
+&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;
+ };
+};
+
+/* ETH */
+&pcie2x1l0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie2_0_rst>;
+ reset-gpios = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>; /* PCIE20_1_PERST_L */
+ vpcie3v3-supply = <&vcc3v3_pcie2x1l0>;
+ status = "okay";
+};
+
+&pcie30phy {
+ status = "okay";
+};
+
+/* B-Key and E-Key */
+&pcie3x2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie3x2_rst>;
+ reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>; /* PCIE30X4_PERSTn_M1_L */
+ vpcie3v3-supply = <&vcc3v3_pcie3x2>;
+ status = "okay";
+};
+
+/* M-Key */
+&pcie3x4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie3x4_rst>;
+ reset-gpios = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>; /* PCIE30X2_PERSTn_M1_L */
+ vpcie3v3-supply = <&vcc3v3_pcie3x4>;
+ status = "okay";
+};
+
+&pinctrl {
+ pcie2 {
+ pcie2_0_rst: pcie2-0-rst {
+ rockchip,pins = <4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pcie3 {
+ pcie3x2_rst: pcie3x2-rst {
+ rockchip,pins = <4 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ pcie3x2_vcc3v3_en: pcie3x2-vcc3v3-en {
+ rockchip,pins = <2 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ pcie3x4_rst: pcie3x4-rst {
+ rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ pcie3x4_vcc3v3_en: pcie3x4-vcc3v3-en {
+ rockchip,pins = <2 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ hym8563 {
+ hym8563_int: hym8563-int {
+ rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ usb {
+ vcc5v0_host_en: vcc5v0-host-en {
+ rockchip,pins = <3 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+/* FAN */
+&pwm2 {
+ pinctrl-0 = <&pwm2m1_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&sata0 {
+ status = "okay";
+};
+
+&sdmmc {
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ disable-wp;
+ no-sdio;
+ no-mmc;
+ sd-uhs-sdr104;
+ vmmc-supply = <&vcc_3v3_s3>;
+ vqmmc-supply = <&vccio_sd_s0>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-0 = <&uart2m0_xfer>;
+ status = "okay";
+};
+
+/* RS232 */
+&uart6 {
+ pinctrl-0 = <&uart6m0_xfer>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+/* RS485 */
+&uart7 {
+ pinctrl-0 = <&uart7m2_xfer>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&u2phy2 {
+ status = "okay";
+};
+
+&u2phy2_host {
+ /* connected to USB hub, which is powered by vcc5v0_sys */
+ phy-supply = <&vcc5v0_sys>;
+ 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";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-wifi.dtso b/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-wifi.dtso
new file mode 100644
index 000000000000..e9a3855e8752
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-wifi.dtso
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd.
+ *
+ * DT-overlay for Edgeble On-SoM WiFi6/BT M.2 1216 modules,
+ * - AW-XM548NF
+ * - Intel 8260D2W
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+
+&{/} {
+ vcc3v3_pcie2x1l1: vcc3v3-pcie2x1l1-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio0 RK_PC4 GPIO_ACTIVE_HIGH>; /* WIFI_3V3_EN */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie2_1_vcc3v3_en>;
+ regulator-name = "vcc3v3_pcie2x1l1";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <50000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+};
+
+&combphy2_psu {
+ status = "okay";
+};
+
+/* WiFi6 */
+&pcie2x1l1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie2_1_rst>;
+ reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>; /* PCIE20_2_WIFI_PERSTn */
+ vpcie3v3-supply = <&vcc3v3_pcie2x1l1>;
+ status = "okay";
+};
+
+&pinctrl {
+ pcie2 {
+ pcie2_1_rst: pcie2-1-rst {
+ rockchip,pins = <4 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ pcie2_1_vcc3v3_en: pcie2-1-vcc-en {
+ rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a.dtsi
index 727580aaa105..4c76a00b41eb 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a.dtsi
@@ -3,29 +3,8 @@
* Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd.
*/
+#include "rk3588-edgeble-neu6a-common.dtsi"
+
/ {
compatible = "edgeble,neural-compute-module-6a", "rockchip,rk3588";
-
- aliases {
- mmc0 = &sdhci;
- };
-
- 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>;
- };
-};
-
-&sdhci {
- bus-width = <8>;
- no-sdio;
- no-sd;
- non-removable;
- mmc-hs400-1_8v;
- mmc-hs400-enhanced-strobe;
- status = "okay";
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6b-io.dts b/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6b-io.dts
index 070baeb63431..0d6f1be69ac8 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6b-io.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6b-io.dts
@@ -6,84 +6,10 @@
/dts-v1/;
#include "rk3588j.dtsi"
#include "rk3588-edgeble-neu6b.dtsi"
+#include "rk3588-edgeble-neu6a-io.dtsi"
/ {
model = "Edgeble Neu6B IO Board";
compatible = "edgeble,neural-compute-module-6a-io",
"edgeble,neural-compute-module-6b", "rockchip,rk3588";
-
- chosen {
- stdout-path = "serial2:1500000n8";
- };
-};
-
-&combphy0_ps {
- status = "okay";
-};
-
-&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;
- };
-};
-
-&pinctrl {
- hym8563 {
- hym8563_int: hym8563-int {
- rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
- };
- };
-};
-
-/* FAN */
-&pwm2 {
- pinctrl-0 = <&pwm2m1_pins>;
- pinctrl-names = "default";
- status = "okay";
-};
-
-&sata0 {
- status = "okay";
-};
-
-&sdmmc {
- bus-width = <4>;
- cap-mmc-highspeed;
- cap-sd-highspeed;
- disable-wp;
- no-sdio;
- no-mmc;
- sd-uhs-sdr104;
- vmmc-supply = <&vcc_3v3_s3>;
- vqmmc-supply = <&vccio_sd_s0>;
- status = "okay";
-};
-
-&uart2 {
- pinctrl-0 = <&uart2m0_xfer>;
- status = "okay";
-};
-
-/* RS232 */
-&uart6 {
- pinctrl-0 = <&uart6m0_xfer>;
- pinctrl-names = "default";
- status = "okay";
-};
-
-/* RS485 */
-&uart7 {
- pinctrl-0 = <&uart7m2_xfer>;
- pinctrl-names = "default";
- status = "okay";
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6b.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6b.dtsi
index 017559bba37f..c4634bc09fb4 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6b.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6b.dtsi
@@ -3,387 +3,8 @@
* Copyright (c) 2023 Edgeble AI Technologies Pvt. Ltd.
*/
+#include "rk3588-edgeble-neu6a-common.dtsi"
+
/ {
compatible = "edgeble,neural-compute-module-6b", "rockchip,rk3588";
-
- aliases {
- mmc0 = &sdhci;
- };
-
- 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>;
- };
-
- 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>;
- };
-
- 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>;
- };
-};
-
-&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>;
-};
-
-&sdhci {
- bus-width = <8>;
- no-sdio;
- no-sd;
- non-removable;
- mmc-hs400-1_8v;
- mmc-hs400-enhanced-strobe;
- status = "okay";
-};
-
-&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";
- spi-max-frequency = <1000000>;
- reg = <0x0>;
- interrupt-parent = <&gpio0>;
- interrupts = <RK_PA7 IRQ_TYPE_LEVEL_LOW>;
- pinctrl-names = "default";
- pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
- <&rk806_dvs2_null>, <&rk806_dvs3_null>;
-
- 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_pwrctrl2";
- 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-name = "vdd_gpu_s0";
- regulator-boot-on;
- regulator-min-microvolt = <550000>;
- regulator-max-microvolt = <950000>;
- regulator-ramp-delay = <12500>;
- regulator-enable-ramp-delay = <400>;
-
- regulator-state-mem {
- regulator-off-in-suspend;
- };
- };
-
- vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 {
- regulator-name = "vdd_cpu_lit_s0";
- regulator-always-on;
- regulator-boot-on;
- regulator-min-microvolt = <550000>;
- regulator-max-microvolt = <950000>;
- regulator-ramp-delay = <12500>;
-
- regulator-state-mem {
- regulator-off-in-suspend;
- };
- };
-
- vdd_log_s0: dcdc-reg3 {
- regulator-name = "vdd_log_s0";
- regulator-always-on;
- regulator-boot-on;
- regulator-min-microvolt = <675000>;
- regulator-max-microvolt = <750000>;
- 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-name = "vdd_vdenc_s0";
- regulator-always-on;
- regulator-boot-on;
- regulator-min-microvolt = <550000>;
- regulator-max-microvolt = <950000>;
- regulator-init-microvolt = <750000>;
- regulator-ramp-delay = <12500>;
-
- regulator-state-mem {
- regulator-off-in-suspend;
- };
- };
-
- vdd_ddr_s0: dcdc-reg5 {
- regulator-name = "vdd_ddr_s0";
- regulator-always-on;
- regulator-boot-on;
- regulator-min-microvolt = <675000>;
- regulator-max-microvolt = <900000>;
- regulator-ramp-delay = <12500>;
-
- regulator-state-mem {
- regulator-off-in-suspend;
- regulator-suspend-microvolt = <850000>;
- };
- };
-
- vdd2_ddr_s3: dcdc-reg6 {
- regulator-name = "vdd2_ddr_s3";
- regulator-always-on;
- regulator-boot-on;
-
- regulator-state-mem {
- regulator-on-in-suspend;
- };
- };
-
- vcc_2v0_pldo_s3: dcdc-reg7 {
- regulator-name = "vdd_2v0_pldo_s3";
- regulator-always-on;
- regulator-boot-on;
- regulator-min-microvolt = <2000000>;
- regulator-max-microvolt = <2000000>;
- regulator-ramp-delay = <12500>;
-
- regulator-state-mem {
- regulator-on-in-suspend;
- regulator-suspend-microvolt = <2000000>;
- };
- };
-
- vcc_3v3_s3: dcdc-reg8 {
- regulator-name = "vcc_3v3_s3";
- 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>;
- };
- };
-
- vddq_ddr_s0: dcdc-reg9 {
- regulator-name = "vddq_ddr_s0";
- regulator-always-on;
- regulator-boot-on;
-
- regulator-state-mem {
- regulator-off-in-suspend;
- };
- };
-
- vcc_1v8_s3: dcdc-reg10 {
- regulator-name = "vcc_1v8_s3";
- regulator-always-on;
- regulator-boot-on;
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
-
- regulator-state-mem {
- regulator-on-in-suspend;
- regulator-suspend-microvolt = <1800000>;
- };
- };
-
- avcc_1v8_s0: pldo-reg1 {
- regulator-name = "avcc_1v8_s0";
- regulator-always-on;
- regulator-boot-on;
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
-
- regulator-state-mem {
- regulator-off-in-suspend;
- };
- };
-
- vcc_1v8_s0: pldo-reg2 {
- regulator-name = "vcc_1v8_s0";
- regulator-always-on;
- regulator-boot-on;
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
-
- regulator-state-mem {
- regulator-off-in-suspend;
- regulator-suspend-microvolt = <1800000>;
- };
- };
-
- avdd_1v2_s0: pldo-reg3 {
- regulator-name = "avdd_1v2_s0";
- regulator-always-on;
- regulator-boot-on;
- regulator-min-microvolt = <1200000>;
- regulator-max-microvolt = <1200000>;
-
- regulator-state-mem {
- regulator-off-in-suspend;
- };
- };
-
- vcc_3v3_s0: pldo-reg4 {
- regulator-name = "vcc_3v3_s0";
- regulator-always-on;
- regulator-boot-on;
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- regulator-ramp-delay = <12500>;
-
- regulator-state-mem {
- regulator-off-in-suspend;
- };
- };
-
- vccio_sd_s0: pldo-reg5 {
- regulator-name = "vccio_sd_s0";
- regulator-always-on;
- regulator-boot-on;
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <3300000>;
- regulator-ramp-delay = <12500>;
-
- regulator-state-mem {
- regulator-off-in-suspend;
- };
- };
-
- pldo6_s3: pldo-reg6 {
- regulator-name = "pldo6_s3";
- regulator-always-on;
- regulator-boot-on;
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
-
- regulator-state-mem {
- regulator-on-in-suspend;
- regulator-suspend-microvolt = <1800000>;
- };
- };
-
- vdd_0v75_s3: nldo-reg1 {
- regulator-name = "vdd_0v75_s3";
- regulator-always-on;
- regulator-boot-on;
- regulator-min-microvolt = <750000>;
- regulator-max-microvolt = <750000>;
-
- regulator-state-mem {
- regulator-on-in-suspend;
- regulator-suspend-microvolt = <750000>;
- };
- };
-
- vdd_ddr_pll_s0: nldo-reg2 {
- regulator-name = "vdd_ddr_pll_s0";
- regulator-always-on;
- regulator-boot-on;
- regulator-min-microvolt = <850000>;
- regulator-max-microvolt = <850000>;
-
- regulator-state-mem {
- regulator-off-in-suspend;
- regulator-suspend-microvolt = <850000>;
- };
- };
-
- avdd_0v75_s0: nldo-reg3 {
- regulator-name = "avdd_0v75_s0";
- regulator-always-on;
- regulator-boot-on;
- regulator-min-microvolt = <750000>;
- regulator-max-microvolt = <750000>;
-
- regulator-state-mem {
- regulator-off-in-suspend;
- };
- };
-
- vdd_0v85_s0: nldo-reg4 {
- regulator-name = "vdd_0v85_s0";
- regulator-always-on;
- regulator-boot-on;
- regulator-min-microvolt = <850000>;
- regulator-max-microvolt = <850000>;
-
- regulator-state-mem {
- regulator-off-in-suspend;
- };
- };
-
- vdd_0v75_s0: nldo-reg5 {
- regulator-name = "vdd_0v75_s0";
- regulator-always-on;
- regulator-boot-on;
- regulator-min-microvolt = <750000>;
- regulator-max-microvolt = <750000>;
-
- regulator-state-mem {
- regulator-off-in-suspend;
- };
- };
- };
- };
};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
index 997b516c2533..ad8e36a339dc 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
@@ -159,6 +159,29 @@
regulator-max-microvolt = <3300000>;
vin-supply = <&vcc5v0_sys>;
};
+
+ vcc3v3_sd_s0: vcc3v3-sd-s0-regulator {
+ compatible = "regulator-fixed";
+ enable-active-low;
+ gpio = <&gpio4 RK_PA5 GPIO_ACTIVE_LOW>;
+ regulator-boot-on;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "vcc3v3_sd_s0";
+ vin-supply = <&vcc_3v3_s3>;
+ };
+
+ vdd_4g_3v3: vdd-4g-3v3-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio4 RK_PC6 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pin_4g_lte_pwren>;
+ regulator-name = "vdd_4g_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
};
&combphy0_ps {
@@ -504,6 +527,10 @@
};
usb {
+ pin_4g_lte_pwren: 4g-lte-pwren {
+ rockchip,pins = <4 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
typec5v_pwren: typec5v-pwren {
rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
};
@@ -539,11 +566,12 @@
bus-width = <4>;
cap-mmc-highspeed;
cap-sd-highspeed;
+ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
disable-wp;
no-mmc;
no-sdio;
sd-uhs-sdr104;
- vmmc-supply = <&vcc_3v3_s3>;
+ vmmc-supply = <&vcc3v3_sd_s0>;
vqmmc-supply = <&vccio_sd_s0>;
status = "okay";
};
@@ -884,6 +912,7 @@
};
&u2phy2_host {
+ phy-supply = <&vdd_4g_3v3>;
status = "okay";
};
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 3e660ff6cd5f..1b606ea5b6cf 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
@@ -444,7 +444,6 @@
&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 87a0abf95f7d..67414d72e2b6 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts
@@ -429,7 +429,6 @@
&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-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
index a0e303c3a1dc..1fe8b2a0ed75 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
@@ -58,6 +58,13 @@
#cooling-cells = <2>;
};
+ rfkill {
+ compatible = "rfkill-gpio";
+ label = "rfkill-pcie-wlan";
+ radio-type = "wlan";
+ shutdown-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
+ };
+
vcc3v3_pcie2x1l0: vcc3v3-pcie2x1l0-regulator {
compatible = "regulator-fixed";
enable-active-high;
@@ -371,7 +378,6 @@
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>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dts b/arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dts
new file mode 100644
index 000000000000..d672198c6b64
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dts
@@ -0,0 +1,266 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Theobroma Systems Design und Consulting GmbH
+ */
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include "rk3588-tiger.dtsi"
+
+/ {
+ model = "Theobroma Systems RK3588-Q7 SoM on Haikou devkit";
+ compatible = "tsd,rk3588-tiger-haikou", "tsd,rk3588-tiger", "rockchip,rk3588";
+
+ aliases {
+ ethernet0 = &gmac0;
+ mmc1 = &sdmmc;
+ };
+
+ chosen {
+ stdout-path = "serial2:115200n8";
+ };
+
+ dc_12v: dc-12v-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "dc_12v";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&haikou_keys_pin>;
+
+ button-batlow-n {
+ label = "BATLOW#";
+ linux,code = <KEY_BATTERY>;
+ gpios = <&gpio3 RK_PB5 GPIO_ACTIVE_LOW>;
+ };
+
+ button-slp-btn-n {
+ label = "SLP_BTN#";
+ linux,code = <KEY_SLEEP>;
+ gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_LOW>;
+ };
+
+ button-wake-n {
+ label = "WAKE#";
+ linux,code = <KEY_WAKEUP>;
+ gpios = <&gpio3 RK_PC6 GPIO_ACTIVE_LOW>;
+ wakeup-source;
+ };
+
+ switch-lid-btn-n {
+ label = "LID_BTN#";
+ linux,code = <SW_LID>;
+ linux,input-type = <EV_SW>;
+ gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ i2s3-sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,name = "Haikou,I2S-codec";
+ simple-audio-card,mclk-fs = <512>;
+ simple-audio-card,frame-master = <&sgtl5000_codec>;
+ simple-audio-card,bitclock-master = <&sgtl5000_codec>;
+
+ sgtl5000_codec: simple-audio-card,codec {
+ sound-dai = <&sgtl5000>;
+ };
+
+ simple-audio-card,cpu {
+ sound-dai = <&i2s3_2ch>;
+ };
+ };
+
+ sgtl5000_clk: sgtl5000-oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24576000>;
+ };
+
+ vcc3v3_baseboard: vcc3v3-baseboard-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_baseboard";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&dc_12v>;
+ };
+
+ vcc3v3_low_noise: vcc3v3-low-noise-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_low_noise";
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc5v0_usb>;
+ };
+
+ vcc5v0_baseboard: vcc5v0-baseboard-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_baseboard";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&dc_12v>;
+ };
+
+ vcc5v0_usb: vcc5v0-usb-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_usb";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&dc_12v>;
+ };
+
+ vddd_audio_1v6: vddd-audio-1v6-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vddd_audio_1v6";
+ regulator-boot-on;
+ regulator-min-microvolt = <1600000>;
+ regulator-max-microvolt = <1600000>;
+ vin-supply = <&vcc5v0_usb>;
+ };
+};
+
+&combphy2_psu {
+ status = "okay";
+};
+
+&gmac0 {
+ status = "okay";
+};
+
+&i2c1 {
+ status = "okay";
+
+ eeprom@50 {
+ reg = <0x50>;
+ compatible = "atmel,24c01";
+ pagesize = <8>;
+ size = <128>;
+ vcc-supply = <&vcc3v3_baseboard>;
+ };
+};
+
+&i2c5 {
+ clock-frequency = <400000>;
+ status = "okay";
+
+ sgtl5000: codec@a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ clocks = <&sgtl5000_clk>;
+ #sound-dai-cells = <0>;
+ VDDA-supply = <&vcc3v3_low_noise>;
+ VDDIO-supply = <&vcc3v3_baseboard>;
+ VDDD-supply = <&vddd_audio_1v6>;
+ };
+};
+
+&i2c8 {
+ status = "okay";
+};
+
+&i2s3_2ch {
+ status = "okay";
+};
+
+&pcie30phy {
+ status = "okay";
+};
+
+&pcie3x4 {
+ vpcie3v3-supply = <&vcc3v3_baseboard>;
+ status = "okay";
+};
+
+&pinctrl {
+ haikou {
+ haikou_keys_pin: haikou-keys-pin {
+ rockchip,pins =
+ /* BATLOW# */
+ <3 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>,
+ /* SLP_BTN# */
+ <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_up>,
+ /* WAKE# */
+ <3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>,
+ /* LID_BTN */
+ <3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+};
+
+&sdmmc {
+ /* while the same pin, sdmmc_det does not detect card changes */
+ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
+ disable-wp;
+ pinctrl-0 = <&sdmmc_bus4 &sdmmc_cmd &sdmmc_clk>;
+ sd-uhs-sdr12;
+ sd-uhs-sdr25;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+ vmmc-supply = <&vcc3v3_baseboard>;
+ status = "okay";
+};
+
+&u2phy2 {
+ status = "okay";
+};
+
+&u2phy2_host {
+ status = "okay";
+};
+
+&u2phy3 {
+ status = "okay";
+};
+
+&u2phy3_host {
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-0 = <&uart2m2_xfer>;
+ status = "okay";
+};
+
+&uart5 {
+ rts-gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+/* host0 on Q7_USB_P2, lower usb3 port */
+&usb_host0_ehci {
+ status = "okay";
+};
+
+/* host0 on Q7_USB_P2, lower usb3 port */
+&usb_host0_ohci {
+ status = "okay";
+};
+
+/* host1 on Q7_USB_P3, usb2 port */
+&usb_host1_ehci {
+ status = "okay";
+};
+
+/* host1 on Q7_USB_P3, usb2 port */
+&usb_host1_ohci {
+ status = "okay";
+};
+
+/* host2 on Q7_USB_P2, lower 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
new file mode 100644
index 000000000000..1eb2543a5fde
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-tiger.dtsi
@@ -0,0 +1,690 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Theobroma Systems Design und Consulting GmbH
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rk3588.dtsi"
+
+/ {
+ compatible = "tsd,rk3588-tiger", "rockchip,rk3588";
+
+ aliases {
+ mmc0 = &sdhci;
+ rtc0 = &rtc_twi;
+ };
+
+ emmc_pwrseq: emmc-pwrseq {
+ compatible = "mmc-pwrseq-emmc";
+ pinctrl-0 = <&emmc_reset>;
+ pinctrl-names = "default";
+ reset-gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_HIGH>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&module_led_pin>;
+
+ /* Named LED1 on the board */
+ led-1 {
+ gpios = <&gpio1 RK_PD3 GPIO_ACTIVE_HIGH>;
+ function = LED_FUNCTION_HEARTBEAT;
+ linux,default-trigger = "heartbeat";
+ color = <LED_COLOR_ID_AMBER>;
+ };
+ };
+
+ /*
+ * 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 = <1000000000>;
+ };
+
+ pcie_refclk: pcie-refclk-clock {
+ compatible = "gpio-gate-clock";
+ clocks = <&pcie_refclk_gen>;
+ #clock-cells = <0>;
+ enable-gpios = <&gpio4 RK_PB4 GPIO_ACTIVE_HIGH>; /* PCIE30X4_CLKREQN_M1_L */
+ };
+
+ 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>;
+ };
+
+ vcc_1v2_s3: vcc-1v2-s3-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_1v2_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ 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 = <&vcc5v0_baseboard>;
+ };
+};
+
+&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>;
+};
+
+&gmac0 {
+ clock_in_out = "output";
+ phy-handle = <&rgmii_phy>;
+ phy-mode = "rgmii";
+ phy-supply = <&vcc_1v2_s3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac0_miim
+ &gmac0_rx_bus2
+ &gmac0_tx_bus2
+ &gmac0_rgmii_clk
+ &gmac0_rgmii_bus
+ &eth0_pins
+ &eth_reset>;
+ tx_delay = <0x10>;
+ rx_delay = <0x10>;
+ snps,reset-gpio = <&gpio4 RK_PC3 GPIO_ACTIVE_LOW>;
+ snps,reset-active-low;
+ snps,reset-delays-us = <0 10000 100000>;
+};
+
+&i2c1 {
+ pinctrl-0 = <&i2c1m0_xfer>;
+};
+
+&i2c1m0_xfer {
+ rockchip,pins =
+ /* i2c1_scl_m0 */
+ <0 RK_PB5 9 &pcfg_pull_none_drv_level_0>,
+ /* i2c1_sda_m0 */
+ <0 RK_PB6 9 &pcfg_pull_none_drv_level_0>;
+};
+
+&i2c2 {
+ pinctrl-0 = <&i2c2m3_xfer>;
+ status = "okay";
+};
+
+&i2c2m3_xfer {
+ rockchip,pins =
+ /* i2c2_scl_m3 */
+ <1 RK_PC5 9 &pcfg_pull_none_drv_level_0>,
+ /* i2c2_sda_m3 */
+ <1 RK_PC4 9 &pcfg_pull_none_drv_level_0>;
+};
+
+&i2c3 {
+ pinctrl-0 = <&i2c3m0_xfer>;
+};
+
+&i2c4 {
+ pinctrl-0 = <&i2c4m4_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;
+ };
+ };
+};
+
+&i2c5 {
+ pinctrl-0 = <&i2c5m1_xfer>;
+};
+
+&i2c5m1_xfer {
+ rockchip,pins =
+ /* i2c5_scl_m1 */
+ <4 RK_PB6 9 &pcfg_pull_none_drv_level_0>,
+ /* i2c5_sda_m1 */
+ <4 RK_PB7 9 &pcfg_pull_none_drv_level_0>;
+};
+
+&i2c6 {
+ /*
+ * Mule-ATtiny can handle up to Fast mode Plus (1MHz) on I2C bus,
+ * but SOC can handle only up to (400kHz).
+ */
+ clock-frequency = <400000>;
+ status = "okay";
+
+ fan@18 {
+ compatible = "ti,amc6821";
+ reg = <0x18>;
+ };
+
+ rtc_twi: rtc@6f {
+ compatible = "isil,isl1208";
+ reg = <0x6f>;
+ };
+};
+
+&i2c6m0_xfer {
+ rockchip,pins =
+ /* i2c6_scl_m0 */
+ <0 RK_PD0 9 &pcfg_pull_none_drv_level_0>,
+ /* i2c6_sda_m0 */
+ <0 RK_PC7 9 &pcfg_pull_none_drv_level_0>;
+};
+
+&i2c7 {
+ 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;
+ };
+ };
+};
+
+&i2c7m0_xfer {
+ rockchip,pins =
+ /* i2c7_scl_m0 */
+ <1 RK_PD0 9 &pcfg_pull_none_drv_level_0>,
+ /* i2c7_sda_m0 */
+ <1 RK_PD1 9 &pcfg_pull_none_drv_level_0>;
+};
+
+&i2c8 {
+ pinctrl-0 = <&i2c8m2_xfer>;
+};
+
+&mdio0 {
+ rgmii_phy: ethernet-phy@6 {
+ /* KSZ9031 or KSZ9131 */
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x6>;
+ clocks = <&cru REFCLKO25M_ETH0_OUT>;
+ };
+};
+
+&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";
+ reset-gpios = <&gpio3 RK_PB6 GPIO_ACTIVE_HIGH>;
+};
+
+&pinctrl {
+ emmc {
+ emmc_reset: emmc-reset {
+ rockchip,pins = <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ ethernet {
+ eth_reset: eth-reset {
+ rockchip,pins = <4 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ leds {
+ module_led_pin: module-led-pin {
+ rockchip,pins = <1 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&saradc {
+ vref-supply = <&vcc_1v8_s0>;
+ status = "okay";
+};
+
+&sdhci {
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+ mmc-hs400-1_8v;
+ mmc-hs400-enhanced-strobe;
+ mmc-pwrseq = <&emmc_pwrseq>;
+ no-sdio;
+ no-sd;
+ non-removable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_bus8 &emmc_cmd &emmc_clk &emmc_data_strobe>;
+ supports-cqe;
+ vmmc-supply = <&vcc_3v3_s3>;
+ vqmmc-supply = <&vcc_1v8_s3>;
+ status = "okay";
+};
+
+&sdmmc {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ max-frequency = <150000000>;
+ vqmmc-supply = <&vccio_sd_s0>;
+};
+
+&spi0 {
+ pinctrl-0 = <&spi0m1_cs0 &spi0m1_cs1 &spi0m3_pins>;
+};
+
+&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>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ 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_pwrctrl2";
+ 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: 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: dcdc-reg2 {
+ regulator-name = "vdd_cpu_lit_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_log_s0: dcdc-reg3 {
+ regulator-name = "vdd_log_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <750000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_vdenc_s0: dcdc-reg4 {
+ regulator-name = "vdd_vdenc_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_ddr_s0: dcdc-reg5 {
+ regulator-name = "vdd_ddr_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <900000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ vdd2_ddr_s3: dcdc-reg6 {
+ regulator-name = "vdd2_ddr_s3";
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_2v0_pldo_s3: dcdc-reg7 {
+ regulator-name = "vcc_2v0_pldo_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <2000000>;
+ };
+ };
+
+ vcc_3v3_s3: dcdc-reg8 {
+ regulator-name = "vcc_3v3_s3";
+ 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>;
+ };
+ };
+
+ vddq_ddr_s0: dcdc-reg9 {
+ regulator-name = "vddq_ddr_s0";
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s3: dcdc-reg10 {
+ regulator-name = "vcc_1v8_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vcca_1v8_s0: pldo-reg1 {
+ regulator-name = "vcca_1v8_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s0: pldo-reg2 {
+ regulator-name = "vcc_1v8_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vdda_1v2_s0: pldo-reg3 {
+ regulator-name = "vdda_1v2_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcca_3v3_s0: pldo-reg4 {
+ regulator-name = "vcca_3v3_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vccio_sd_s0: pldo-reg5 {
+ regulator-name = "vccio_sd_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ pldo6_s3: pldo-reg6 {
+ regulator-name = "pldo6_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vdd_0v75_s3: nldo-reg1 {
+ regulator-name = "vdd_0v75_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdda_ddr_pll_s0: nldo-reg2 {
+ regulator-name = "vdda_ddr_pll_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ vdda_0v75_s0: nldo-reg3 {
+ regulator-name = "vdda_0v75_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdda_0v85_s0: nldo-reg4 {
+ regulator-name = "vdda_0v85_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v75_s0: nldo-reg5 {
+ regulator-name = "vdd_0v75_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+};
+
+&tsadc {
+ status = "okay";
+};
+
+/* Mule-ATtiny UPDI */
+&uart4 {
+ pinctrl-0 = <&uart4m2_xfer>;
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts b/arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts
new file mode 100644
index 000000000000..9090c5c99f2a
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts
@@ -0,0 +1,688 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2024 Rockchip Electronics Co., Ltd.
+ *
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rk3588.dtsi"
+
+/ {
+ model = "Rockchip Toybrick TB-RK3588X Board";
+ compatible = "rockchip,rk3588-toybrick-x0", "rockchip,rk3588";
+
+ aliases {
+ mmc0 = &sdhci;
+ };
+
+ 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-vol-up {
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+ press-threshold-microvolt = <17000>;
+ };
+
+ button-vol-down {
+ label = "Volume Down";
+ linux,code = <KEY_VOLUMEDOWN>;
+ press-threshold-microvolt = <417000>;
+ };
+
+ button-menu {
+ label = "Menu";
+ linux,code = <KEY_MENU>;
+ press-threshold-microvolt = <890000>;
+ };
+
+ button-escape {
+ label = "Escape";
+ linux,code = <KEY_ESC>;
+ press-threshold-microvolt = <1235000>;
+ };
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ power-supply = <&vcc12v_dcin>;
+ pwms = <&pwm2 0 25000 0>;
+ };
+
+ 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>;
+ };
+
+ 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>;
+ };
+
+ vcc5v0_host: vcc5v0-host-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc5v0_host_en>;
+ regulator-name = "vcc5v0_host";
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_usb>;
+ };
+
+ 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>;
+ };
+
+ vcc5v0_usbdcin: vcc5v0-usbdcin-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_usbdcin";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc12v_dcin>;
+ };
+
+ vcc5v0_usb: vcc5v0-usb-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_usb";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_usbdcin>;
+ };
+
+ 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";
+};
+
+&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>;
+};
+
+&gmac0 {
+ clock_in_out = "output";
+ phy-handle = <&rgmii_phy>;
+ phy-mode = "rgmii-rxid";
+ pinctrl-0 = <&gmac0_miim
+ &gmac0_tx_bus2
+ &gmac0_rx_bus2
+ &gmac0_rgmii_clk
+ &gmac0_rgmii_bus>;
+ pinctrl-names = "default";
+ rx_delay = <0x00>;
+ tx_delay = <0x43>;
+ 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";
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PD4 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&hym8563_int>;
+ wakeup-source;
+ };
+};
+
+&mdio0 {
+ rgmii_phy: ethernet-phy@1 {
+ /* RTL8211F */
+ compatible = "ethernet-phy-id001c.c916";
+ reg = <0x1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&rtl8211f_rst>;
+ reset-assert-us = <20000>;
+ reset-deassert-us = <100000>;
+ reset-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&pinctrl {
+ rtl8211f {
+ rtl8211f_rst: rtl8211f-rst {
+ rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ };
+
+ hym8563 {
+ hym8563_int: hym8563-int {
+ rockchip,pins = <0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ usb {
+ vcc5v0_host_en: vcc5v0-host-en {
+ rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&pwm2 {
+ status = "okay";
+};
+
+&saradc {
+ vref-supply = <&vcc_1v8_s0>;
+ status = "okay";
+};
+
+&sdhci {
+ bus-width = <8>;
+ mmc-hs400-1_8v;
+ mmc-hs400-enhanced-strobe;
+ no-sdio;
+ no-sd;
+ non-removable;
+ 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";
+ 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-name = "vdd_gpu_s0";
+ regulator-boot-on;
+ regulator-enable-ramp-delay = <400>;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 {
+ regulator-name = "vdd_cpu_lit_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_log_s0: dcdc-reg3 {
+ regulator-name = "vdd_log_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <750000>;
+ 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-name = "vdd_vdenc_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-init-microvolt = <750000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_ddr_s0: dcdc-reg5 {
+ regulator-name = "vdd_ddr_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <900000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ vdd2_ddr_s3: dcdc-reg6 {
+ regulator-name = "vdd2_ddr_s3";
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_2v0_pldo_s3: dcdc-reg7 {
+ regulator-name = "vdd_2v0_pldo_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <2000000>;
+ };
+ };
+
+ vcc_3v3_s3: dcdc-reg8 {
+ regulator-name = "vcc_3v3_s3";
+ 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>;
+ };
+ };
+
+ vddq_ddr_s0: dcdc-reg9 {
+ regulator-name = "vddq_ddr_s0";
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s3: dcdc-reg10 {
+ regulator-name = "vcc_1v8_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ avcc_1v8_s0: pldo-reg1 {
+ regulator-name = "avcc_1v8_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s0: pldo-reg2 {
+ regulator-name = "vcc_1v8_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ avdd_1v2_s0: pldo-reg3 {
+ regulator-name = "avdd_1v2_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_3v3_s0: pldo-reg4 {
+ regulator-name = "vcc_3v3_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vccio_sd_s0: pldo-reg5 {
+ regulator-name = "vccio_sd_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ pldo6_s3: pldo-reg6 {
+ regulator-name = "pldo6_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vdd_0v75_s3: nldo-reg1 {
+ regulator-name = "vdd_0v75_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_ddr_pll_s0: nldo-reg2 {
+ regulator-name = "vdd_ddr_pll_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ avdd_0v75_s0: nldo-reg3 {
+ regulator-name = "avdd_0v75_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <837500>;
+ regulator-max-microvolt = <837500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v85_s0: nldo-reg4 {
+ regulator-name = "vdd_0v85_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v75_s0: nldo-reg5 {
+ regulator-name = "vdd_0v75_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+};
+
+&u2phy2 {
+ status = "okay";
+};
+
+&u2phy2_host {
+ phy-supply = <&vcc5v0_host>;
+ status = "okay";
+};
+
+&u2phy3 {
+ status = "okay";
+};
+
+&u2phy3_host {
+ phy-supply = <&vcc5v0_host>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-0 = <&uart2m0_xfer>;
+ 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/rk3588s-indiedroid-nova.dts b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
index 3c2278886851..ce8119cbb824 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
@@ -141,6 +141,10 @@
status = "okay";
};
+&combphy2_psu {
+ status = "okay";
+};
+
&cpu_l0 {
cpu-supply = <&vdd_cpu_lit_s0>;
};
@@ -842,3 +846,7 @@
&usb_host1_ohci {
status = "okay";
};
+
+&usb_host2_xhci {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6c.dts b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6c.dts
new file mode 100644
index 000000000000..497bbb57071f
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6c.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include "rk3588s-nanopi-r6s.dts"
+
+/ {
+ model = "FriendlyElec NanoPi R6C";
+ compatible = "friendlyarm,nanopi-r6c", "rockchip,rk3588s";
+};
+
+&lan2_led {
+ label = "user_led";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6s.dts b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6s.dts
new file mode 100644
index 000000000000..4fa644ae510c
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6s.dts
@@ -0,0 +1,764 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include "rk3588s.dtsi"
+
+/ {
+ model = "FriendlyElec NanoPi R6S";
+ compatible = "friendlyarm,nanopi-r6s", "rockchip,rk3588s";
+
+ aliases {
+ ethernet0 = &gmac1;
+ mmc0 = &sdmmc;
+ mmc1 = &sdhci;
+ };
+
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+
+ adc-keys {
+ compatible = "adc-keys";
+ io-channels = <&saradc 0>;
+ io-channel-names = "buttons";
+ keyup-threshold-microvolt = <1800000>;
+ poll-interval = <100>;
+
+ button-maskrom {
+ label = "Maskrom";
+ linux,code = <KEY_VENDOR>;
+ press-threshold-microvolt = <1800>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&key1_pin>;
+
+ button-user {
+ label = "User";
+ linux,code = <BTN_1>;
+ gpios = <&gpio1 RK_PC0 GPIO_ACTIVE_LOW>;
+ debounce-interval = <50>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ sys_led: led-0 {
+ label = "sys_led";
+ gpios = <&gpio1 RK_PC1 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ pinctrl-names = "default";
+ pinctrl-0 = <&sys_led_pin>;
+ };
+
+ wan_led: led-1 {
+ label = "wan_led";
+ gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&wan_led_pin>;
+ };
+
+ lan1_led: led-2 {
+ label = "lan1_led";
+ gpios = <&gpio1 RK_PC3 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&lan1_led_pin>;
+ };
+
+ lan2_led: led-3 {
+ label = "lan2_led";
+ gpios = <&gpio1 RK_PC4 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&lan2_led_pin>;
+ };
+ };
+
+ 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>;
+ };
+
+ vcc_3v3_s0: vcc-3v3-s0-regulator {
+ compatible = "regulator-fixed";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc_3v3_s0";
+ vin-supply = <&vcc_3v3_s3>;
+ };
+
+ vcc_3v3_sd_s0: vcc-3v3-sd-s0-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio4 RK_PB4 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd_s0_pwr>;
+ regulator-name = "vcc_3v3_sd_s0";
+ regulator-boot-on;
+ regulator-max-microvolt = <3000000>;
+ regulator-min-microvolt = <3000000>;
+ vin-supply = <&vcc_3v3_s3>;
+ };
+
+ vcc_3v3_pcie20: vcc3v3-pcie20-regulator {
+ 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>;
+ };
+
+ vcc5v0_usb: vcc5v0-usb-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_usb";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc5v0_usb_otg0: vcc5v0-usb-otg0-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&typec5v_pwren>;
+ regulator-name = "vcc5v0_usb_otg0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_usb>;
+ };
+
+ vcc5v0_host_20: vcc5v0-host-20-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio4 RK_PB5 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc5v0_host20_en>;
+ regulator-name = "vcc5v0_host_20";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_usb>;
+ };
+};
+
+&combphy0_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>;
+};
+
+&gmac1 {
+ clock_in_out = "output";
+ phy-handle = <&rgmii_phy1>;
+ phy-mode = "rgmii-rxid";
+ pinctrl-0 = <&gmac1_miim
+ &gmac1_tx_bus2
+ &gmac1_rx_bus2
+ &gmac1_rgmii_clk
+ &gmac1_rgmii_bus>;
+ pinctrl-names = "default";
+ tx_delay = <0x42>;
+ 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";
+
+ vdd_npu_s0: regulator@42 {
+ compatible = "rockchip,rk8602";
+ reg = <0x42>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_npu_s0";
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <2300>;
+ regulator-boot-on;
+ regulator-always-on;
+ vin-supply = <&vcc5v0_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";
+ pinctrl-names = "default";
+ pinctrl-0 = <&rtc_int>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>;
+ wakeup-source;
+ };
+};
+
+&mdio1 {
+ rgmii_phy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-id001c.c916";
+ reg = <0x1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&rtl8211f_rst>;
+ reset-assert-us = <20000>;
+ reset-deassert-us = <100000>;
+ reset-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&pcie2x1l1 {
+ reset-gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc_3v3_pcie20>;
+ status = "okay";
+};
+
+&pcie2x1l2 {
+ reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc_3v3_pcie20>;
+ status = "okay";
+};
+
+&pinctrl {
+ gpio-key {
+ key1_pin: key1-pin {
+ rockchip,pins = <1 RK_PC0 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ gpio-leds {
+ sys_led_pin: sys-led-pin {
+ rockchip,pins =
+ <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ wan_led_pin: wan-led-pin {
+ rockchip,pins =
+ <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ lan1_led_pin: lan1-led-pin {
+ rockchip,pins =
+ <1 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ lan2_led_pin: lan2-led-pin {
+ rockchip,pins =
+ <1 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ hym8563 {
+ rtc_int: rtc-int {
+ rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ sdmmc {
+ sd_s0_pwr: sd-s0-pwr {
+ rockchip,pins = <4 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ usb {
+ typec5v_pwren: typec5v-pwren {
+ rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ vcc5v0_host20_en: vcc5v0-host20-en {
+ rockchip,pins = <4 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ rtl8211f {
+ rtl8211f_rst: rtl8211f-rst {
+ rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&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-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>;
+ 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;
+ 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-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;
+ };
+ };
+
+ avcc_3v3_s0: pldo-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "avcc_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>;
+ };
+ };
+
+ avdd_ddr_pll_s0: nldo-reg2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-name = "avdd_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;
+ };
+ };
+
+ avdd_0v85_s0: nldo-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-name = "avdd_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";
+};
+
+&u2phy2 {
+ status = "okay";
+};
+
+&u2phy2_host {
+ phy-supply = <&vcc5v0_host_20>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-0 = <&uart2m0_xfer>;
+ status = "okay";
+};
+
+&usb_host0_ehci {
+ status = "okay";
+};
+
+&usb_host0_ohci {
+ 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 2002fd0221fa..00afb90d4eb1 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
@@ -366,7 +366,6 @@
bus-width = <4>;
cap-mmc-highspeed;
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/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
index 36b1b7acfe6a..87b83c87bd55 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
@@ -519,6 +519,7 @@
vo1_grf: syscon@fd5a8000 {
compatible = "rockchip,rk3588-vo-grf", "syscon";
reg = <0x0 0xfd5a8000 0x0 0x100>;
+ clocks = <&cru PCLK_VO1GRF>;
};
php_grf: syscon@fd5b0000 {
@@ -586,6 +587,11 @@
};
};
+ 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>;
@@ -1704,7 +1710,6 @@
dmas = <&dmac1 0>, <&dmac1 1>;
dma-names = "tx", "rx";
power-domains = <&power RK3588_PD_AUDIO>;
- rockchip,trcm-sync-tx-only;
pinctrl-names = "default";
pinctrl-0 = <&i2s2m1_lrck
&i2s2m1_sclk
@@ -1725,7 +1730,6 @@
dmas = <&dmac1 2>, <&dmac1 3>;
dma-names = "tx", "rx";
power-domains = <&power RK3588_PD_AUDIO>;
- rockchip,trcm-sync-tx-only;
pinctrl-names = "default";
pinctrl-0 = <&i2s3_lrck
&i2s3_sclk
@@ -2360,6 +2364,22 @@
#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>;
diff --git a/arch/arm64/boot/dts/st/stm32mp251.dtsi b/arch/arm64/boot/dts/st/stm32mp251.dtsi
index 96859d098ef8..5dd4f3580a60 100644
--- a/arch/arm64/boot/dts/st/stm32mp251.dtsi
+++ b/arch/arm64/boot/dts/st/stm32mp251.dtsi
@@ -52,6 +52,18 @@
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>;
+ };
};
firmware {
diff --git a/arch/arm64/boot/dts/st/stm32mp255.dtsi b/arch/arm64/boot/dts/st/stm32mp255.dtsi
index e6fa596211f5..17f197c5b22b 100644
--- a/arch/arm64/boot/dts/st/stm32mp255.dtsi
+++ b/arch/arm64/boot/dts/st/stm32mp255.dtsi
@@ -6,4 +6,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>;
+ };
+
+ venc: venc@480e0000 {
+ compatible = "st,stm32mp25-venc";
+ reg = <0x480e0000 0x800>;
+ interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ck_icn_ls_mcu>;
+ };
+ };
+ };
};
diff --git a/arch/arm64/boot/dts/tesla/fsd.dtsi b/arch/arm64/boot/dts/tesla/fsd.dtsi
index aaffb50b8b60..047a83cee603 100644
--- a/arch/arm64/boot/dts/tesla/fsd.dtsi
+++ b/arch/arm64/boot/dts/tesla/fsd.dtsi
@@ -601,6 +601,7 @@
clocks = <&clock_peric PERIC_PCLK_UART0>,
<&clock_peric PERIC_SCLK_UART0>;
clock-names = "uart", "clk_uart_baud0";
+ samsung,uart-fifosize = <64>;
status = "disabled";
};
@@ -613,6 +614,7 @@
clocks = <&clock_peric PERIC_PCLK_UART1>,
<&clock_peric PERIC_SCLK_UART1>;
clock-names = "uart", "clk_uart_baud0";
+ samsung,uart-fifosize = <64>;
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile
index 52c1dc910308..9a722c2473fb 100644
--- a/arch/arm64/boot/dts/ti/Makefile
+++ b/arch/arm64/boot/dts/ti/Makefile
@@ -1,4 +1,4 @@
-# SPDX-License-Identifier: GPL-2.0
+# SPDX-License-Identifier: GPL-2.0-only
#
# Make file to build device tree binaries for boards based on
# Texas Instruments Inc processors
@@ -22,6 +22,7 @@ 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-am62x-phyboard-lyra-gpio-fan.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-am62-lp-sk.dtb
# Boards with AM62Ax SoC
@@ -37,7 +38,15 @@ dtb-$(CONFIG_ARCH_K3) += k3-am62x-sk-csi2-imx219.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-am62x-sk-hdmi-audio.dtbo
# Boards with AM64x SoC
+k3-am642-hummingboard-t-pcie-dtbs := \
+ k3-am642-hummingboard-t.dtb k3-am642-hummingboard-t-pcie.dtbo
+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-hummingboard-t.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t-pcie.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t-usb3.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am642-phyboard-electra-rdk.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am642-sk.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am642-tqma64xxl-mbax4xxl.dtb
@@ -45,18 +54,24 @@ dtb-$(CONFIG_ARCH_K3) += k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-am64-tqma64xxl-mbax4xxl-wlan.dtbo
# Boards with AM65x SoC
-k3-am654-gp-evm-dtbs := k3-am654-base-board.dtb k3-am654-base-board-rocktech-rk101-panel.dtbo
+k3-am654-gp-evm-dtbs := k3-am654-base-board.dtb \
+ k3-am654-base-board-rocktech-rk101-panel.dtbo \
+ k3-am654-pcie-usb3.dtbo
k3-am654-evm-dtbs := k3-am654-base-board.dtb k3-am654-icssg2.dtbo
-k3-am654-idk-dtbs := k3-am654-evm.dtb k3-am654-idk.dtbo
+k3-am654-idk-dtbs := k3-am654-evm.dtb k3-am654-idk.dtbo k3-am654-pcie-usb2.dtbo
dtb-$(CONFIG_ARCH_K3) += k3-am6528-iot2050-basic.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am6528-iot2050-basic-pg2.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am6548-iot2050-advanced.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am6548-iot2050-advanced-m2.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am6548-iot2050-advanced-pg2.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am6548-iot2050-advanced-sm.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am654-base-board.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am654-gp-evm.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am654-evm.dtb
dtb-$(CONFIG_ARCH_K3) += k3-am654-idk.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am654-base-board-rocktech-rk101-panel.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am654-pcie-usb2.dtbo
+dtb-$(CONFIG_ARCH_K3) += k3-am654-pcie-usb3.dtbo
# Boards with J7200 SoC
k3-j7200-evm-dtbs := k3-j7200-common-proc-board.dtb k3-j7200-evm-quad-port-eth-exp.dtbo
@@ -69,6 +84,7 @@ 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
dtb-$(CONFIG_ARCH_K3) += k3-j721e-sk.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-j721e-sk-csi2-dual-imx219.dtbo
# Boards with J721s2 SoC
dtb-$(CONFIG_ARCH_K3) += k3-am68-sk-base-board.dtb
@@ -78,6 +94,9 @@ k3-j721s2-evm-dtbs := k3-j721s2-common-proc-board.dtb k3-j721s2-evm-gesi-exp-boa
dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm.dtb
dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm-pcie1-ep.dtbo
+# Boards with J722s SoC
+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
@@ -87,6 +106,8 @@ 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-gpio-fan-dtbs := k3-am625-phyboard-lyra-rdk.dtb \
+ k3-am62x-phyboard-lyra-gpio-fan.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 \
@@ -101,12 +122,27 @@ k3-am62a7-sk-csi2-ov5640-dtbs := k3-am62a7-sk.dtb \
k3-am62x-sk-csi2-ov5640.dtbo
k3-am62a7-sk-csi2-tevi-ov5640-dtbs := k3-am62a7-sk.dtb \
k3-am62x-sk-csi2-tevi-ov5640.dtbo
+k3-am62a7-sk-hdmi-audio-dtbs := k3-am62a7-sk.dtb k3-am62x-sk-hdmi-audio.dtbo
+k3-am62p5-sk-csi2-imx219-dtbs := k3-am62p5-sk.dtb \
+ k3-am62x-sk-csi2-imx219.dtbo
+k3-am62p5-sk-csi2-ov5640-dtbs := k3-am62p5-sk.dtb \
+ k3-am62x-sk-csi2-ov5640.dtbo
+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-tqma64xxl-mbax4xxl-sdcard-dtbs := \
k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo
k3-am642-tqma64xxl-mbax4xxl-wlan-dtbs := \
k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-wlan.dtbo
+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-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
dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
@@ -118,9 +154,17 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
k3-am62-lp-sk-hdmi-audio.dtb \
k3-am62a7-sk-csi2-imx219.dtb \
k3-am62a7-sk-csi2-ov5640.dtb \
+ k3-am62a7-sk-hdmi-audio.dtb \
+ k3-am62p5-sk-csi2-imx219.dtb \
+ k3-am62p5-sk-csi2-ov5640.dtb \
+ k3-am62p5-sk-csi2-tevi-ov5640.dtb \
+ k3-am642-evm-icssg1-dualemac.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-j721e-evm-pcie0-ep.dtb \
+ k3-j721e-sk-csi2-dual-imx219-dtbs \
k3-j721s2-evm-pcie1-ep.dtb
# Enable support for device-tree overlays
@@ -128,7 +172,12 @@ DTC_FLAGS_k3-am625-beagleplay += -@
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-tqma64xxl-mbax4xxl += -@
DTC_FLAGS_k3-am6548-iot2050-advanced-m2 += -@
+DTC_FLAGS_k3-am68-sk-base-board += -@
+DTC_FLAGS_k3-am69-sk += -@
DTC_FLAGS_k3-j721e-common-proc-board += -@
+DTC_FLAGS_k3-j721e-sk += -@
DTC_FLAGS_k3-j721s2-common-proc-board += -@
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 5e6feb8cd125..c4149059a4c5 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* AM62x LP SK: https://www.ti.com/tool/SK-AM62-LP
*
- * Copyright (C) 2021-2023 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2021-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
diff --git a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
index 464b7565d085..e9cffca073ef 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for AM625 SoC Family Main Domain peripherals
*
- * Copyright (C) 2020-2022 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2020-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
&cbass_main {
@@ -42,9 +42,8 @@
};
};
- main_conf: syscon@100000 {
- compatible = "syscon", "simple-mfd";
- reg = <0x00 0x00100000 0x00 0x20000>;
+ main_conf: bus@100000 {
+ compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x0 0x00 0x00100000 0x20000>;
@@ -559,10 +558,9 @@
clock-names = "clk_ahb", "clk_xin";
assigned-clocks = <&k3_clks 57 6>;
assigned-clock-parents = <&k3_clks 57 8>;
+ bus-width = <8>;
mmc-ddr-1_8v;
mmc-hs200-1_8v;
- ti,trm-icp = <0x2>;
- bus-width = <8>;
ti,clkbuf-sel = <0x7>;
ti,otap-del-sel-legacy = <0x0>;
ti,otap-del-sel-mmc-hs = <0x0>;
@@ -580,7 +578,8 @@
power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
clock-names = "clk_ahb", "clk_xin";
- ti,trm-icp = <0x2>;
+ bus-width = <4>;
+ ti,clkbuf-sel = <0x7>;
ti,otap-del-sel-legacy = <0x8>;
ti,otap-del-sel-sd-hs = <0x0>;
ti,otap-del-sel-sdr12 = <0x0>;
@@ -592,8 +591,6 @@
ti,itap-del-sel-sd-hs = <0x1>;
ti,itap-del-sel-sdr12 = <0xa>;
ti,itap-del-sel-sdr25 = <0x1>;
- ti,clkbuf-sel = <0x7>;
- bus-width = <4>;
status = "disabled";
};
@@ -604,7 +601,8 @@
power-domains = <&k3_pds 184 TI_SCI_PD_EXCLUSIVE>;
clocks = <&k3_clks 184 5>, <&k3_clks 184 6>;
clock-names = "clk_ahb", "clk_xin";
- ti,trm-icp = <0x2>;
+ bus-width = <4>;
+ ti,clkbuf-sel = <0x7>;
ti,otap-del-sel-legacy = <0x8>;
ti,otap-del-sel-sd-hs = <0x0>;
ti,otap-del-sel-sdr12 = <0x0>;
@@ -616,7 +614,6 @@
ti,itap-del-sel-sd-hs = <0xa>;
ti,itap-del-sel-sdr12 = <0xa>;
ti,itap-del-sel-sdr25 = <0x1>;
- ti,clkbuf-sel = <0x7>;
status = "disabled";
};
@@ -640,6 +637,8 @@
interrupt-names = "host", "peripheral";
maximum-speed = "high-speed";
dr_mode = "otg";
+ snps,usb2-gadget-lpm-disable;
+ snps,usb2-lpm-disable;
};
};
@@ -663,6 +662,8 @@
interrupt-names = "host", "peripheral";
maximum-speed = "high-speed";
dr_mode = "otg";
+ snps,usb2-gadget-lpm-disable;
+ snps,usb2-lpm-disable;
};
};
@@ -779,9 +780,10 @@
<0x00 0x30207000 0x00 0x1000>, /* ovr1 */
<0x00 0x30208000 0x00 0x1000>, /* ovr2 */
<0x00 0x3020a000 0x00 0x1000>, /* vp1: Used for OLDI */
- <0x00 0x3020b000 0x00 0x1000>; /* vp2: Used as DPI Out */
+ <0x00 0x3020b000 0x00 0x1000>, /* vp2: Used as DPI Out */
+ <0x00 0x30201000 0x00 0x1000>; /* common1 */
reg-names = "common", "vidl1", "vid",
- "ovr1", "ovr2", "vp1", "vp2";
+ "ovr1", "ovr2", "vp1", "vp2", "common1";
power-domains = <&k3_pds 186 TI_SCI_PD_EXCLUSIVE>;
clocks = <&k3_clks 186 6>,
<&dss_vp1_clk>,
diff --git a/arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi
index 0e0b234581c6..e66d486ef1f2 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-mcu.dtsi
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for AM625 SoC Family MCU Domain peripherals
*
- * Copyright (C) 2020-2022 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2020-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
&cbass_mcu {
diff --git a/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi b/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi
index aa43e7407eee..43488cc8bcb1 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi
@@ -1,6 +1,6 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
- * Copyright (C) 2022 - 2023 PHYTEC Messtechnik GmbH
+ * Copyright (C) 2022-2024 PHYTEC Messtechnik GmbH
* Author: Wadim Egorov <w.egorov@phytec.de>
*
* Product homepage:
@@ -317,7 +317,6 @@
&sdhci0 {
pinctrl-names = "default";
pinctrl-0 = <&main_mmc0_pins_default>;
- ti,driver-strength-ohm = <50>;
disable-wp;
non-removable;
status = "okay";
diff --git a/arch/arm64/boot/dts/ti/k3-am62-thermal.dtsi b/arch/arm64/boot/dts/ti/k3-am62-thermal.dtsi
index a358757e26f0..12ba833002a1 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-thermal.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-thermal.dtsi
@@ -1,4 +1,7 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
#include <dt-bindings/thermal/thermal.h>
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 bf6d27e70bc4..6c4cec8728e4 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi
@@ -185,7 +185,6 @@
/* Verdin SD_1 */
&sdhci1 {
- ti,driver-strength-ohm = <33>;
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 680071688dcb..be62648e7818 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi
@@ -206,7 +206,6 @@
/* Verdin SD_1 */
&sdhci1 {
- ti,driver-strength-ohm = <33>;
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 17b93534f658..77b1beb638ad 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-verdin-mallow.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-mallow.dtsi
@@ -127,6 +127,16 @@
<&pinctrl_qspi1_cs2_gpio>;
cs-gpios = <0>, <&main_gpio0 12 GPIO_ACTIVE_LOW>;
status = "okay";
+
+ tpm@1 {
+ compatible = "infineon,slb9670", "tcg,tpm_tis-spi";
+ reg = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_qspi1_dqs_gpio>;
+ interrupt-parent = <&main_gpio1>;
+ interrupts = <18 IRQ_TYPE_EDGE_FALLING>;
+ spi-max-frequency = <18500000>;
+ };
};
/* Verdin UART_3 */
diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi
index a6808b10c7b2..4768ef42c4fc 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-wifi.dtsi
@@ -26,7 +26,6 @@
mmc-pwrseq = <&wifi_pwrseq>;
non-removable;
ti,fails-without-test-cd;
- ti,driver-strength-ohm = <50>;
vmmc-supply = <&reg_3v3>;
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 6a06724b6d16..e8d8857ad51f 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
@@ -42,6 +42,22 @@
usb1 = &usb1;
};
+ connector {
+ compatible = "gpio-usb-b-connector", "usb-b-connector";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb0_id>;
+ id-gpios = <&main_gpio1 19 GPIO_ACTIVE_HIGH>;
+ label = "USB_1";
+ self-powered;
+ vbus-supply = <&reg_usb0_vbus>;
+
+ port {
+ usb_dr_connector: endpoint {
+ remote-endpoint = <&usb0_ep>;
+ };
+ };
+ };
+
verdin_gpio_keys: gpio-keys {
compatible = "gpio-keys";
pinctrl-names = "default";
@@ -151,6 +167,18 @@
vin-supply = <&reg_sd_3v3_1v8>;
};
+ reg_usb0_vbus: regulator-usb0-vbus {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb0_en>;
+ enable-active-high;
+ /* Verdin USB_1_EN (SODIMM 155) */
+ gpio = <&main_gpio1 50 GPIO_ACTIVE_HIGH>;
+ regulator-max-microvolt = <5000000>;
+ regulator-min-microvolt = <5000000>;
+ regulator-name = "USB_1_EN";
+ };
+
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
@@ -436,6 +464,13 @@
>;
};
+ /* Verdin USB_1_EN */
+ pinctrl_usb0_en: main-gpio1-50-default-pins {
+ pinctrl-single,pins = <
+ AM62X_IOPAD(0x0254, PIN_INPUT, 7) /* (C20) USB0_DRVVBUS.GPIO1_50 */ /* SODIMM 155 */
+ >;
+ };
+
/* On-module I2C - PMIC_I2C */
pinctrl_i2c0: main-i2c0-default-pins {
pinctrl-single,pins = <
@@ -660,13 +695,6 @@
>;
};
- /* Verdin USB_1 */
- pinctrl_usb0: main-usb0-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x0254, PIN_OUTPUT, 0) /* (C20) USB0_DRVVBUS */ /* SODIMM 155 */
- >;
- };
-
/* Verdin USB_2 */
pinctrl_usb1: main-usb1-default-pins {
pinctrl-single,pins = <
@@ -1013,7 +1041,7 @@
"",
"",
"SODIMM_17",
- "", /* 50 */
+ "SODIMM_155", /* 50 */
"",
"",
"",
@@ -1118,7 +1146,7 @@
regulator-always-on;
regulator-boot-on;
regulator-max-microvolt = <850000>;
- regulator-min-microvolt = <850000>;
+ regulator-min-microvolt = <750000>;
regulator-name = "+VDD_CORE (PMIC BUCK1)";
};
@@ -1407,7 +1435,6 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sdhci0>;
non-removable;
- ti,driver-strength-ohm = <50>;
status = "okay";
};
@@ -1416,7 +1443,6 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sdhci1>;
disable-wp;
- ti,driver-strength-ohm = <50>;
vmmc-supply = <&reg_sdhc1_vmmc>;
vqmmc-supply = <&reg_sdhc1_vqmmc>;
status = "disabled";
@@ -1428,11 +1454,16 @@
status = "disabled";
};
-/* TODO: role swich using ID pin */
&usb0 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usb0>, <&pinctrl_usb0_id>;
+ adp-disable;
+ usb-role-switch;
status = "disabled";
+
+ port {
+ usb0_ep: endpoint {
+ remote-endpoint = <&usb_dr_connector>;
+ };
+ };
};
/* Verdin USB_2 */
diff --git a/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
index fef76f52a52e..23ce1bfda8d6 100644
--- a/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
@@ -1,10 +1,12 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for AM625 SoC Family Wakeup Domain peripherals
*
- * Copyright (C) 2020-2022 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2020-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
+#include <dt-bindings/bus/ti-sysc.h>
+
&cbass_wakeup {
wkup_conf: syscon@43000000 {
bootph-all;
@@ -21,14 +23,34 @@
};
};
- wkup_uart0: serial@2b300000 {
- compatible = "ti,am64-uart", "ti,am654-uart";
- reg = <0x00 0x2b300000 0x00 0x100>;
- interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
+ target-module@2b300050 {
+ compatible = "ti,sysc-omap2", "ti,sysc";
+ reg = <0x00 0x2b300050 0x00 0x4>,
+ <0x00 0x2b300054 0x00 0x4>,
+ <0x00 0x2b300058 0x00 0x4>;
+ reg-names = "rev", "sysc", "syss";
+ ti,sysc-mask = <(SYSC_OMAP2_ENAWAKEUP |
+ SYSC_OMAP2_SOFTRESET |
+ SYSC_OMAP2_AUTOIDLE)>;
+ ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+ <SYSC_IDLE_NO>,
+ <SYSC_IDLE_SMART>,
+ <SYSC_IDLE_SMART_WKUP>;
+ ti,syss-mask = <1>;
+ ti,no-reset-on-init;
power-domains = <&k3_pds 114 TI_SCI_PD_EXCLUSIVE>;
clocks = <&k3_clks 114 0>;
- clock-names = "fclk";
- status = "disabled";
+ clock-names = "fck";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x00 0x2b300000 0x100000>;
+
+ wkup_uart0: serial@0 {
+ compatible = "ti,am64-uart", "ti,am654-uart";
+ reg = <0x0 0x100>;
+ interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
};
wkup_i2c0: i2c@2b200000 {
diff --git a/arch/arm64/boot/dts/ti/k3-am62.dtsi b/arch/arm64/boot/dts/ti/k3-am62.dtsi
index f1e15206e1ce..f0781f2bea29 100644
--- a/arch/arm64/boot/dts/ti/k3-am62.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62.dtsi
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for AM62 SoC Family
*
- * Copyright (C) 2020-2022 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2020-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
#include <dt-bindings/gpio/gpio.h>
diff --git a/arch/arm64/boot/dts/ti/k3-am625-beagleplay-csi2-ov5640.dtso b/arch/arm64/boot/dts/ti/k3-am625-beagleplay-csi2-ov5640.dtso
index 5e80ca7033ba..3b4643b7d19c 100644
--- a/arch/arm64/boot/dts/ti/k3-am625-beagleplay-csi2-ov5640.dtso
+++ b/arch/arm64/boot/dts/ti/k3-am625-beagleplay-csi2-ov5640.dtso
@@ -1,7 +1,7 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* ALINX AN5641 & Digilent PCam 5C - OV5640 camera module
- * Copyright (C) 2022-2023 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
diff --git a/arch/arm64/boot/dts/ti/k3-am625-beagleplay-csi2-tevi-ov5640.dtso b/arch/arm64/boot/dts/ti/k3-am625-beagleplay-csi2-tevi-ov5640.dtso
index 5e1cbbc27c8f..81a2763d43c6 100644
--- a/arch/arm64/boot/dts/ti/k3-am625-beagleplay-csi2-tevi-ov5640.dtso
+++ b/arch/arm64/boot/dts/ti/k3-am625-beagleplay-csi2-tevi-ov5640.dtso
@@ -1,7 +1,7 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Technexion TEVI-OV5640-*-RPI - OV5640 camera module
- * Copyright (C) 2022-2023 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
diff --git a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
index eadbdd9ffe37..a34e0df2ab86 100644
--- a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
+++ b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
@@ -1,9 +1,9 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* https://beagleplay.org/
*
- * Copyright (C) 2022-2023 Texas Instruments Incorporated - https://www.ti.com/
- * Copyright (C) 2022-2023 Robert Nelson, BeagleBoard.org Foundation
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2022-2024 Robert Nelson, BeagleBoard.org Foundation
*/
/dts-v1/;
@@ -29,7 +29,6 @@
i2c3 = &main_i2c3;
i2c4 = &wkup_i2c0;
i2c5 = &mcu_i2c0;
- mdio-gpio0 = &mdio0;
mmc0 = &sdhci0;
mmc1 = &sdhci1;
mmc2 = &sdhci2;
@@ -231,27 +230,6 @@
};
};
- /* Workaround for errata i2329 - just use mdio bitbang */
- mdio0: mdio {
- compatible = "virtual,mdio-gpio";
- pinctrl-names = "default";
- pinctrl-0 = <&mdio0_pins_default>;
- gpios = <&main_gpio0 86 GPIO_ACTIVE_HIGH>, /* MDC */
- <&main_gpio0 85 GPIO_ACTIVE_HIGH>; /* MDIO */
- #address-cells = <1>;
- #size-cells = <0>;
-
- cpsw3g_phy0: ethernet-phy@0 {
- reg = <0>;
- };
-
- cpsw3g_phy1: ethernet-phy@1 {
- reg = <1>;
- reset-gpios = <&main_gpio1 5 GPIO_ACTIVE_LOW>;
- reset-assert-us = <25>;
- reset-deassert-us = <60000>; /* T2 */
- };
- };
};
&main_pmx0 {
@@ -312,8 +290,8 @@
mdio0_pins_default: mdio0-default-pins {
pinctrl-single,pins = <
- AM62X_IOPAD(0x0160, PIN_OUTPUT, 7) /* (AD24) MDIO0_MDC.GPIO0_86 */
- AM62X_IOPAD(0x015c, PIN_INPUT, 7) /* (AB22) MDIO0_MDIO.GPIO0_85 */
+ AM62X_IOPAD(0x0160, PIN_OUTPUT, 0) /* (AD24) MDIO0_MDC */
+ AM62X_IOPAD(0x015c, PIN_INPUT, 0) /* (AB22) MDIO0_MDIO */
>;
};
@@ -573,11 +551,13 @@
};
&usbss0 {
+ bootph-all;
ti,vbus-divider;
status = "okay";
};
&usb0 {
+ bootph-all;
dr_mode = "peripheral";
};
@@ -611,8 +591,20 @@
};
&cpsw3g_mdio {
- /* Workaround for errata i2329 - Use mdio bitbang */
- status = "disabled";
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mdio0_pins_default>;
+
+ cpsw3g_phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+
+ cpsw3g_phy1: ethernet-phy@1 {
+ reg = <1>;
+ reset-gpios = <&main_gpio1 5 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <25>;
+ reset-deassert-us = <60000>; /* T2 */
+ };
};
&main_gpio0 {
@@ -827,7 +819,6 @@
bootph-all;
pinctrl-names = "default";
pinctrl-0 = <&emmc_pins_default>;
- ti,driver-strength-ohm = <50>;
disable-wp;
status = "okay";
};
@@ -840,7 +831,6 @@
vmmc-supply = <&vdd_3v3_sd>;
vqmmc-supply = <&vdd_sd_dv>;
- ti,driver-strength-ohm = <50>;
disable-wp;
cd-gpios = <&main_gpio1 48 GPIO_ACTIVE_LOW>;
cd-debounce-delay-ms = <100>;
@@ -852,12 +842,10 @@
vmmc-supply = <&wlan_en>;
pinctrl-names = "default";
pinctrl-0 = <&wifi_pins_default>, <&wifi_32k_clk>;
- bus-width = <4>;
non-removable;
ti,fails-without-test-cd;
cap-power-off-card;
keep-power-in-suspend;
- ti,driver-strength-ohm = <50>;
assigned-clocks = <&k3_clks 157 158>;
assigned-clock-parents = <&k3_clks 157 160>;
#address-cells = <1>;
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 4bc0134c987d..a83a90497857 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
@@ -1,6 +1,6 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
- * Copyright (C) 2022 - 2023 PHYTEC Messtechnik GmbH
+ * Copyright (C) 2022-2024 PHYTEC Messtechnik GmbH
* Author: Wadim Egorov <w.egorov@phytec.de>
*
* Product homepage:
@@ -222,6 +222,7 @@
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>;
};
@@ -333,7 +334,6 @@
vqmmc-supply = <&vddshv5_sdio>;
pinctrl-names = "default";
pinctrl-0 = <&main_mmc1_pins_default>;
- ti,driver-strength-ohm = <50>;
disable-wp;
no-1-8-v;
status = "okay";
diff --git a/arch/arm64/boot/dts/ti/k3-am625-sk.dts b/arch/arm64/boot/dts/ti/k3-am625-sk.dts
index b18092497c9a..ae81ebb39d02 100644
--- a/arch/arm64/boot/dts/ti/k3-am625-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am625-sk.dts
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* AM625 SK: https://www.ti.com/lit/zip/sprr448
*
- * Copyright (C) 2021-2022 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2021-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
diff --git a/arch/arm64/boot/dts/ti/k3-am625.dtsi b/arch/arm64/boot/dts/ti/k3-am625.dtsi
index 4193c2b3eed6..4014add6320d 100644
--- a/arch/arm64/boot/dts/ti/k3-am625.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am625.dtsi
@@ -1,10 +1,10 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for AM625 SoC family in Quad core configuration
*
* TRM: https://www.ti.com/lit/pdf/spruiv7
*
- * Copyright (C) 2020-2022 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2020-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
index f0b8c9ab1459..aa1e057082f0 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for AM62A SoC Family Main Domain peripherals
*
- * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
&cbass_main {
@@ -42,9 +42,8 @@
};
};
- main_conf: syscon@100000 {
- compatible = "ti,j721e-system-controller", "syscon", "simple-mfd";
- reg = <0x00 0x00100000 0x00 0x20000>;
+ main_conf: bus@100000 {
+ compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x00 0x00 0x00100000 0x20000>;
@@ -536,6 +535,24 @@
status = "disabled";
};
+ sdhci0: mmc@fa10000 {
+ compatible = "ti,am62-sdhci";
+ reg = <0x00 0xfa10000 0x00 0x260>, <0x00 0xfa18000 0x00 0x134>;
+ interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 57 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 57 5>, <&k3_clks 57 6>;
+ clock-names = "clk_ahb", "clk_xin";
+ assigned-clocks = <&k3_clks 57 6>;
+ assigned-clock-parents = <&k3_clks 57 8>;
+ bus-width = <8>;
+ mmc-hs200-1_8v;
+ ti,clkbuf-sel = <0x7>;
+ ti,otap-del-sel-legacy = <0x0>;
+ ti,otap-del-sel-mmc-hs = <0x0>;
+ ti,otap-del-sel-hs200 = <0x6>;
+ status = "disabled";
+ };
+
sdhci1: mmc@fa00000 {
compatible = "ti,am62-sdhci";
reg = <0x00 0xfa00000 0x00 0x260>, <0x00 0xfa08000 0x00 0x134>;
@@ -543,7 +560,8 @@
power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
clock-names = "clk_ahb", "clk_xin";
- ti,trm-icp = <0x2>;
+ 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>;
@@ -555,8 +573,30 @@
ti,itap-del-sel-sd-hs = <0x0>;
ti,itap-del-sel-sdr12 = <0x0>;
ti,itap-del-sel-sdr25 = <0x0>;
- ti,clkbuf-sel = <0x7>;
+ no-1-8-v;
+ status = "disabled";
+ };
+
+ sdhci2: mmc@fa20000 {
+ compatible = "ti,am62-sdhci";
+ reg = <0x00 0xfa20000 0x00 0x260>, <0x00 0xfa28000 0x00 0x134>;
+ 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-sdr104 = <0x6>;
+ ti,otap-del-sel-ddr50 = <0x9>;
+ 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>;
no-1-8-v;
status = "disabled";
};
@@ -985,4 +1025,30 @@
power-domains = <&k3_pds 185 TI_SCI_PD_EXCLUSIVE>;
status = "disabled";
};
+
+ dss: dss@30200000 {
+ compatible = "ti,am62a7-dss";
+ reg = <0x00 0x30200000 0x00 0x1000>, /* common */
+ <0x00 0x30202000 0x00 0x1000>, /* vidl1 */
+ <0x00 0x30206000 0x00 0x1000>, /* vid */
+ <0x00 0x30207000 0x00 0x1000>, /* ovr1 */
+ <0x00 0x30208000 0x00 0x1000>, /* ovr2 */
+ <0x00 0x3020a000 0x00 0x1000>, /* vp1: Tied OFF in the SoC */
+ <0x00 0x3020b000 0x00 0x1000>, /* vp2: Used as DPI Out */
+ <0x00 0x30201000 0x00 0x1000>; /* common1 */
+ reg-names = "common", "vidl1", "vid",
+ "ovr1", "ovr2", "vp1", "vp2", "common1";
+ power-domains = <&k3_pds 186 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 186 6>,
+ <&k3_clks 186 0>,
+ <&k3_clks 186 2>;
+ clock-names = "fck", "vp1", "vp2";
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+
+ dss_ports: ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
};
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-mcu.dtsi
index a6d16a94088c..8c36e56f4138 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-mcu.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-mcu.dtsi
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for AM625 SoC Family MCU Domain peripherals
*
- * Copyright (C) 2020-2022 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2020-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
&cbass_mcu {
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-thermal.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-thermal.dtsi
index 85ce545633ea..c7486fb2a5b4 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-thermal.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-thermal.dtsi
@@ -1,4 +1,7 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
#include <dt-bindings/thermal/thermal.h>
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi
index 4e8279fa01e1..f7bec484705a 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for AM62A SoC Family Wakeup Domain peripherals
*
- * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
&cbass_wakeup {
diff --git a/arch/arm64/boot/dts/ti/k3-am62a.dtsi b/arch/arm64/boot/dts/ti/k3-am62a.dtsi
index 61a210ecd5ff..b1b884600293 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a.dtsi
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for AM62A SoC Family
*
- * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
#include <dt-bindings/gpio/gpio.h>
diff --git a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
index 7b7142586295..f241637a5642 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* AM62A SK: https://www.ti.com/lit/zip/sprr459
*
- * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
@@ -20,6 +20,7 @@
serial0 = &wkup_uart0;
serial2 = &main_uart0;
serial3 = &main_uart1;
+ mmc0 = &sdhci0;
mmc1 = &sdhci1;
};
@@ -132,6 +133,18 @@
clock-frequency = <12288000>;
};
+ hdmi0: connector-hdmi {
+ compatible = "hdmi-connector";
+ label = "hdmi";
+ type = "a";
+
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&sii9022_out>;
+ };
+ };
+ };
+
codec_audio: sound {
compatible = "simple-audio-card";
simple-audio-card,name = "AM62Ax-SKEVM";
@@ -181,6 +194,39 @@
};
&main_pmx0 {
+ main_dss0_pins_default: main-dss0-default-pins {
+ pinctrl-single,pins = <
+ AM62AX_IOPAD(0x100, PIN_OUTPUT, 0) /* (V17) VOUT0_VSYNC */
+ AM62AX_IOPAD(0x0f8, PIN_OUTPUT, 0) /* (T18) VOUT0_HSYNC */
+ AM62AX_IOPAD(0x104, PIN_OUTPUT, 0) /* (AA22) VOUT0_PCLK */
+ AM62AX_IOPAD(0x0fc, PIN_OUTPUT, 0) /* (U17) VOUT0_DE */
+ AM62AX_IOPAD(0x0b8, PIN_OUTPUT, 0) /* (U22) VOUT0_DATA0 */
+ AM62AX_IOPAD(0x0bc, PIN_OUTPUT, 0) /* (U21) VOUT0_DATA1 */
+ AM62AX_IOPAD(0x0c0, PIN_OUTPUT, 0) /* (U20) VOUT0_DATA2 */
+ AM62AX_IOPAD(0x0c4, PIN_OUTPUT, 0) /* (U19) VOUT0_DATA3 */
+ AM62AX_IOPAD(0x0c8, PIN_OUTPUT, 0) /* (T19) VOUT0_DATA4 */
+ AM62AX_IOPAD(0x0cc, PIN_OUTPUT, 0) /* (U18) VOUT0_DATA5 */
+ AM62AX_IOPAD(0x0d0, PIN_OUTPUT, 0) /* (V22) VOUT0_DATA6 */
+ AM62AX_IOPAD(0x0d4, PIN_OUTPUT, 0) /* (V21) VOUT0_DATA7 */
+ AM62AX_IOPAD(0x0d8, PIN_OUTPUT, 0) /* (V19) VOUT0_DATA8 */
+ AM62AX_IOPAD(0x0dc, PIN_OUTPUT, 0) /* (V18) VOUT0_DATA9 */
+ AM62AX_IOPAD(0x0e0, PIN_OUTPUT, 0) /* (W22) VOUT0_DATA10 */
+ AM62AX_IOPAD(0x0e4, PIN_OUTPUT, 0) /* (W21) VOUT0_DATA11 */
+ AM62AX_IOPAD(0x0e8, PIN_OUTPUT, 0) /* (W20) VOUT0_DATA12 */
+ AM62AX_IOPAD(0x0ec, PIN_OUTPUT, 0) /* (W19) VOUT0_DATA13 */
+ AM62AX_IOPAD(0x0f0, PIN_OUTPUT, 0) /* (Y21) VOUT0_DATA14 */
+ AM62AX_IOPAD(0x0f4, PIN_OUTPUT, 0) /* (Y22) VOUT0_DATA15 */
+ AM62AX_IOPAD(0x05c, PIN_OUTPUT, 1) /* (P22) GPMC0_AD8.VOUT0_DATA16 */
+ AM62AX_IOPAD(0x060, PIN_OUTPUT, 1) /* (R19) GPMC0_AD9.VOUT0_DATA17 */
+ AM62AX_IOPAD(0x064, PIN_OUTPUT, 1) /* (R20) GPMC0_AD10.VOUT0_DATA18 */
+ AM62AX_IOPAD(0x068, PIN_OUTPUT, 1) /* (R22) GPMC0_AD11.VOUT0_DATA19 */
+ AM62AX_IOPAD(0x06c, PIN_OUTPUT, 1) /* (T22) GPMC0_AD12.VOUT0_DATA20 */
+ AM62AX_IOPAD(0x070, PIN_OUTPUT, 1) /* (R21) GPMC0_AD13.VOUT0_DATA21 */
+ AM62AX_IOPAD(0x074, PIN_OUTPUT, 1) /* (T20) GPMC0_AD14.VOUT0_DATA22 */
+ AM62AX_IOPAD(0x078, PIN_OUTPUT, 1) /* (T21) GPMC0_AD15.VOUT0_DATA23 */
+ >;
+ };
+
main_uart0_pins_default: main-uart0-default-pins {
pinctrl-single,pins = <
AM62AX_IOPAD(0x1c8, PIN_INPUT, 0) /* (E14) UART0_RXD */
@@ -218,6 +264,22 @@
>;
};
+ main_mmc0_pins_default: main-mmc0-default-pins {
+ pinctrl-single,pins = <
+ AM62AX_IOPAD(0x220, PIN_INPUT, 0) /* (Y3) MMC0_CMD */
+ AM62AX_IOPAD(0x218, PIN_INPUT, 0) /* (AB1) MMC0_CLKLB */
+ AM62AX_IOPAD(0x21c, PIN_INPUT, 0) /* (AB1) MMC0_CLK */
+ AM62AX_IOPAD(0x214, PIN_INPUT, 0) /* (AA2) MMC0_DAT0 */
+ AM62AX_IOPAD(0x210, PIN_INPUT_PULLUP, 0) /* (AA1) MMC0_DAT1 */
+ AM62AX_IOPAD(0x20c, PIN_INPUT_PULLUP, 0) /* (AA3) MMC0_DAT2 */
+ AM62AX_IOPAD(0x208, PIN_INPUT_PULLUP, 0) /* (Y4) MMC0_DAT3 */
+ AM62AX_IOPAD(0x204, PIN_INPUT_PULLUP, 0) /* (AB2) MMC0_DAT4 */
+ AM62AX_IOPAD(0x200, PIN_INPUT_PULLUP, 0) /* (AC1) MMC0_DAT5 */
+ AM62AX_IOPAD(0x1fc, PIN_INPUT_PULLUP, 0) /* (AD2) MMC0_DAT6 */
+ AM62AX_IOPAD(0x1f8, PIN_INPUT_PULLUP, 0) /* (AC2) MMC0_DAT7 */
+ >;
+ };
+
main_mmc1_pins_default: main-mmc1-default-pins {
pinctrl-single,pins = <
AM62AX_IOPAD(0x23c, PIN_INPUT, 0) /* (A21) MMC1_CMD */
@@ -466,6 +528,36 @@
"CSI_EN", "AUTO_100M_1000M_CONFIG",
"CSI_VLDO_SEL", "SoC_WLAN_SDIO_RST";
};
+
+ sii9022: bridge-hdmi@3b {
+ compatible = "sil,sii9022";
+ reg = <0x3b>;
+ interrupt-parent = <&exp1>;
+ interrupts = <16 IRQ_TYPE_EDGE_FALLING>;
+ #sound-dai-cells = <0>;
+ sil,i2s-data-lanes = < 0 >;
+
+ 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>;
+ };
+ };
+ };
+ };
};
&main_i2c2 {
@@ -475,13 +567,21 @@
clock-frequency = <400000>;
};
+&sdhci0 {
+ /* eMMC */
+ status = "okay";
+ non-removable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mmc0_pins_default>;
+ disable-wp;
+};
+
&sdhci1 {
/* SD/MMC */
status = "okay";
vmmc-supply = <&vdd_mmc1>;
pinctrl-names = "default";
pinctrl-0 = <&main_mmc1_pins_default>;
- ti,driver-strength-ohm = <50>;
disable-wp;
};
@@ -583,3 +683,20 @@
tx-num-evt = <32>;
rx-num-evt = <32>;
};
+
+&dss {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_dss0_pins_default>;
+};
+
+&dss_ports {
+ /* VP2: DPI Output */
+ port@1 {
+ reg = <1>;
+
+ dpi1_out: endpoint {
+ remote-endpoint = <&sii9022_in>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am62a7.dtsi b/arch/arm64/boot/dts/ti/k3-am62a7.dtsi
index 58f1c43edcf8..f86a23404e6d 100644
--- a/arch/arm64/boot/dts/ti/k3-am62a7.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62a7.dtsi
@@ -1,10 +1,10 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for AM62A7 SoC family in Quad core configuration
*
* TRM: https://www.ti.com/lit/zip/spruj16
*
- * Copyright (C) 2020-2022 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2020-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
diff --git a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
index 4c51bae06b57..7337a9e13535 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
@@ -1,7 +1,7 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree file for the AM62P main domain peripherals
- * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
&cbass_main {
@@ -158,6 +158,43 @@
};
};
+ 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>;
@@ -534,7 +571,21 @@
clock-names = "clk_ahb", "clk_xin";
assigned-clocks = <&k3_clks 57 2>;
assigned-clock-parents = <&k3_clks 57 4>;
- ti,otap-del-sel-legacy = <0x0>;
+ 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";
};
@@ -545,7 +596,19 @@
power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
clocks = <&k3_clks 58 5>, <&k3_clks 58 6>;
clock-names = "clk_ahb", "clk_xin";
- ti,otap-del-sel-legacy = <0x8>;
+ 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";
};
@@ -556,7 +619,19 @@
power-domains = <&k3_pds 184 TI_SCI_PD_EXCLUSIVE>;
clocks = <&k3_clks 184 5>, <&k3_clks 184 6>;
clock-names = "clk_ahb", "clk_xin";
- ti,otap-del-sel-legacy = <0x8>;
+ 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";
};
@@ -891,4 +966,73 @@
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-mcu.dtsi
index c4b0b91d70cf..b973b550eb9d 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-mcu.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-mcu.dtsi
@@ -1,7 +1,7 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree file for the AM62P MCU domain peripherals
- * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
&cbass_mcu {
@@ -187,6 +187,8 @@
ranges = <0x79000000 0x00 0x79000000 0x8000>,
<0x79020000 0x00 0x79020000 0x8000>;
power-domains = <&k3_pds 7 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+
mcu_r5fss0_core0: r5f@79000000 {
compatible = "ti,am62-r5f";
reg = <0x79000000 0x00008000>,
diff --git a/arch/arm64/boot/dts/ti/k3-am62p-thermal.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-thermal.dtsi
index 85ce545633ea..c7486fb2a5b4 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-thermal.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-thermal.dtsi
@@ -1,4 +1,7 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
#include <dt-bindings/thermal/thermal.h>
diff --git a/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
index 19f42b39394e..a84756c336d0 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
@@ -1,7 +1,7 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree file for the AM62P wakeup domain peripherals
- * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
&cbass_wakeup {
@@ -78,6 +78,7 @@
ranges = <0x78000000 0x00 0x78000000 0x8000>,
<0x78100000 0x00 0x78100000 0x8000>;
power-domains = <&k3_pds 119 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
wkup_r5fss0_core0: r5f@78000000 {
compatible = "ti,am62-r5f";
diff --git a/arch/arm64/boot/dts/ti/k3-am62p.dtsi b/arch/arm64/boot/dts/ti/k3-am62p.dtsi
index 84ffe7b9dcaf..94babc412575 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p.dtsi
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for AM62P SoC Family
*
- * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
#include <dt-bindings/gpio/gpio.h>
@@ -71,7 +71,7 @@
<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 0x48000000 0x00 0x48000000 0x00 0x06408000>, /* DMSS */
<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-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
index 1773c05f752c..e86f34e835c1 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
@@ -1,7 +1,7 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree file for the AM62P5-SK
- * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
*
* Schematics: https://www.ti.com/lit/zip/sprr487
*/
@@ -413,6 +413,7 @@
status = "okay";
ti,driver-strength-ohm = <50>;
disable-wp;
+ bootph-all;
};
&sdhci1 {
@@ -422,9 +423,7 @@
vqmmc-supply = <&vddshv_sdio>;
pinctrl-names = "default";
pinctrl-0 = <&main_mmc1_pins_default>;
- ti,driver-strength-ohm = <50>;
disable-wp;
- no-1-8-v;
bootph-all;
};
@@ -445,6 +444,10 @@
};
&cpsw3g_mdio {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mdio1_pins_default>;
+ status = "okay";
+
cpsw3g_phy0: ethernet-phy@0 {
reg = <0>;
ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
diff --git a/arch/arm64/boot/dts/ti/k3-am62p5.dtsi b/arch/arm64/boot/dts/ti/k3-am62p5.dtsi
index 50147bb63e03..41f479dca455 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p5.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62p5.dtsi
@@ -1,7 +1,7 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree file for the AM62P5 SoC family (quad core)
- * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
*
* TRM: https://www.ti.com/lit/pdf/spruj83
*/
diff --git a/arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra-gpio-fan.dtso b/arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra-gpio-fan.dtso
new file mode 100644
index 000000000000..f0b2fd4165a7
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra-gpio-fan.dtso
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2024 PHYTEC America LLC
+ * Author: Garrett Giordano <ggiordano@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 40 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 = <
+ AM62X_IOPAD(0x0a4, PIN_OUTPUT, 7) /* (M22) GPMC0_DIR.GPIO0_40 */
+ >;
+ };
+};
+
+&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-am62x-sk-common.dtsi b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
index 33768c02d8eb..3c45782ab2b7 100644
--- a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Common dtsi for AM62x SK and derivatives
*
- * Copyright (C) 2021-2023 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2021-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
#include <dt-bindings/leds/common.h>
@@ -411,7 +411,6 @@
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&main_mmc0_pins_default>;
- ti,driver-strength-ohm = <50>;
disable-wp;
};
@@ -421,7 +420,6 @@
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&main_mmc1_pins_default>;
- ti,driver-strength-ohm = <50>;
disable-wp;
};
@@ -460,6 +458,7 @@
};
&usbss0 {
+ bootph-all;
status = "okay";
ti,vbus-divider;
};
@@ -470,6 +469,7 @@
};
&usb0 {
+ bootph-all;
#address-cells = <1>;
#size-cells = <0>;
usb-role-switch;
diff --git a/arch/arm64/boot/dts/ti/k3-am62x-sk-csi2-imx219.dtso b/arch/arm64/boot/dts/ti/k3-am62x-sk-csi2-imx219.dtso
index 6f4cd73c2f43..76ca02127f95 100644
--- a/arch/arm64/boot/dts/ti/k3-am62x-sk-csi2-imx219.dtso
+++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-csi2-imx219.dtso
@@ -1,7 +1,7 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* IMX219 (RPi v2) Camera Module
- * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
diff --git a/arch/arm64/boot/dts/ti/k3-am62x-sk-csi2-ov5640.dtso b/arch/arm64/boot/dts/ti/k3-am62x-sk-csi2-ov5640.dtso
index 9323a4b38389..ccc7f5e43184 100644
--- a/arch/arm64/boot/dts/ti/k3-am62x-sk-csi2-ov5640.dtso
+++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-csi2-ov5640.dtso
@@ -1,7 +1,7 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* ALINX AN5641 & Digilent PCam 5C - OV5640 camera module
- * Copyright (C) 2022-2023 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
diff --git a/arch/arm64/boot/dts/ti/k3-am62x-sk-csi2-tevi-ov5640.dtso b/arch/arm64/boot/dts/ti/k3-am62x-sk-csi2-tevi-ov5640.dtso
index dcaa33a4c8d3..4eaf9d757dd0 100644
--- a/arch/arm64/boot/dts/ti/k3-am62x-sk-csi2-tevi-ov5640.dtso
+++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-csi2-tevi-ov5640.dtso
@@ -1,7 +1,7 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Technexion TEVI-OV5640-*-RPI - OV5640 camera module
- * Copyright (C) 2022-2023 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
diff --git a/arch/arm64/boot/dts/ti/k3-am62x-sk-hdmi-audio.dtso b/arch/arm64/boot/dts/ti/k3-am62x-sk-hdmi-audio.dtso
index 43a0ddc123e5..18c3082f68e6 100644
--- a/arch/arm64/boot/dts/ti/k3-am62x-sk-hdmi-audio.dtso
+++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-hdmi-audio.dtso
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/**
* Audio playback via HDMI for AM625-SK and AM62-LP SK.
*
@@ -6,7 +6,7 @@
* AM625 SK: https://www.ti.com/tool/SK-AM62
* AM62-LP SK: https://www.ti.com/tool/SK-AM62-LP
*
- * Copyright (C) 2023 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
diff --git a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
index e348114f42e0..6f9aa5e02138 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for AM642 SoC Family Main Domain peripherals
*
- * Copyright (C) 2020-2021 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2020-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
#include <dt-bindings/phy/phy-cadence.h>
@@ -51,10 +51,11 @@
reg = <0x00000014 0x4>;
};
- serdes_ln_ctrl: mux-controller {
- compatible = "mmio-mux";
+ serdes_ln_ctrl: mux-controller@4080 {
+ compatible = "reg-mux";
+ reg = <0x4080 0x4>;
#mux-control-cells = <1>;
- mux-reg-masks = <0x4080 0x3>; /* SERDES0 lane0 select */
+ mux-reg-masks = <0x0 0x3>; /* SERDES0 lane0 select */
};
phy_gmii_sel: phy@4044 {
@@ -626,13 +627,18 @@
power-domains = <&k3_pds 57 TI_SCI_PD_EXCLUSIVE>;
clocks = <&k3_clks 57 0>, <&k3_clks 57 1>;
clock-names = "clk_ahb", "clk_xin";
+ bus-width = <8>;
mmc-ddr-1_8v;
mmc-hs200-1_8v;
+ ti,clkbuf-sel = <0x7>;
ti,trm-icp = <0x2>;
ti,otap-del-sel-legacy = <0x0>;
ti,otap-del-sel-mmc-hs = <0x0>;
ti,otap-del-sel-ddr52 = <0x6>;
ti,otap-del-sel-hs200 = <0x7>;
+ ti,itap-del-sel-legacy = <0x10>;
+ ti,itap-del-sel-mmc-hs = <0xa>;
+ ti,itap-del-sel-ddr52 = <0x3>;
status = "disabled";
};
@@ -643,15 +649,19 @@
power-domains = <&k3_pds 58 TI_SCI_PD_EXCLUSIVE>;
clocks = <&k3_clks 58 3>, <&k3_clks 58 4>;
clock-names = "clk_ahb", "clk_xin";
- ti,trm-icp = <0x2>;
+ bus-width = <4>;
+ ti,clkbuf-sel = <0x7>;
ti,otap-del-sel-legacy = <0x0>;
- ti,otap-del-sel-sd-hs = <0xf>;
+ ti,otap-del-sel-sd-hs = <0x0>;
ti,otap-del-sel-sdr12 = <0xf>;
ti,otap-del-sel-sdr25 = <0xf>;
ti,otap-del-sel-sdr50 = <0xc>;
ti,otap-del-sel-sdr104 = <0x6>;
ti,otap-del-sel-ddr50 = <0x9>;
- ti,clkbuf-sel = <0x7>;
+ 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";
};
@@ -1041,25 +1051,6 @@
status = "disabled";
};
- pcie0_ep: pcie-ep@f102000 {
- compatible = "ti,am64-pcie-ep", "ti,j721e-pcie-ep";
- reg = <0x00 0x0f102000 0x00 0x1000>,
- <0x00 0x0f100000 0x00 0x400>,
- <0x00 0x0d000000 0x00 0x00800000>,
- <0x00 0x68000000 0x00 0x08000000>;
- reg-names = "intd_cfg", "user_cfg", "reg", "mem";
- interrupt-names = "link_state";
- interrupts = <GIC_SPI 203 IRQ_TYPE_EDGE_RISING>;
- ti,syscon-pcie-ctrl = <&main_conf 0x4070>;
- max-link-speed = <2>;
- num-lanes = <1>;
- power-domains = <&k3_pds 114 TI_SCI_PD_EXCLUSIVE>;
- clocks = <&k3_clks 114 0>;
- clock-names = "fck";
- max-functions = /bits/ 8 <1>;
- status = "disabled";
- };
-
epwm0: pwm@23000000 {
compatible = "ti,am64-epwm", "ti,am3352-ehrpwm";
#pwm-cells = <3>;
@@ -1244,6 +1235,18 @@
};
};
+ icssg0_iep0: iep@2e000 {
+ compatible = "ti,am654-icss-iep";
+ reg = <0x2e000 0x1000>;
+ clocks = <&icssg0_iepclk_mux>;
+ };
+
+ icssg0_iep1: iep@2f000 {
+ compatible = "ti,am654-icss-iep";
+ reg = <0x2f000 0x1000>;
+ clocks = <&icssg0_iepclk_mux>;
+ };
+
icssg0_mii_rt: mii-rt@32000 {
compatible = "ti,pruss-mii", "syscon";
reg = <0x32000 0x100>;
@@ -1385,6 +1388,18 @@
};
};
+ icssg1_iep0: iep@2e000 {
+ compatible = "ti,am654-icss-iep";
+ reg = <0x2e000 0x1000>;
+ clocks = <&icssg1_iepclk_mux>;
+ };
+
+ icssg1_iep1: iep@2f000 {
+ compatible = "ti,am654-icss-iep";
+ reg = <0x2f000 0x1000>;
+ clocks = <&icssg1_iepclk_mux>;
+ };
+
icssg1_mii_rt: mii-rt@32000 {
compatible = "ti,pruss-mii", "syscon";
reg = <0x32000 0x100>;
diff --git a/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi
index b9508072bebb..ec17285869da 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for AM64 SoC Family MCU Domain peripherals
*
- * Copyright (C) 2020-2021 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2020-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
&cbass_mcu {
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 1678e74cb750..125e507966fb 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-phycore-som.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-phycore-som.dtsi
@@ -1,9 +1,9 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
- * Copyright (C) 2021 PHYTEC America, LLC - https://www.phytec.com
+ * Copyright (C) 2021-2024 PHYTEC America, LLC - https://www.phytec.com
* Author: Matt McKee <mmckee@phytec.com>
*
- * Copyright (C) 2022 PHYTEC Messtechnik GmbH
+ * Copyright (C) 2022-2024 PHYTEC Messtechnik GmbH
* Author: Wadim Egorov <w.egorov@phytec.de>
*
* Product homepage:
@@ -318,3 +318,10 @@
disable-wp;
keep-power-in-suspend;
};
+
+&tscadc0 {
+ status = "okay";
+ adc {
+ ti,adc-channels = <0 1 2 3 4 5 6 7>;
+ };
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am64-thermal.dtsi b/arch/arm64/boot/dts/ti/k3-am64-thermal.dtsi
index 036db56ba797..b1cd5542428c 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-thermal.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-thermal.dtsi
@@ -1,4 +1,7 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
#include <dt-bindings/thermal/thermal.h>
diff --git a/arch/arm64/boot/dts/ti/k3-am64.dtsi b/arch/arm64/boot/dts/ti/k3-am64.dtsi
index 0187c42aed4f..74e56cc68d46 100644
--- a/arch/arm64/boot/dts/ti/k3-am64.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64.dtsi
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for AM642 SoC Family
*
- * Copyright (C) 2020-2021 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2020-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
#include <dt-bindings/gpio/gpio.h>
diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso b/arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso
new file mode 100644
index 000000000000..af2fd3e7448b
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am642-evm-icssg1-dualemac.dtso
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/**
+ * DT overlay for enabling 2nd ICSSG1 port on AM642 EVM
+ *
+ * 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>;
+ tx-internal-delay-ps = <250>;
+ rx-internal-delay-ps = <2000>;
+ };
+ };
+ };
+};
+
+&main_pmx0 {
+ icssg1_rgmii2_pins_default: icssg1-rgmii2-default-pins {
+ pinctrl-single,pins = <
+ AM64X_IOPAD(0x0108, PIN_INPUT, 2) /* (W11) PRG1_PRU1_GPO0.RGMII2_RD0 */
+ AM64X_IOPAD(0x010c, PIN_INPUT, 2) /* (V11) PRG1_PRU1_GPO1.RGMII2_RD1 */
+ AM64X_IOPAD(0x0110, PIN_INPUT, 2) /* (AA12) PRG1_PRU1_GPO2.RGMII2_RD2 */
+ AM64X_IOPAD(0x0114, PIN_INPUT, 2) /* (Y12) PRG1_PRU1_GPO3.RGMII2_RD3 */
+ AM64X_IOPAD(0x0120, PIN_INPUT, 2) /* (U11) PRG1_PRU1_GPO6.RGMII2_RXC */
+ AM64X_IOPAD(0x0118, PIN_INPUT, 2) /* (W12) PRG1_PRU1_GPO4.RGMII2_RX_CTL */
+ AM64X_IOPAD(0x0134, PIN_OUTPUT, 2) /* (AA10) PRG1_PRU1_GPO11.RGMII2_TD0 */
+ AM64X_IOPAD(0x0138, PIN_OUTPUT, 2) /* (V10) PRG1_PRU1_GPO12.RGMII2_TD1 */
+ AM64X_IOPAD(0x013c, PIN_OUTPUT, 2) /* (U10) PRG1_PRU1_GPO13.RGMII2_TD2 */
+ AM64X_IOPAD(0x0140, PIN_OUTPUT, 2) /* (AA11) PRG1_PRU1_GPO14.RGMII2_TD3 */
+ AM64X_IOPAD(0x0148, PIN_OUTPUT, 2) /* (Y10) PRG1_PRU1_GPO16.RGMII2_TXC */
+ AM64X_IOPAD(0x0144, PIN_OUTPUT, 2) /* (Y11) PRG1_PRU1_GPO15.RGMII2_TX_CTL */
+ >;
+ };
+};
+
+&cpsw3g {
+ pinctrl-0 = <&rgmii1_pins_default>;
+};
+
+&cpsw_port2 {
+ status = "disabled";
+};
+
+&mdio_mux_1 {
+ status = "disabled";
+};
+
+&icssg1_eth {
+ pinctrl-0 = <&icssg1_rgmii1_pins_default>, <&icssg1_rgmii2_pins_default>;
+};
+
+&icssg1_emac1 {
+ status = "okay";
+ phy-handle = <&icssg1_phy2>;
+ phy-mode = "rgmii-id";
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am642-evm.dts b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
index 8c5651d2cf5d..53fe1d065ddb 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-evm.dts
@@ -1,6 +1,6 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
- * Copyright (C) 2020-2021 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2020-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
@@ -32,6 +32,7 @@
mmc1 = &sdhci1;
ethernet0 = &cpsw_port1;
ethernet1 = &cpsw_port2;
+ ethernet2 = &icssg1_emac0;
};
memory@80000000 {
@@ -198,7 +199,7 @@
mux-gpios = <&exp1 12 GPIO_ACTIVE_HIGH>;
};
- mdio-mux-1 {
+ mdio_mux_1: mdio-mux-1 {
compatible = "mdio-mux-multiplexer";
mux-controls = <&mdio_mux>;
mdio-parent-bus = <&cpsw3g_mdio>;
@@ -229,6 +230,64 @@
max-bitrate = <5000000>;
standby-gpios = <&exp1 9 GPIO_ACTIVE_HIGH>;
};
+
+ icssg1_eth: icssg1-eth {
+ compatible = "ti,am642-icssg-prueth";
+ pinctrl-names = "default";
+ pinctrl-0 = <&icssg1_rgmii1_pins_default>;
+ sram = <&oc_sram>;
+ ti,prus = <&pru1_0>, <&rtu1_0>, <&tx_pru1_0>, <&pru1_1>, <&rtu1_1>, <&tx_pru1_1>;
+ firmware-name = "ti-pruss/am64x-sr2-pru0-prueth-fw.elf",
+ "ti-pruss/am64x-sr2-rtu0-prueth-fw.elf",
+ "ti-pruss/am64x-sr2-txpru0-prueth-fw.elf",
+ "ti-pruss/am64x-sr2-pru1-prueth-fw.elf",
+ "ti-pruss/am64x-sr2-rtu1-prueth-fw.elf",
+ "ti-pruss/am64x-sr2-txpru1-prueth-fw.elf";
+
+ ti,pruss-gp-mux-sel = <2>, /* MII mode */
+ <2>,
+ <2>,
+ <2>, /* MII mode */
+ <2>,
+ <2>;
+ ti,mii-g-rt = <&icssg1_mii_g_rt>;
+ ti,mii-rt = <&icssg1_mii_rt>;
+ ti,iep = <&icssg1_iep0>, <&icssg1_iep1>;
+ interrupt-parent = <&icssg1_intc>;
+ interrupts = <24 0 2>, <25 1 3>;
+ interrupt-names = "tx_ts0", "tx_ts1";
+ dmas = <&main_pktdma 0xc200 15>, /* egress slice 0 */
+ <&main_pktdma 0xc201 15>, /* egress slice 0 */
+ <&main_pktdma 0xc202 15>, /* egress slice 0 */
+ <&main_pktdma 0xc203 15>, /* egress slice 0 */
+ <&main_pktdma 0xc204 15>, /* egress slice 1 */
+ <&main_pktdma 0xc205 15>, /* egress slice 1 */
+ <&main_pktdma 0xc206 15>, /* egress slice 1 */
+ <&main_pktdma 0xc207 15>, /* egress slice 1 */
+ <&main_pktdma 0x4200 15>, /* ingress slice 0 */
+ <&main_pktdma 0x4201 15>; /* ingress slice 1 */
+ dma-names = "tx0-0", "tx0-1", "tx0-2", "tx0-3",
+ "tx1-0", "tx1-1", "tx1-2", "tx1-3",
+ "rx0", "rx1";
+
+ ethernet-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ icssg1_emac0: port@0 {
+ reg = <0>;
+ phy-handle = <&icssg1_phy1>;
+ phy-mode = "rgmii-id";
+ /* Filled in by bootloader */
+ local-mac-address = [00 00 00 00 00 00];
+ };
+ icssg1_emac1: port@1 {
+ reg = <1>;
+ /* Filled in by bootloader */
+ local-mac-address = [00 00 00 00 00 00];
+ status = "disabled";
+ };
+ };
+ };
};
&main_pmx0 {
@@ -383,6 +442,30 @@
AM64X_IOPAD(0x0030, PIN_OUTPUT_PULLUP, 7) /* (L18) OSPI0_CSN1.GPIO0_12 */
>;
};
+
+ icssg1_mdio1_pins_default: icssg1-mdio1-default-pins {
+ pinctrl-single,pins = <
+ AM64X_IOPAD(0x015c, PIN_OUTPUT, 0) /* (Y6) PRG1_MDIO0_MDC */
+ AM64X_IOPAD(0x0158, PIN_INPUT, 0) /* (AA6) PRG1_MDIO0_MDIO */
+ >;
+ };
+
+ icssg1_rgmii1_pins_default: icssg1-rgmii1-default-pins{
+ pinctrl-single,pins = <
+ AM64X_IOPAD(0x00b8, PIN_INPUT, 2) /* (Y7) PRG1_PRU0_GPO0.PRG1_RGMII1_RD0 */
+ AM64X_IOPAD(0x00bc, PIN_INPUT, 2) /* (U8) PRG1_PRU0_GPO1.PRG1_RGMII1_RD1 */
+ AM64X_IOPAD(0x00c0, PIN_INPUT, 2) /* (W8) PRG1_PRU0_GPO2.PRG1_RGMII1_RD2 */
+ AM64X_IOPAD(0x00c4, PIN_INPUT, 2) /* (V8) PRG1_PRU0_GPO3.PRG1_RGMII1_RD3 */
+ AM64X_IOPAD(0x00d0, PIN_INPUT, 2) /* (AA7) PRG1_PRU0_GPO6.PRG1_RGMII1_RXC */
+ AM64X_IOPAD(0x00c8, PIN_INPUT, 2) /* (Y8) PRG1_PRU0_GPO4.PRG1_RGMII1_RX_CTL */
+ AM64X_IOPAD(0x00e4, PIN_INPUT, 2) /* (AA8) PRG1_PRU0_GPO11.PRG1_RGMII1_TD0 */
+ AM64X_IOPAD(0x00e8, PIN_INPUT, 2) /* (U9) PRG1_PRU0_GPO12.PRG1_RGMII1_TD1 */
+ AM64X_IOPAD(0x00ec, PIN_INPUT, 2) /* (W9) PRG1_PRU0_GPO13.PRG1_RGMII1_TD2 */
+ AM64X_IOPAD(0x00f0, PIN_INPUT, 2) /* (AA9) PRG1_PRU0_GPO14.PRG1_RGMII1_TD3 */
+ AM64X_IOPAD(0x00f8, PIN_INPUT, 2) /* (V9) PRG1_PRU0_GPO16.PRG1_RGMII1_TXC */
+ AM64X_IOPAD(0x00f4, PIN_INPUT, 2) /* (Y9) PRG1_PRU0_GPO15.PRG1_RGMII1_TX_CTL */
+ >;
+ };
};
&main_uart0 {
@@ -494,10 +577,10 @@
/* eMMC */
&sdhci0 {
status = "okay";
- bus-width = <8>;
non-removable;
ti,driver-strength-ohm = <50>;
disable-wp;
+ bootph-all;
};
/* SD/MMC */
@@ -506,9 +589,7 @@
status = "okay";
vmmc-supply = <&vdd_mmc1>;
pinctrl-names = "default";
- bus-width = <4>;
pinctrl-0 = <&main_mmc1_pins_default>;
- ti,driver-strength-ohm = <50>;
disable-wp;
};
@@ -660,25 +741,25 @@
};
&main_r5fss0_core0 {
- mboxes = <&mailbox0_cluster2>, <&mbox_main_r5fss0_core0>;
+ mboxes = <&mailbox0_cluster2 &mbox_main_r5fss0_core0>;
memory-region = <&main_r5fss0_core0_dma_memory_region>,
<&main_r5fss0_core0_memory_region>;
};
&main_r5fss0_core1 {
- mboxes = <&mailbox0_cluster2>, <&mbox_main_r5fss0_core1>;
+ mboxes = <&mailbox0_cluster2 &mbox_main_r5fss0_core1>;
memory-region = <&main_r5fss0_core1_dma_memory_region>,
<&main_r5fss0_core1_memory_region>;
};
&main_r5fss1_core0 {
- mboxes = <&mailbox0_cluster4>, <&mbox_main_r5fss1_core0>;
+ mboxes = <&mailbox0_cluster4 &mbox_main_r5fss1_core0>;
memory-region = <&main_r5fss1_core0_dma_memory_region>,
<&main_r5fss1_core0_memory_region>;
};
&main_r5fss1_core1 {
- mboxes = <&mailbox0_cluster4>, <&mbox_main_r5fss1_core1>;
+ mboxes = <&mailbox0_cluster4 &mbox_main_r5fss1_core1>;
memory-region = <&main_r5fss1_core1_dma_memory_region>,
<&main_r5fss1_core1_memory_region>;
};
@@ -705,12 +786,6 @@
num-lanes = <1>;
};
-&pcie0_ep {
- phys = <&serdes0_pcie_link>;
- phy-names = "pcie-phy";
- num-lanes = <1>;
-};
-
&ecap0 {
status = "okay";
/* PWM is available on Pin 1 of header J12 */
@@ -731,3 +806,15 @@
pinctrl-0 = <&main_mcan1_pins_default>;
phys = <&transceiver2>;
};
+
+&icssg1_mdio {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&icssg1_mdio1_pins_default>;
+
+ icssg1_phy1: ethernet-phy@f {
+ reg = <0xf>;
+ tx-internal-delay-ps = <250>;
+ rx-internal-delay-ps = <2000>;
+ };
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-pcie.dtso b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-pcie.dtso
new file mode 100644
index 000000000000..bd9a5caf20da
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-pcie.dtso
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Josua Mayer <josua@solid-run.com>
+ *
+ * Overlay for SolidRun AM642 HummingBoard-T to enable PCI-E.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/phy/phy.h>
+
+#include "k3-serdes.h"
+
+&pcie0_rc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie0_default_pins>;
+ reset-gpios = <&main_gpio1 15 GPIO_ACTIVE_HIGH>;
+ phys = <&serdes0_link>;
+ phy-names = "pcie-phy";
+ num-lanes = <1>;
+ status = "okay";
+};
+
+&serdes0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ serdes0_link: phy@0 {
+ reg = <0>;
+ cdns,num-lanes = <1>;
+ cdns,phy-type = <PHY_TYPE_PCIE>;
+ #phy-cells = <0>;
+ resets = <&serdes_wiz0 1>;
+ };
+};
+
+&serdes_ln_ctrl {
+ idle-states = <AM64_SERDES0_LANE0_PCIE0>;
+};
+
+&serdes_mux {
+ idle-state = <1>;
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-usb3.dtso b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-usb3.dtso
new file mode 100644
index 000000000000..ffcc3bd3c7bc
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t-usb3.dtso
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Josua Mayer <josua@solid-run.com>
+ *
+ * Overlay for SolidRun AM642 HummingBoard-T to enable USB-3.1.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/phy/phy.h>
+
+#include "k3-serdes.h"
+
+&serdes0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ serdes0_link: phy@0 {
+ reg = <0>;
+ cdns,num-lanes = <1>;
+ cdns,phy-type = <PHY_TYPE_USB3>;
+ #phy-cells = <0>;
+ resets = <&serdes_wiz0 1>;
+ };
+};
+
+&serdes_ln_ctrl {
+ idle-states = <AM64_SERDES0_LANE0_USB>;
+};
+
+&serdes_mux {
+ idle-state = <0>;
+};
+
+&usbss0 {
+ /delete-property/ ti,usb2-only;
+};
+
+&usb0 {
+ maximum-speed = "super-speed";
+ phys = <&serdes0_link>;
+ phy-names = "cdns3,usb3-phy";
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts
new file mode 100644
index 000000000000..234d76e4e944
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am642-hummingboard-t.dts
@@ -0,0 +1,292 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Josua Mayer <josua@solid-run.com>
+ *
+ * DTS for SolidRun AM642 HummingBoard-T,
+ * running on Cortex A53.
+ *
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/phy/phy.h>
+
+#include "k3-am642.dtsi"
+#include "k3-am642-sr-som.dtsi"
+
+/ {
+ model = "SolidRun AM642 HummingBoard-T";
+ compatible = "solidrun,am642-hummingboard-t", "solidrun,am642-sr-som", "ti,am642";
+
+ aliases {
+ serial5 = &main_uart3;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&leds_default_pins>;
+
+ /* D24 */
+ led1: led-1 {
+ label = "led1";
+ gpios = <&main_gpio0 29 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_GREEN>;
+ };
+
+ /* D25 */
+ led2: led-2 {
+ label = "led2";
+ gpios = <&main_gpio0 30 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_GREEN>;
+ };
+
+ /* D26 */
+ led3: led-3 {
+ label = "led3";
+ gpios = <&main_gpio0 33 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_GREEN>;
+ };
+ };
+
+ regulator-m2-3v3 {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&regulator_pcie_3v3_default_pins>;
+ regulator-name = "m2-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&main_gpio1 17 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-always-on;
+ };
+
+ regulator-vpp-1v8 {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&regulator_vpp_1v8_default_pins>;
+ regulator-name = "vpp-1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ gpio = <&main_gpio1 78 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ serdes_mux: mux-controller {
+ compatible = "gpio-mux";
+ pinctrl-names = "default";
+ pinctrl-0 = <&serdes_mux_default_pins>;
+ #mux-control-cells = <0>;
+ /*
+ * Mux has 2 IOs:
+ * - select: 0 = USB-3 (M2); 1 = PCIE (M1)
+ * - shutdown: 0 = active; 1 = disabled (high impedance)
+ */
+ mux-gpios = <&main_gpio1 40 GPIO_ACTIVE_HIGH>, <&main_gpio1 41 GPIO_ACTIVE_HIGH>;
+ /* default disabled */
+ idle-state = <2>;
+ };
+};
+
+&main_gpio0 {
+ m2-reset-hog {
+ gpio-hog;
+ gpios = <12 GPIO_ACTIVE_LOW>;
+ output-low; /* deasserted */
+ line-name = "m2-reset";
+ };
+
+ m1-m2-w-disable1-hog {
+ gpio-hog;
+ gpios = <32 GPIO_ACTIVE_LOW>;
+ output-low; /* deasserted */
+ line-name = "m1-m2-pcie-w-disable1";
+ };
+
+ m1-m2-w-disable2-hog {
+ gpio-hog;
+ gpios = <34 GPIO_ACTIVE_LOW>;
+ output-low; /* deasserted */
+ line-name = "m1-m2-pcie-w-disable2";
+ };
+};
+
+&main_gpio1 {
+ m1-pcie-clkreq0-hog {
+ gpio-hog;
+ gpios = <11 GPIO_ACTIVE_LOW>;
+ input;
+ line-name = "m1-pcie-clkreq0";
+ };
+
+ m2-pcie-clkreq-hog {
+ gpio-hog;
+ gpios = <35 GPIO_ACTIVE_LOW>;
+ input;
+ line-name = "m2-pcie-clkreq";
+ };
+};
+
+&main_i2c0 {
+ pinctrl-0 = <&main_i2c0_default_pins>, <&main_i2c0_int_default_pins>;
+
+ humidity-sensor@41 {
+ compatible = "ti,hdc2010";
+ reg = <0x41>;
+ interrupt-parent = <&main_gpio0>;
+ interrupts = <37 IRQ_TYPE_EDGE_FALLING>;
+ };
+
+ light-sensor@44 {
+ compatible = "ti,opt3001";
+ reg = <0x44>;
+ interrupt-parent = <&main_gpio0>;
+ interrupts = <37 IRQ_TYPE_EDGE_FALLING>;
+ };
+
+ /* charger@6a */
+};
+
+&main_i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_i2c1_default_pins>;
+ status = "okay";
+
+ rtc@69 {
+ compatible = "abracon,abx80x";
+ reg = <0x69>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&rtc_int_default_pins>;
+ abracon,tc-diode = "schottky";
+ abracon,tc-resistor = <3>;
+ interrupt-parent = <&main_gpio0>;
+ interrupts = <44 IRQ_TYPE_EDGE_FALLING>;
+ };
+};
+
+&main_mcan0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mcan0_default_pins>;
+ status = "okay";
+
+ can-transceiver {
+ max-bitrate = <8000000>;
+ };
+};
+
+&main_mcan1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mcan1_default_pins>;
+ status = "okay";
+
+ can-transceiver {
+ max-bitrate = <8000000>;
+ };
+};
+
+&main_pmx0 {
+ leds_default_pins: leds-default-pins {
+ pinctrl-single,pins = <
+ AM64X_IOPAD(0x0074, PIN_OUTPUT, 7) /* GPMC0_AD14.GPIO0_29 */
+ AM64X_IOPAD(0x0078, PIN_OUTPUT, 7) /* GPMC0_AD15.GPIO0_30 */
+ AM64X_IOPAD(0x0088, PIN_OUTPUT, 7) /* GPMC0_OEn_REn.GPIO0_33 */
+ >;
+ };
+
+ main_i2c0_int_default_pins: main-i2c0-int-default-pins {
+ pinctrl-single,pins = <
+ /* external pull-up on Carrier */
+ AM64X_IOPAD(0x0098, PIN_INPUT, 7) /* GPMC0_WAIT0.GPIO0_37 */
+ >;
+ };
+
+ main_i2c1_default_pins: main-i2c1-default-pins {
+ pinctrl-single,pins = <
+ /* external pull-up on SoM */
+ AM64X_IOPAD(0x0268, PIN_INPUT, 0) /* I2C1_SCL.I2C1_SCL */
+ AM64X_IOPAD(0x026c, PIN_INPUT, 0) /* I2C1_SDA.I2C1_SDA */
+ >;
+ };
+
+ main_mcan0_default_pins: main-mcan0-default-pins {
+ pinctrl-single,pins = <
+ AM64X_IOPAD(0x0254, PIN_INPUT, 0) /* MCAN0_RX.MCAN0_RX */
+ AM64X_IOPAD(0x0250, PIN_OUTPUT, 0) /* MCAN0_TX.MCAN0_TX */
+ >;
+ };
+
+ main_mcan1_default_pins: main-mcan1-default-pins {
+ pinctrl-single,pins = <
+ AM64X_IOPAD(0x025c, PIN_INPUT, 0) /* MCAN1_RX.MCAN1_RX */
+ AM64X_IOPAD(0x0258, PIN_OUTPUT, 0) /* MCAN1_TX.MCAN1_TX */
+ >;
+ };
+
+ main_uart3_default_pins: main-uart3-default-pins {
+ pinctrl-single,pins = <
+ AM64X_IOPAD(0x016c, PIN_INPUT, 10) /* PRG0_PRU0_GPO3.UART3_CTSn */
+ AM64X_IOPAD(0x0170, PIN_OUTPUT, 10) /* PRG0_PRU0_GPO4.UART3_TXD */
+ AM64X_IOPAD(0x0174, PIN_OUTPUT, 10) /* PRG0_PRU0_GPO5.UART3_RTSn */
+ AM64X_IOPAD(0x01ac, PIN_INPUT, 10) /* PRG0_PRU0_GPO19.UART3_RXD */
+ >;
+ };
+
+ pcie0_default_pins: pcie0-default-pins {
+ pinctrl-single,pins = <
+ /* connector M2 RESET */
+ AM64X_IOPAD(0x0030, PIN_OUTPUT, 7) /* OSPI0_CSn1.GPIO0_12 */
+ /* connectors M1 & M2 W_DISABLE1 */
+ AM64X_IOPAD(0x0084, PIN_OUTPUT, 7) /* GPMC0_ADVN_ALE.GPIO0_32 */
+ /* connectors M1 & M2 W_DISABLE2 */
+ AM64X_IOPAD(0x008c, PIN_OUTPUT, 7) /* GPMC0_WEN.GPIO0_34 */
+ /* connectors M1 & M2 PERST0 (PCI Reset) */
+ AM64X_IOPAD(0x019c, PIN_OUTPUT, 7) /* PRG0_PRU0_GPO15.GPIO1_15 */
+ /* connector M1 CLKREQ0 */
+ AM64X_IOPAD(0x018c, PIN_INPUT, 7) /* PRG0_PRU0_GPO11.GPIO1_11 */
+ /* connector M2 CLKREQ0 */
+ AM64X_IOPAD(0x01ec, PIN_INPUT, 7) /* PRG0_PRU1_GPO15.GPIO1_35 */
+ >;
+ };
+
+ regulator_pcie_3v3_default_pins: regulator-pcie-3v3-default-pins {
+ pinctrl-single,pins = <
+ AM64X_IOPAD(0x01a4, PIN_OUTPUT, 7) /* PRG0_PRU0_GPO17.GPIO1_17 */
+ >;
+ };
+
+ regulator_vpp_1v8_default_pins: regulator-vpp-1v8-default-pins {
+ pinctrl-single,pins = <
+ AM64X_IOPAD(0x029c, PIN_OUTPUT, 7) /* MMC1_SDWP.GPIO1_78 */
+ >;
+ };
+
+ rtc_int_default_pins: rtc-int-default-pins {
+ pinctrl-single,pins = <
+ /* external pull-up on Carrier */
+ AM64X_IOPAD(0x00b4, PIN_INPUT, 7) /* GPMC0_CSn3.GPIO0_44 */
+ >;
+ };
+
+ serdes_mux_default_pins: serdes-mux-default-pins {
+ pinctrl-single,pins = <
+ /* SEL, 10k pull-down on carrier, 2.2k pullup on SoM */
+ AM64X_IOPAD(0x0200, PIN_OUTPUT, 7) /* PRG0_MDIO0_MDIO.GPIO1_40 */
+ /* EN */
+ AM64X_IOPAD(0x0204, PIN_OUTPUT, 7) /* PRG0_MDIO0_MDC.GPIO1_41 */
+ >;
+ };
+};
+
+&main_uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_uart3_default_pins>;
+ uart-has-rtscts;
+ rs485-rts-active-low;
+ linux,rs485-enabled-at-boot-time;
+ status = "okay";
+};
+
+&usb0 {
+ dr_mode = "host";
+};
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 53b64e55413f..8237b8c815b8 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
@@ -1,9 +1,9 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
- * Copyright (C) 2021 PHYTEC America, LLC - https://www.phytec.com
+ * Copyright (C) 2021-2024 PHYTEC America, LLC - https://www.phytec.com
* Author: Matt McKee <mmckee@phytec.com>
*
- * Copyright (C) 2022 PHYTEC Messtechnik GmbH
+ * Copyright (C) 2022-2024 PHYTEC Messtechnik GmbH
* Author: Wadim Egorov <w.egorov@phytec.de>
*
* Product homepage:
@@ -159,6 +159,15 @@
>;
};
+ main_spi0_pins_default: main-spi0-default-pins {
+ pinctrl-single,pins = <
+ AM64X_IOPAD(0x020c, PIN_OUTPUT, 7) /* (C13) SPI0_CS1.GPIO1_43 */
+ AM64X_IOPAD(0x0210, PIN_INPUT, 0) /* (D13) SPI0_CLK */
+ AM64X_IOPAD(0x0214, PIN_OUTPUT, 0) /* (A13) SPI0_D0 */
+ AM64X_IOPAD(0x0218, PIN_INPUT, 0) /* (A14) SPI0_D1 */
+ >;
+ };
+
main_uart0_pins_default: main-uart0-default-pins {
pinctrl-single,pins = <
AM64X_IOPAD(0x0230, PIN_INPUT, 0) /* (D15) UART0_RXD */
@@ -248,6 +257,20 @@
phys = <&can_tc2>;
};
+&main_spi0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_spi0_pins_default>;
+ cs-gpios = <0>, <&main_gpio1 43 GPIO_ACTIVE_LOW>;
+ ti,pindir-d0-out-d1-in;
+
+ tpm@1 {
+ compatible = "infineon,slb9670", "tcg,tpm_tis-spi";
+ reg = <1>;
+ spi-max-frequency = <10000000>;
+ };
+};
+
&main_uart0 {
status = "okay";
pinctrl-names = "default";
@@ -269,7 +292,6 @@
pinctrl-names = "default";
pinctrl-0 = <&main_mmc1_pins_default>;
bus-width = <4>;
- ti,driver-strength-ohm = <50>;
disable-wp;
no-1-8-v;
};
diff --git a/arch/arm64/boot/dts/ti/k3-am642-sk.dts b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
index 1dddd6fc1a0d..67cd41bf806e 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-sk.dts
@@ -1,6 +1,6 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
- * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
@@ -469,9 +469,7 @@
status = "okay";
vmmc-supply = <&vdd_mmc1>;
pinctrl-names = "default";
- bus-width = <4>;
pinctrl-0 = <&main_mmc1_pins_default>;
- ti,driver-strength-ohm = <50>;
disable-wp;
};
@@ -646,25 +644,25 @@
};
&main_r5fss0_core0 {
- mboxes = <&mailbox0_cluster2>, <&mbox_main_r5fss0_core0>;
+ mboxes = <&mailbox0_cluster2 &mbox_main_r5fss0_core0>;
memory-region = <&main_r5fss0_core0_dma_memory_region>,
<&main_r5fss0_core0_memory_region>;
};
&main_r5fss0_core1 {
- mboxes = <&mailbox0_cluster2>, <&mbox_main_r5fss0_core1>;
+ mboxes = <&mailbox0_cluster2 &mbox_main_r5fss0_core1>;
memory-region = <&main_r5fss0_core1_dma_memory_region>,
<&main_r5fss0_core1_memory_region>;
};
&main_r5fss1_core0 {
- mboxes = <&mailbox0_cluster4>, <&mbox_main_r5fss1_core0>;
+ mboxes = <&mailbox0_cluster4 &mbox_main_r5fss1_core0>;
memory-region = <&main_r5fss1_core0_dma_memory_region>,
<&main_r5fss1_core0_memory_region>;
};
&main_r5fss1_core1 {
- mboxes = <&mailbox0_cluster4>, <&mbox_main_r5fss1_core1>;
+ mboxes = <&mailbox0_cluster4 &mbox_main_r5fss1_core1>;
memory-region = <&main_r5fss1_core1_dma_memory_region>,
<&main_r5fss1_core1_memory_region>;
};
diff --git a/arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi b/arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi
new file mode 100644
index 000000000000..c19d0b8bbf0f
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am642-sr-som.dtsi
@@ -0,0 +1,594 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2023 Josua Mayer <josua@solid-run.com>
+ *
+ */
+
+#include <dt-bindings/net/ti-dp83869.h>
+
+/ {
+ model = "SolidRun AM642 SoM";
+ compatible = "solidrun,am642-sr-som", "ti,am642";
+
+ aliases {
+ ethernet0 = &cpsw_port1;
+ ethernet1 = &icssg1_emac0;
+ ethernet2 = &icssg1_emac1;
+ mmc0 = &sdhci0;
+ mmc1 = &sdhci1;
+ serial2 = &main_uart0;
+ };
+
+ chosen {
+ /* SoC default UART console */
+ stdout-path = "serial2:115200n8";
+ };
+
+ /* PRU Ethernet Controller */
+ ethernet {
+ compatible = "ti,am642-icssg-prueth";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pru_rgmii1_default_pins>, <&pru_rgmii2_default_pins>;
+
+ sram = <&oc_sram>;
+ ti,prus = <&pru1_0>, <&rtu1_0>, <&tx_pru1_0>, <&pru1_1>, <&rtu1_1>, <&tx_pru1_1>;
+ firmware-name = "ti-pruss/am65x-sr2-pru0-prueth-fw.elf",
+ "ti-pruss/am65x-sr2-rtu0-prueth-fw.elf",
+ "ti-pruss/am65x-sr2-txpru0-prueth-fw.elf",
+ "ti-pruss/am65x-sr2-pru1-prueth-fw.elf",
+ "ti-pruss/am65x-sr2-rtu1-prueth-fw.elf",
+ "ti-pruss/am65x-sr2-txpru1-prueth-fw.elf";
+
+ /* configure internal pinmux for mii mode */
+ ti,pruss-gp-mux-sel = <2>, <2>, <2>, <2>, <2>, <2>;
+
+ ti,mii-g-rt = <&icssg1_mii_g_rt>;
+ ti,mii-rt = <&icssg1_mii_rt>;
+ ti,iep = <&icssg1_iep0>, <&icssg1_iep1>;
+
+ /*
+ * Configure icssg interrupt controller to map pru-internal
+ * interrupts 8/9 via channels 0/1 to host interrupts 0/1.
+ *
+ * For details see interrupt controller documentation:
+ * Documentation/devicetree/bindings/interrupt-controller/ti,pruss-intc.yaml
+ */
+ interrupt-parent = <&icssg1_intc>;
+ interrupts = <24 0 2>, <25 1 3>;
+ interrupt-names = "tx_ts0", "tx_ts1";
+
+ dmas = <&main_pktdma 0xc200 15>, /* egress slice 0 */
+ <&main_pktdma 0xc201 15>, /* egress slice 0 */
+ <&main_pktdma 0xc202 15>, /* egress slice 0 */
+ <&main_pktdma 0xc203 15>, /* egress slice 0 */
+ <&main_pktdma 0xc204 15>, /* egress slice 1 */
+ <&main_pktdma 0xc205 15>, /* egress slice 1 */
+ <&main_pktdma 0xc206 15>, /* egress slice 1 */
+ <&main_pktdma 0xc207 15>, /* egress slice 1 */
+ <&main_pktdma 0x4200 15>, /* ingress slice 0 */
+ <&main_pktdma 0x4201 15>; /* ingress slice 1 */
+ dma-names = "tx0-0", "tx0-1", "tx0-2", "tx0-3",
+ "tx1-0", "tx1-1", "tx1-2", "tx1-3",
+ "rx0", "rx1";
+
+ ethernet-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ icssg1_emac0: port@0 {
+ reg = <0>;
+ ti,syscon-rgmii-delay = <&main_conf 0x4110>;
+ /* Filled in by bootloader */
+ local-mac-address = [00 00 00 00 00 00];
+ phy-handle = <&ethernet_phy2>;
+ phy-mode = "rgmii-id";
+ };
+
+ icssg1_emac1: port@1 {
+ reg = <1>;
+ ti,syscon-rgmii-delay = <&main_conf 0x4114>;
+ /* Filled in by bootloader */
+ local-mac-address = [00 00 00 00 00 00];
+ phy-handle = <&ethernet_phy1>;
+ phy-mode = "rgmii-id";
+ };
+ };
+ };
+
+ /* DDR16SS0:
+ * - Bank 1 @ 0x080000000-0x0FFFFFFFF: max. 2GB in 32-bit address space
+ * - Bank 2 @ 0x880000000-0x9FFFFFFFF: max. 6GB in 64-bit address space
+ */
+ memory@80000000 {
+ reg = <0x00000000 0x80000000 0x00000000 0x80000000>,
+ <0x00000008 0x80000000 0x00000001 0x80000000>;
+ device_type = "memory";
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ secure_ddr: optee@9e800000 {
+ reg = <0x00 0x9e800000 0x00 0x01800000>; /* for OP-TEE */
+ no-map;
+ };
+
+ main_r5fss0_core0_dma_memory_region: r5f-dma-memory@a0000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa0000000 0x00 0x100000>;
+ no-map;
+ };
+
+ main_r5fss0_core0_memory_region: r5f-memory@a0100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa0100000 0x00 0xf00000>;
+ no-map;
+ };
+
+ main_r5fss0_core1_dma_memory_region: r5f-dma-memory@a1000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa1000000 0x00 0x100000>;
+ no-map;
+ };
+
+ main_r5fss0_core1_memory_region: r5f-memory@a1100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa1100000 0x00 0xf00000>;
+ no-map;
+ };
+
+ main_r5fss1_core0_dma_memory_region: r5f-dma-memory@a2000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa2000000 0x00 0x100000>;
+ no-map;
+ };
+
+ main_r5fss1_core0_memory_region: r5f-memory@a2100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa2100000 0x00 0xf00000>;
+ no-map;
+ };
+
+ main_r5fss1_core1_dma_memory_region: r5f-dma-memory@a3000000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa3000000 0x00 0x100000>;
+ no-map;
+ };
+
+ main_r5fss1_core1_memory_region: r5f-memory@a3100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa3100000 0x00 0xf00000>;
+ no-map;
+ };
+ };
+
+ vdd_mmc0: regulator-vdd-mmc0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd-mmc0";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+};
+
+&cpsw3g {
+ pinctrl-names = "default";
+ pinctrl-0 = <&rgmii1_default_pins>;
+};
+
+&cpsw3g_mdio {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mdio0_default_pins>;
+ status = "okay";
+
+ ethernet_phy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-id2000.a0f1";
+ reg = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ethernet_phy0_default_pins>;
+ ti,clk-output-sel = <DP83869_CLK_O_SEL_REF_CLK>;
+ ti,op-mode = <DP83869_RGMII_COPPER_ETHERNET>;
+ /*
+ * Disable interrupts because ISR never clears 0x0040
+ *
+ * interrupt-parent = <&main_gpio1>;
+ * interrupts = <70 IRQ_TYPE_LEVEL_LOW>;
+ */
+ /*
+ * Disable HW Reset because clock signal is daisy-chained
+ *
+ * reset-gpios = <&main_gpio0 84 GPIO_ACTIVE_LOW>;
+ * reset-assert-us = <1>;
+ * reset-deassert-us = <30>;
+ */
+ };
+};
+
+&cpsw_port1 {
+ phy-mode = "rgmii-id";
+ phy-handle = <&ethernet_phy0>;
+};
+
+&cpsw_port2 {
+ status = "disabled";
+};
+
+&icssg1_mdio {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pru1_mdio0_default_pins>;
+ status = "okay";
+
+ ethernet_phy1: ethernet-phy@3 {
+ compatible = "ethernet-phy-id2000.a0f1";
+ reg = <3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ethernet_phy1_default_pins>;
+ ti,clk-output-sel = <DP83869_CLK_O_SEL_REF_CLK>;
+ ti,op-mode = <DP83869_RGMII_COPPER_ETHERNET>;
+ /*
+ * Disable interrupts because ISR never clears 0x0040
+ *
+ * interrupt-parent = <&main_gpio1>;
+ * interrupts = <70 IRQ_TYPE_LEVEL_LOW>;
+ */
+ /*
+ * Disable HW Reset because clock signal is daisy-chained
+ *
+ * reset-gpios = <&main_gpio0 20 GPIO_ACTIVE_LOW>;
+ * reset-assert-us = <1>;
+ * reset-deassert-us = <30>;
+ */
+ };
+
+ ethernet_phy2: ethernet-phy@f {
+ compatible = "ethernet-phy-id2000.a0f1";
+ reg = <0xf>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ethernet_phy2_default_pins>;
+ ti,op-mode = <DP83869_RGMII_COPPER_ETHERNET>;
+ /*
+ * Disable interrupts because ISR never clears 0x0040
+ *
+ * interrupt-parent = <&main_gpio1>;
+ * interrupts = <70 IRQ_TYPE_LEVEL_LOW>;
+ */
+ /*
+ * Disable HW Reset because clock signal is daisy-chained
+ *
+ * reset-gpios = <&main_gpio0 52 GPIO_ACTIVE_LOW>;
+ * reset-assert-us = <1>;
+ * reset-deassert-us = <30>;
+ */
+ };
+};
+
+&mailbox0_cluster2 {
+ status = "okay";
+
+ mbox_main_r5fss0_core0: mbox-main-r5fss0-core0 {
+ ti,mbox-rx = <0 0 2>;
+ ti,mbox-tx = <1 0 2>;
+ };
+
+ mbox_main_r5fss0_core1: mbox-main-r5fss0-core1 {
+ ti,mbox-rx = <2 0 2>;
+ ti,mbox-tx = <3 0 2>;
+ };
+};
+
+&mailbox0_cluster4 {
+ status = "okay";
+
+ mbox_main_r5fss1_core0: mbox-main-r5fss1-core0 {
+ ti,mbox-rx = <0 0 2>;
+ ti,mbox-tx = <1 0 2>;
+ };
+
+ mbox_main_r5fss1_core1: mbox-main-r5fss1-core1 {
+ ti,mbox-rx = <2 0 2>;
+ ti,mbox-tx = <3 0 2>;
+ };
+};
+
+&main_i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_i2c0_default_pins>;
+ status = "okay";
+
+ som_eeprom: eeprom@50 {
+ compatible = "atmel,24c01";
+ reg = <0x50>;
+ pagesize = <8>;
+ };
+};
+
+&main_pmx0 {
+ /* hog global functions */
+ pinctrl-names = "default";
+ pinctrl-0 = <&ethernet_phy_default_pins>;
+
+ ethernet_phy_default_pins: ethernet-phy-default-pins {
+ pinctrl-single,pins = <
+ /* interrupt / power-down, external pull-up on SoM */
+ AM64X_IOPAD(0x0278, PIN_INPUT, 7) /* EXTINTn.GPIO1_70 */
+ >;
+ };
+
+ ethernet_phy0_default_pins: ethernet-phy0-default-pins {
+ pinctrl-single,pins = <
+ /* reset */
+ AM64X_IOPAD(0x0154, PIN_OUTPUT, 7) /* PRG1_PRU1_GPO19.GPIO0_84 */
+ /* reference clock */
+ AM64X_IOPAD(0x0274, PIN_OUTPUT, 5) /* EXT_REFCLK1.CLKOUT0 */
+ >;
+ };
+
+ ethernet_phy1_default_pins: ethernet-phy1-default-pins {
+ pinctrl-single,pins = <
+ /* reset */
+ AM64X_IOPAD(0x0150, PIN_OUTPUT, 7) /* PRG1_PRU1_GPO18.GPIO0_20 */
+ /* led0, external pull-down on SoM */
+ AM64X_IOPAD(0x0128, PIN_INPUT, 7) /* PRG1_PRU1_GPO8.GPIO0_73 */
+ /* led1/rxer */
+ AM64X_IOPAD(0x011c, PIN_INPUT, 7) /* PRG1_PRU1_GPO5.GPIO0_70 */
+ >;
+ };
+
+ ethernet_phy2_default_pins: ethernet-phy2-default-pins {
+ pinctrl-single,pins = <
+ /* reset */
+ AM64X_IOPAD(0x00d4, PIN_OUTPUT, 7) /* PRG1_PRU0_GPO7.GPIO0_52 */
+ /* led0, external pull-down on SoM */
+ AM64X_IOPAD(0x00d8, PIN_INPUT, 7) /* PRG1_PRU0_GPO8.GPIO0_53 */
+ /* led1/rxer */
+ AM64X_IOPAD(0x00cc, PIN_INPUT, 7) /* PRG1_PRU0_GPO5.GPIO0_50 */
+ >;
+ };
+
+ main_i2c0_default_pins: main-i2c0-default-pins {
+ pinctrl-single,pins = <
+ /* external pull-up on SoM */
+ AM64X_IOPAD(0x0260, PIN_INPUT, 0) /* I2C0_SCL.I2C0_SCL */
+ AM64X_IOPAD(0x0264, PIN_INPUT, 0) /* I2C0_SDA.I2C0_SDA */
+ >;
+ };
+
+ /*
+ * main_mmc0_default_pins: main-mmc0-default-pins
+ *
+ * MMC0_CMD: no padconfig
+ * MMC0_CLK: no padconfig, external pull-up on SoM
+ * MMC0_DAT0: no padconfig
+ * MMC0_DAT1: no padconfig
+ * MMC0_DAT2: no padconfig
+ * MMC0_DAT3: no padconfig
+ * MMC0_DAT4: no padconfig
+ * MMC0_DAT5: no padconfig
+ * MMC0_DAT6: no padconfig
+ * MMC0_DAT7: no padconfig
+ * MMC0_DS: no padconfig, external pull-down on SoM
+ */
+
+ main_mmc1_default_pins: main-mmc1-default-pins {
+ pinctrl-single,pins = <
+ AM64X_IOPAD(0x0294, PIN_INPUT_PULLUP, 0) /* (J19) MMC1_CMD */
+ AM64X_IOPAD(0x028c, PIN_INPUT, 0) /* MMC1_CLK.MMC1_CLK */
+ AM64X_IOPAD(0x0288, PIN_INPUT_PULLUP, 0) /* MMC1_DAT0.MMC1_DAT0 */
+ AM64X_IOPAD(0x0284, PIN_INPUT_PULLUP, 0) /* MMC1_DAT1.MMC1_DAT1 */
+ AM64X_IOPAD(0x0280, PIN_INPUT_PULLUP, 0) /* MMC1_DAT2.MMC1_DAT2 */
+ AM64X_IOPAD(0x027c, PIN_INPUT_PULLUP, 0) /* MMC1_DAT3.MMC1_DAT3 */
+ /* external pull-down on SoM & Carrier */
+ AM64X_IOPAD(0x0298, PIN_INPUT_PULLUP, 0) /* MMC1_SDCD.MMC1_SDCD */
+ AM64X_IOPAD(0x0290, PIN_INPUT, 0) /* MMC1_CLKLB: clock loopback */
+ >;
+ };
+
+ main_uart0_default_pins: main-uart0-default-pins {
+ pinctrl-single,pins = <
+ AM64X_IOPAD(0x0230, PIN_INPUT, 0) /* UART0_RXD.UART0_RXD */
+ AM64X_IOPAD(0x0234, PIN_OUTPUT, 0) /* UART0_TXD.UART0_TXD */
+ >;
+ };
+
+ mdio0_default_pins: mdio0-default-pins {
+ pinctrl-single,pins = <
+ AM64X_IOPAD(0x01fc, PIN_OUTPUT, 4) /* PRG0_PRU1_GPO19.MDIO0_MDC */
+ AM64X_IOPAD(0x01f8, PIN_INPUT, 4) /* PRG0_PRU1_GPO18.MDIO0_MDIO */
+ >;
+ };
+
+ ospi0_default_pins: ospi0-default-pins {
+ pinctrl-single,pins = <
+ /* external pull-down on SoM */
+ AM64X_IOPAD(0x0000, PIN_OUTPUT, 0) /* OSPI0_CLK.OSPI0_CLK */
+ AM64X_IOPAD(0x0008, PIN_OUTPUT, 0) /* OSPI0_DQS.OSPI0_DQS */
+ /* external pull-up on SoM */
+ AM64X_IOPAD(0x002c, PIN_OUTPUT, 0) /* OSPI0_CSn0.OSPI0_CSn0 */
+ AM64X_IOPAD(0x000c, PIN_INPUT, 0) /* OSPI0_D0.OSPI0_D0 */
+ AM64X_IOPAD(0x0010, PIN_INPUT, 0) /* OSPI0_D1.OSPI0_D1 */
+ AM64X_IOPAD(0x0014, PIN_INPUT, 0) /* OSPI0_D2.OSPI0_D2 */
+ AM64X_IOPAD(0x0018, PIN_INPUT, 0) /* OSPI0_D3.OSPI0_D3 */
+ AM64X_IOPAD(0x001c, PIN_INPUT, 0) /* OSPI0_D4.OSPI0_D4 */
+ AM64X_IOPAD(0x0020, PIN_INPUT, 0) /* OSPI0_D5.OSPI0_D5 */
+ AM64X_IOPAD(0x0024, PIN_INPUT, 0) /* OSPI0_D6.OSPI0_D6 */
+ AM64X_IOPAD(0x0028, PIN_INPUT, 0) /* OSPI0_D7.OSPI0_D7 */
+ >;
+ };
+
+ ospi0_flash0_default_pins: ospi0-flash0-default-pins {
+ pinctrl-single,pins = <
+ AM64X_IOPAD(0x0034, PIN_OUTPUT, 7) /* OSPI0_CSn2.GPIO0_13 */
+ AM64X_IOPAD(0x0038, PIN_INPUT, 7) /* OSPI0_CSn3.GPIO0_14 */
+ >;
+ };
+
+ pru1_mdio0_default_pins: pru1-mdio0-default-pins {
+ pinctrl-single,pins = <
+ AM64X_IOPAD(0x015c, PIN_OUTPUT, 0) /* PRG1_MDIO0_MDC.PRG1_MDIO0_MDC */
+ AM64X_IOPAD(0x0158, PIN_INPUT, 0) /* PRG1_MDIO0_MDIO.PRG1_MDIO0_MDIO */
+ >;
+ };
+
+ pru_rgmii1_default_pins: pru-rgmii1-default-pins {
+ pinctrl-single,pins = <
+ AM64X_IOPAD(0x00b8, PIN_INPUT, 2) /* (Y7) PRG1_PRU0_GPO0.PRG1_RGMII1_RD0 */
+ AM64X_IOPAD(0x00bc, PIN_INPUT, 2) /* (U8) PRG1_PRU0_GPO1.PRG1_RGMII1_RD1 */
+ AM64X_IOPAD(0x00c0, PIN_INPUT, 2) /* (W8) PRG1_PRU0_GPO2.PRG1_RGMII1_RD2 */
+ AM64X_IOPAD(0x00c4, PIN_INPUT, 2) /* (V8) PRG1_PRU0_GPO3.PRG1_RGMII1_RD3 */
+ AM64X_IOPAD(0x00d0, PIN_INPUT, 2) /* (AA7) PRG1_PRU0_GPO6.PRG1_RGMII1_RXC */
+ AM64X_IOPAD(0x00c8, PIN_INPUT, 2) /* (Y8) PRG1_PRU0_GPO4.PRG1_RGMII1_RX_CTL */
+ AM64X_IOPAD(0x00e4, PIN_OUTPUT, 2) /* (AA8) PRG1_PRU0_GPO11.PRG1_RGMII1_TD0 */
+ AM64X_IOPAD(0x00e8, PIN_OUTPUT, 2) /* (U9) PRG1_PRU0_GPO12.PRG1_RGMII1_TD1 */
+ AM64X_IOPAD(0x00ec, PIN_OUTPUT, 2) /* (W9) PRG1_PRU0_GPO13.PRG1_RGMII1_TD2 */
+ AM64X_IOPAD(0x00f0, PIN_OUTPUT, 2) /* (AA9) PRG1_PRU0_GPO14.PRG1_RGMII1_TD3 */
+ AM64X_IOPAD(0x00f8, PIN_INPUT, 2) /* (V9) PRG1_PRU0_GPO16.PRG1_RGMII1_TXC */
+ AM64X_IOPAD(0x00f4, PIN_OUTPUT, 2) /* (Y9) PRG1_PRU0_GPO15.PRG1_RGMII1_TX_CTL */
+ >;
+ };
+
+ pru_rgmii2_default_pins: pru-rgmii2-default-pins {
+ pinctrl-single,pins = <
+ AM64X_IOPAD(0x0108, PIN_INPUT, 2) /* PRG1_PRU1_GPO0.RGMII2_RD0 */
+ AM64X_IOPAD(0x010c, PIN_INPUT, 2) /* PRG1_PRU1_GPO1.RGMII2_RD1 */
+ AM64X_IOPAD(0x0110, PIN_INPUT, 2) /* PRG1_PRU1_GPO2.RGMII2_RD2 */
+ AM64X_IOPAD(0x0114, PIN_INPUT, 2) /* PRG1_PRU1_GPO3.RGMII2_RD3 */
+ AM64X_IOPAD(0x0120, PIN_INPUT, 2) /* PRG1_PRU1_GPO6.RGMII2_RXC */
+ AM64X_IOPAD(0x0118, PIN_INPUT, 2) /* PRG1_PRU1_GPO4.RGMII2_RX_CTL */
+ AM64X_IOPAD(0x0134, PIN_OUTPUT, 2) /* PRG1_PRU1_GPO11.RGMII2_TD0 */
+ AM64X_IOPAD(0x0138, PIN_OUTPUT, 2) /* PRG1_PRU1_GPO12.RGMII2_TD1 */
+ AM64X_IOPAD(0x013c, PIN_OUTPUT, 2) /* PRG1_PRU1_GPO13.RGMII2_TD2 */
+ AM64X_IOPAD(0x0140, PIN_OUTPUT, 2) /* PRG1_PRU1_GPO14.RGMII2_TD3 */
+ AM64X_IOPAD(0x0148, PIN_INPUT, 2) /* PRG1_PRU1_GPO16.RGMII2_TXC */
+ AM64X_IOPAD(0x0144, PIN_OUTPUT, 2) /* PRG1_PRU1_GPO15.RGMII2_TX_CTL */
+ >;
+ };
+
+ rgmii1_default_pins: rgmii1-default-pins {
+ pinctrl-single,pins = <
+ AM64X_IOPAD(0x01cc, PIN_INPUT, 4) /* PRG0_PRU1_GPO7.RGMII1_RD0 */
+ AM64X_IOPAD(0x01d4, PIN_INPUT, 4) /* PRG0_PRU1_GPO9.RGMII1_RD1 */
+ AM64X_IOPAD(0x01d8, PIN_INPUT, 4) /* PRG0_PRU1_GPO10.RGMII1_RD2 */
+ AM64X_IOPAD(0x01f4, PIN_INPUT, 4) /* PRG0_PRU1_GPO17.RGMII1_RD3 */
+ AM64X_IOPAD(0x0188, PIN_INPUT, 4) /* PRG0_PRU0_GPO10.RGMII1_RXC */
+ AM64X_IOPAD(0x0184, PIN_INPUT, 4) /* PRG0_PRU0_GPO9.RGMII1_RX_CTL */
+ AM64X_IOPAD(0x0124, PIN_OUTPUT, 4) /* PRG1_PRU1_GPO7.RGMII1_TD0 */
+ AM64X_IOPAD(0x012c, PIN_OUTPUT, 4) /* PRG1_PRU1_GPO9.RGMII1_TD1 */
+ AM64X_IOPAD(0x0130, PIN_OUTPUT, 4) /* PRG1_PRU1_GPO10.RGMII1_TD2 */
+ AM64X_IOPAD(0x014c, PIN_OUTPUT, 4) /* PRG1_PRU1_GPO17.RGMII1_TD3 */
+ AM64X_IOPAD(0x00e0, PIN_INPUT, 4) /* PRG1_PRU0_GPO10.RGMII1_TXC */
+ AM64X_IOPAD(0x00dc, PIN_OUTPUT, 4) /* PRG1_PRU0_GPO9.RGMII1_TX_CTL */
+ >;
+ };
+
+ usb0_default_pins: usb0-default-pins {
+ pinctrl-single,pins = <
+ AM64X_IOPAD(0x02a8, PIN_OUTPUT, 0) /* USB0_DRVVBUS.USB0_DRVVBUS */
+ >;
+ };
+};
+
+&main_r5fss0_core0 {
+ mboxes = <&mailbox0_cluster2 &mbox_main_r5fss0_core0>;
+ memory-region = <&main_r5fss0_core0_dma_memory_region>,
+ <&main_r5fss0_core0_memory_region>;
+};
+
+&main_r5fss0_core1 {
+ mboxes = <&mailbox0_cluster2 &mbox_main_r5fss0_core1>;
+ memory-region = <&main_r5fss0_core1_dma_memory_region>,
+ <&main_r5fss0_core1_memory_region>;
+};
+
+&main_r5fss1_core0 {
+ mboxes = <&mailbox0_cluster4 &mbox_main_r5fss1_core0>;
+ memory-region = <&main_r5fss1_core0_dma_memory_region>,
+ <&main_r5fss1_core0_memory_region>;
+};
+
+&main_r5fss1_core1 {
+ mboxes = <&mailbox0_cluster4 &mbox_main_r5fss1_core1>;
+ memory-region = <&main_r5fss1_core1_dma_memory_region>,
+ <&main_r5fss1_core1_memory_region>;
+};
+
+/* SoC default UART console */
+&main_uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_uart0_default_pins>;
+ status = "okay";
+};
+
+&ospi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ospi0_default_pins>;
+ num-cs = <1>;
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ospi0_flash0_default_pins>;
+ spi-tx-bus-width = <8>;
+ spi-rx-bus-width = <8>;
+ spi-max-frequency = <200000000>;
+ cdns,tshsl-ns = <50>;
+ cdns,tsd2d-ns = <50>;
+ cdns,tchsh-ns = <4>;
+ cdns,tslch-ns = <4>;
+ cdns,read-delay = <0>;
+ interrupt-parent = <&main_gpio0>;
+ interrupts = <14 IRQ_TYPE_LEVEL_LOW>;
+ reset-gpios = <&main_gpio0 13 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&sdhci0 {
+ /* mmc0 pins have no padconfig */
+ bus-width = <8>;
+ ti,driver-strength-ohm = <50>;
+ disable-wp;
+ non-removable;
+ cap-mmc-hw-reset;
+ no-sd;
+ /*
+ * MMC controller supports switching between 1.8V and 3.3V signalling.
+ * However MMC0 (unlike MMC1) does not integrate an LDO.
+ * Explicitly link a regulator node for indicating to the driver which
+ * voltages are actually usable.
+ */
+ vqmmc-supply = <&vdd_mmc0>;
+ status = "okay";
+};
+
+/*
+ * microSD is on carrier - however since SoC can boot from it,
+ * configure it just in case.
+ */
+&sdhci1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mmc1_default_pins>;
+ bus-width = <4>;
+ ti,driver-strength-ohm = <50>;
+ disable-wp;
+ status = "okay";
+};
+
+/*
+ * USB settings are a carrier choice - however since SoC can boot from it,
+ * configure as USB-2.0 OTG here, keeping USB-3 serdes disabled.
+ */
+&usb0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_default_pins>;
+ dr_mode = "otg";
+ maximum-speed = "high-speed";
+};
+
+&usbss0 {
+ ti,vbus-divider;
+ ti,usb2-only;
+};
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 55102d35cecc..1f4dc5ad1696 100644
--- a/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl-mbax4xxl.dts
+++ b/arch/arm64/boot/dts/ti/k3-am642-tqma64xxl-mbax4xxl.dts
@@ -422,7 +422,6 @@
cd-gpios = <&main_gpio1 77 GPIO_ACTIVE_LOW>;
disable-wp;
no-mmc;
- ti,driver-strength-ohm = <50>;
ti,fails-without-test-cd;
/* Enabled by overlay */
};
diff --git a/arch/arm64/boot/dts/ti/k3-am642.dtsi b/arch/arm64/boot/dts/ti/k3-am642.dtsi
index 7a6eedea3aae..8589ee55ef09 100644
--- a/arch/arm64/boot/dts/ti/k3-am642.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am642.dtsi
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for AM642 SoC family in Dual core configuration
*
- * Copyright (C) 2020-2021 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2020-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-arduino-connector.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-arduino-connector.dtsi
new file mode 100644
index 000000000000..7ff0abd7c62e
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-arduino-connector.dtsi
@@ -0,0 +1,768 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) Siemens AG, 2018-2023
+ *
+ * Authors:
+ * Le Jin <le.jin@siemens.com>
+ * Jan Kiszka <jan.kiszka@siemens.com>
+ *
+ * Common bits for IOT2050 variants with Arduino connector
+ */
+
+&wkup_pmx0 {
+ pinctrl-names =
+ "default",
+ "d0-uart0-rxd", "d0-gpio", "d0-gpio-pullup", "d0-gpio-pulldown",
+ "d1-uart0-txd", "d1-gpio", "d1-gpio-pullup", "d1-gpio-pulldown",
+ "d2-uart0-ctsn", "d2-gpio", "d2-gpio-pullup", "d2-gpio-pulldown",
+ "d3-uart0-rtsn", "d3-gpio", "d3-gpio-pullup", "d3-gpio-pulldown",
+ "d10-spi0-cs0", "d10-gpio", "d10-gpio-pullup", "d10-gpio-pulldown",
+ "d11-spi0-d0", "d11-gpio", "d11-gpio-pullup", "d11-gpio-pulldown",
+ "d12-spi0-d1", "d12-gpio", "d12-gpio-pullup", "d12-gpio-pulldown",
+ "d13-spi0-clk", "d13-gpio", "d13-gpio-pullup", "d13-gpio-pulldown",
+ "a0-gpio", "a0-gpio-pullup", "a0-gpio-pulldown",
+ "a1-gpio", "a1-gpio-pullup", "a1-gpio-pulldown",
+ "a2-gpio", "a2-gpio-pullup", "a2-gpio-pulldown",
+ "a3-gpio", "a3-gpio-pullup", "a3-gpio-pulldown",
+ "a4-gpio", "a4-gpio-pullup", "a4-gpio-pulldown",
+ "a5-gpio", "a5-gpio-pullup", "a5-gpio-pulldown";
+
+ pinctrl-0 = <&d0_uart0_rxd>;
+ pinctrl-1 = <&d0_uart0_rxd>;
+ pinctrl-2 = <&d0_gpio>;
+ pinctrl-3 = <&d0_gpio_pullup>;
+ pinctrl-4 = <&d0_gpio_pulldown>;
+ pinctrl-5 = <&d1_uart0_txd>;
+ pinctrl-6 = <&d1_gpio>;
+ pinctrl-7 = <&d1_gpio_pullup>;
+ pinctrl-8 = <&d1_gpio_pulldown>;
+ pinctrl-9 = <&d2_uart0_ctsn>;
+ pinctrl-10 = <&d2_gpio>;
+ pinctrl-11 = <&d2_gpio_pullup>;
+ pinctrl-12 = <&d2_gpio_pulldown>;
+ pinctrl-13 = <&d3_uart0_rtsn>;
+ pinctrl-14 = <&d3_gpio>;
+ pinctrl-15 = <&d3_gpio_pullup>;
+ pinctrl-16 = <&d3_gpio_pulldown>;
+ pinctrl-17 = <&d10_spi0_cs0>;
+ pinctrl-18 = <&d10_gpio>;
+ pinctrl-19 = <&d10_gpio_pullup>;
+ pinctrl-20 = <&d10_gpio_pulldown>;
+ pinctrl-21 = <&d11_spi0_d0>;
+ pinctrl-22 = <&d11_gpio>;
+ pinctrl-23 = <&d11_gpio_pullup>;
+ pinctrl-24 = <&d11_gpio_pulldown>;
+ pinctrl-25 = <&d12_spi0_d1>;
+ pinctrl-26 = <&d12_gpio>;
+ pinctrl-27 = <&d12_gpio_pullup>;
+ pinctrl-28 = <&d12_gpio_pulldown>;
+ pinctrl-29 = <&d13_spi0_clk>;
+ pinctrl-30 = <&d13_gpio>;
+ pinctrl-31 = <&d13_gpio_pullup>;
+ pinctrl-32 = <&d13_gpio_pulldown>;
+ pinctrl-33 = <&a0_gpio>;
+ pinctrl-34 = <&a0_gpio_pullup>;
+ pinctrl-35 = <&a0_gpio_pulldown>;
+ pinctrl-36 = <&a1_gpio>;
+ pinctrl-37 = <&a1_gpio_pullup>;
+ pinctrl-38 = <&a1_gpio_pulldown>;
+ pinctrl-39 = <&a2_gpio>;
+ pinctrl-40 = <&a2_gpio_pullup>;
+ pinctrl-41 = <&a2_gpio_pulldown>;
+ pinctrl-42 = <&a3_gpio>;
+ pinctrl-43 = <&a3_gpio_pullup>;
+ pinctrl-44 = <&a3_gpio_pulldown>;
+ pinctrl-45 = <&a4_gpio>;
+ pinctrl-46 = <&a4_gpio_pullup>;
+ pinctrl-47 = <&a4_gpio_pulldown>;
+ pinctrl-48 = <&a5_gpio>;
+ pinctrl-49 = <&a5_gpio_pullup>;
+ pinctrl-50 = <&a5_gpio_pulldown>;
+
+ d0_uart0_rxd: d0-uart0-rxd-pins {
+ pinctrl-single,pins = <
+ /* (P4) MCU_UART0_RXD */
+ AM65X_WKUP_IOPAD(0x0044, PIN_INPUT, 4)
+ >;
+ };
+
+ d0_gpio: d0-gpio-pins {
+ pinctrl-single,pins = <
+ /* (P4) WKUP_GPIO0_29 */
+ AM65X_WKUP_IOPAD(0x0044, PIN_INPUT, 7)
+ >;
+ };
+
+ d0_gpio_pullup: d0-gpio-pullup-pins {
+ pinctrl-single,pins = <
+ /* (P4) WKUP_GPIO0_29 */
+ AM65X_WKUP_IOPAD(0x0044, PIN_INPUT_PULLUP, 7)
+ >;
+ };
+
+ d0_gpio_pulldown: d0-gpio-pulldown-pins {
+ pinctrl-single,pins = <
+ /* (P4) WKUP_GPIO0_29 */
+ AM65X_WKUP_IOPAD(0x0044, PIN_INPUT_PULLDOWN, 7)
+ >;
+ };
+
+ d1_uart0_txd: d1-uart0-txd-pins {
+ pinctrl-single,pins = <
+ /* (P5) MCU_UART0_TXD */
+ AM65X_WKUP_IOPAD(0x0048, PIN_OUTPUT, 4)
+ >;
+ };
+
+ d1_gpio: d1-gpio-pins {
+ pinctrl-single,pins = <
+ /* (P5) WKUP_GPIO0_30 */
+ AM65X_WKUP_IOPAD(0x0048, PIN_INPUT, 7)
+ >;
+ };
+
+ d1_gpio_pullup: d1-gpio-pullup-pins {
+ pinctrl-single,pins = <
+ /* (P5) WKUP_GPIO0_30 */
+ AM65X_WKUP_IOPAD(0x0048, PIN_INPUT, 7)
+ >;
+ };
+
+ d1_gpio_pulldown: d1-gpio-pulldown-pins {
+ pinctrl-single,pins = <
+ /* (P5) WKUP_GPIO0_30 */
+ AM65X_WKUP_IOPAD(0x0048, PIN_INPUT_PULLDOWN, 7)
+ >;
+ };
+
+ d2_uart0_ctsn: d2-uart0-ctsn-pins {
+ pinctrl-single,pins = <
+ /* (P1) MCU_UART0_CTSn */
+ AM65X_WKUP_IOPAD(0x004C, PIN_INPUT, 4)
+ >;
+ };
+
+ d2_gpio: d2-gpio-pins {
+ pinctrl-single,pins = <
+ /* (P5) WKUP_GPIO0_31 */
+ AM65X_WKUP_IOPAD(0x004C, PIN_INPUT, 7)
+ >;
+ };
+
+ d2_gpio_pullup: d2-gpio-pullup-pins {
+ pinctrl-single,pins = <
+ /* (P5) WKUP_GPIO0_31 */
+ AM65X_WKUP_IOPAD(0x004C, PIN_INPUT, 7)
+ >;
+ };
+
+ d2_gpio_pulldown: d2-gpio-pulldown-pins {
+ pinctrl-single,pins = <
+ /* (P5) WKUP_GPIO0_31 */
+ AM65X_WKUP_IOPAD(0x004C, PIN_INPUT_PULLDOWN, 7)
+ >;
+ };
+
+ d3_uart0_rtsn: d3-uart0-rtsn-pins {
+ pinctrl-single,pins = <
+ /* (N3) MCU_UART0_RTSn */
+ AM65X_WKUP_IOPAD(0x0054, PIN_OUTPUT, 4)
+ >;
+ };
+
+ d3_gpio: d3-gpio-pins {
+ pinctrl-single,pins = <
+ /* (N3) WKUP_GPIO0_33 */
+ AM65X_WKUP_IOPAD(0x0054, PIN_INPUT, 7)
+ >;
+ };
+
+ d3_gpio_pullup: d3-gpio-pullup-pins {
+ pinctrl-single,pins = <
+ /* (N3) WKUP_GPIO0_33 */
+ AM65X_WKUP_IOPAD(0x0054, PIN_INPUT, 7)
+ >;
+ };
+
+ d3_gpio_pulldown: d3-gpio-pulldown-pins {
+ pinctrl-single,pins = <
+ /* (N3) WKUP_GPIO0_33 */
+ AM65X_WKUP_IOPAD(0x0054, PIN_INPUT_PULLDOWN, 7)
+ >;
+ };
+
+ d10_spi0_cs0: d10-spi0-cs0-pins {
+ pinctrl-single,pins = <
+ /* (Y4) MCU_SPI0_CS0 */
+ AM65X_WKUP_IOPAD(0x009c, PIN_OUTPUT, 0)
+ >;
+ };
+
+ d10_gpio: d10-gpio-pins {
+ pinctrl-single,pins = <
+ /* (Y4) WKUP_GPIO0_51 */
+ AM65X_WKUP_IOPAD(0x009c, PIN_INPUT, 7)
+ >;
+ };
+
+ d10_gpio_pullup: d10-gpio-pullup-pins {
+ pinctrl-single,pins = <
+ /* (Y4) WKUP_GPIO0_51 */
+ AM65X_WKUP_IOPAD(0x009c, PIN_INPUT, 7)
+ >;
+ };
+
+ d10_gpio_pulldown: d10-gpio-pulldown-pins {
+ pinctrl-single,pins = <
+ /* (Y4) WKUP_GPIO0_51 */
+ AM65X_WKUP_IOPAD(0x009c, PIN_INPUT_PULLDOWN, 7)
+ >;
+ };
+
+ d11_spi0_d0: d11-spi0-d0-pins {
+ pinctrl-single,pins = <
+ /* (Y3) MCU_SPI0_D0 */
+ AM65X_WKUP_IOPAD(0x0094, PIN_INPUT, 0)
+ >;
+ };
+
+ d11_gpio: d11-gpio-pins {
+ pinctrl-single,pins = <
+ /* (Y3) WKUP_GPIO0_49 */
+ AM65X_WKUP_IOPAD(0x0094, PIN_INPUT, 7)
+ >;
+ };
+
+ d11_gpio_pullup: d11-gpio-pullup-pins {
+ pinctrl-single,pins = <
+ /* (Y3) WKUP_GPIO0_49 */
+ AM65X_WKUP_IOPAD(0x0094, PIN_INPUT, 7)
+ >;
+ };
+
+ d11_gpio_pulldown: d11-gpio-pulldown-pins {
+ pinctrl-single,pins = <
+ /* (Y3) WKUP_GPIO0_49 */
+ AM65X_WKUP_IOPAD(0x0094, PIN_INPUT_PULLDOWN, 7)
+ >;
+ };
+
+ d12_spi0_d1: d12-spi0-d1-pins {
+ pinctrl-single,pins = <
+ /* (Y2) MCU_SPI0_D1 */
+ AM65X_WKUP_IOPAD(0x0098, PIN_INPUT, 0)
+ >;
+ };
+
+ d12_gpio: d12-gpio-pins {
+ pinctrl-single,pins = <
+ /* (Y2) WKUP_GPIO0_50 */
+ AM65X_WKUP_IOPAD(0x0098, PIN_INPUT, 7)
+ >;
+ };
+
+ d12_gpio_pullup: d12-gpio-pullup-pins {
+ pinctrl-single,pins = <
+ /* (Y2) WKUP_GPIO0_50 */
+ AM65X_WKUP_IOPAD(0x0098, PIN_INPUT, 7)
+ >;
+ };
+
+ d12_gpio_pulldown: d12-gpio-pulldown-pins {
+ pinctrl-single,pins = <
+ /* (Y2) WKUP_GPIO0_50 */
+ AM65X_WKUP_IOPAD(0x0098, PIN_INPUT_PULLDOWN, 7)
+ >;
+ };
+
+ d13_spi0_clk: d13-spi0-clk-pins {
+ pinctrl-single,pins = <
+ /* (Y1) MCU_SPI0_CLK */
+ AM65X_WKUP_IOPAD(0x0090, PIN_INPUT, 0)
+ >;
+ };
+
+ d13_gpio: d13-gpio-pins {
+ pinctrl-single,pins = <
+ /* (Y1) WKUP_GPIO0_48 */
+ AM65X_WKUP_IOPAD(0x0090, PIN_INPUT, 7)
+ >;
+ };
+
+ d13_gpio_pullup: d13-gpio-pullup-pins {
+ pinctrl-single,pins = <
+ /* (Y1) WKUP_GPIO0_48 */
+ AM65X_WKUP_IOPAD(0x0090, PIN_INPUT, 7)
+ >;
+ };
+
+ d13_gpio_pulldown: d13-gpio-pulldown-pins {
+ pinctrl-single,pins = <
+ /* (Y1) WKUP_GPIO0_48 */
+ AM65X_WKUP_IOPAD(0x0090, PIN_INPUT_PULLDOWN, 7)
+ >;
+ };
+
+ a0_gpio: a0-gpio-pins {
+ pinctrl-single,pins = <
+ /* (L6) WKUP_GPIO0_45 */
+ AM65X_WKUP_IOPAD(0x0084, PIN_INPUT, 7)
+ >;
+ };
+
+ a0_gpio_pullup: a0-gpio-pullup-pins {
+ pinctrl-single,pins = <
+ /* (L6) WKUP_GPIO0_45 */
+ AM65X_WKUP_IOPAD(0x0084, PIN_INPUT, 7)
+ >;
+ };
+
+ a0_gpio_pulldown: a0-gpio-pulldown-pins {
+ pinctrl-single,pins = <
+ /* (L6) WKUP_GPIO0_45 */
+ AM65X_WKUP_IOPAD(0x0084, PIN_INPUT_PULLDOWN, 7)
+ >;
+ };
+
+ a1_gpio: a1-gpio-pins {
+ pinctrl-single,pins = <
+ /* (M6) WKUP_GPIO0_44 */
+ AM65X_WKUP_IOPAD(0x0080, PIN_INPUT, 7)
+ >;
+ };
+
+ a1_gpio_pullup: a1-gpio-pullup-pins {
+ pinctrl-single,pins = <
+ /* (M6) WKUP_GPIO0_44 */
+ AM65X_WKUP_IOPAD(0x0080, PIN_INPUT, 7)
+ >;
+ };
+
+ a1_gpio_pulldown: a1-gpio-pulldown-pins {
+ pinctrl-single,pins = <
+ /* (M6) WKUP_GPIO0_44 */
+ AM65X_WKUP_IOPAD(0x0080, PIN_INPUT_PULLDOWN, 7)
+ >;
+ };
+
+ a2_gpio: a2-gpio-pins {
+ pinctrl-single,pins = <
+ /* (L5) WKUP_GPIO0_43 */
+ AM65X_WKUP_IOPAD(0x007C, PIN_INPUT, 7)
+ >;
+ };
+
+ a2_gpio_pullup: a2-gpio-pullup-pins {
+ pinctrl-single,pins = <
+ /* (L5) WKUP_GPIO0_43 */
+ AM65X_WKUP_IOPAD(0x007C, PIN_INPUT, 7)
+ >;
+ };
+
+ a2_gpio_pulldown: a2-gpio-pulldown-pins {
+ pinctrl-single,pins = <
+ /* (L5) WKUP_GPIO0_43 */
+ AM65X_WKUP_IOPAD(0x007C, PIN_INPUT_PULLDOWN, 7)
+ >;
+ };
+
+ a3_gpio: a3-gpio-pins {
+ pinctrl-single,pins = <
+ /* (M5) WKUP_GPIO0_39 */
+ AM65X_WKUP_IOPAD(0x006C, PIN_INPUT, 7)
+ >;
+ };
+
+ a3_gpio_pullup: a3-gpio-pullup-pins {
+ pinctrl-single,pins = <
+ /* (M5) WKUP_GPIO0_39 */
+ AM65X_WKUP_IOPAD(0x006C, PIN_INPUT, 7)
+ >;
+ };
+
+ a3_gpio_pulldown: a3-gpio-pulldown-pins {
+ pinctrl-single,pins = <
+ /* (M5) WKUP_GPIO0_39 */
+ AM65X_WKUP_IOPAD(0x006C, PIN_INPUT_PULLDOWN, 7)
+ >;
+ };
+
+ a4_gpio: a4-gpio-pins {
+ pinctrl-single,pins = <
+ /* (L2) WKUP_GPIO0_42 */
+ AM65X_WKUP_IOPAD(0x0078, PIN_INPUT, 7)
+ >;
+ };
+
+ a4_gpio_pullup: a4-gpio-pullup-pins {
+ pinctrl-single,pins = <
+ /* (L2) WKUP_GPIO0_42 */
+ AM65X_WKUP_IOPAD(0x0078, PIN_INPUT, 7)
+ >;
+ };
+
+ a4_gpio_pulldown: a4-gpio-pulldown-pins {
+ pinctrl-single,pins = <
+ /* (L2) WKUP_GPIO0_42 */
+ AM65X_WKUP_IOPAD(0x0078, PIN_INPUT_PULLDOWN, 7)
+ >;
+ };
+
+ a5_gpio: a5-gpio-pins {
+ pinctrl-single,pins = <
+ /* (N5) WKUP_GPIO0_35 */
+ AM65X_WKUP_IOPAD(0x005C, PIN_INPUT, 7)
+ >;
+ };
+
+ a5_gpio_pullup: a5-gpio-pullup-pins {
+ pinctrl-single,pins = <
+ /* (N5) WKUP_GPIO0_35 */
+ AM65X_WKUP_IOPAD(0x005C, PIN_INPUT_PULLUP, 7)
+ >;
+ };
+
+ a5_gpio_pulldown: a5-gpio-pulldown-pins {
+ pinctrl-single,pins = <
+ /* (N5) WKUP_GPIO0_35 */
+ AM65X_WKUP_IOPAD(0x005C, PIN_INPUT_PULLDOWN, 7)
+ >;
+ };
+
+ wkup_i2c0_pins_default: wkup-i2c0-default-pins {
+ pinctrl-single,pins = <
+ /* (AC7) WKUP_I2C0_SCL */
+ AM65X_WKUP_IOPAD(0x00e0, PIN_INPUT, 0)
+ /* (AD6) WKUP_I2C0_SDA */
+ AM65X_WKUP_IOPAD(0x00e4, PIN_INPUT, 0)
+ >;
+ };
+
+ arduino_i2c_aio_switch_pins_default: arduino-i2c-aio-switch-default-pins {
+ pinctrl-single,pins = <
+ /* (R2) WKUP_GPIO0_21 */
+ AM65X_WKUP_IOPAD(0x0024, PIN_OUTPUT, 7)
+ >;
+ };
+
+ arduino_io_oe_pins_default: arduino-io-oe-default-pins {
+ pinctrl-single,pins = <
+ /* (N4) WKUP_GPIO0_34 */
+ AM65X_WKUP_IOPAD(0x0058, PIN_OUTPUT, 7)
+ /* (M2) WKUP_GPIO0_36 */
+ AM65X_WKUP_IOPAD(0x0060, PIN_OUTPUT, 7)
+ /* (M3) WKUP_GPIO0_37 */
+ AM65X_WKUP_IOPAD(0x0064, PIN_OUTPUT, 7)
+ /* (M4) WKUP_GPIO0_38 */
+ AM65X_WKUP_IOPAD(0x0068, PIN_OUTPUT, 7)
+ /* (M1) WKUP_GPIO0_41 */
+ AM65X_WKUP_IOPAD(0x0074, PIN_OUTPUT, 7)
+ >;
+ };
+};
+
+&main_pmx0 {
+ pinctrl-names =
+ "default",
+ "d4-ehrpwm0-a", "d4-gpio", "d4-gpio-pullup", "d4-gpio-pulldown",
+ "d5-ehrpwm1-a", "d5-gpio", "d5-gpio-pullup", "d5-gpio-pulldown",
+ "d6-ehrpwm2-a", "d6-gpio", "d6-gpio-pullup", "d6-gpio-pulldown",
+ "d7-ehrpwm3-a", "d7-gpio", "d7-gpio-pullup", "d7-gpio-pulldown",
+ "d8-ehrpwm4-a", "d8-gpio", "d8-gpio-pullup", "d8-gpio-pulldown",
+ "d9-ehrpwm5-a", "d9-gpio", "d9-gpio-pullup", "d9-gpio-pulldown";
+
+ pinctrl-0 = <&d4_ehrpwm0_a>;
+ pinctrl-1 = <&d4_ehrpwm0_a>;
+ pinctrl-2 = <&d4_gpio>;
+ pinctrl-3 = <&d4_gpio_pullup>;
+ pinctrl-4 = <&d4_gpio_pulldown>;
+
+ pinctrl-5 = <&d5_ehrpwm1_a>;
+ pinctrl-6 = <&d5_gpio>;
+ pinctrl-7 = <&d5_gpio_pullup>;
+ pinctrl-8 = <&d5_gpio_pulldown>;
+
+ pinctrl-9 = <&d6_ehrpwm2_a>;
+ pinctrl-10 = <&d6_gpio>;
+ pinctrl-11 = <&d6_gpio_pullup>;
+ pinctrl-12 = <&d6_gpio_pulldown>;
+
+ pinctrl-13 = <&d7_ehrpwm3_a>;
+ pinctrl-14 = <&d7_gpio>;
+ pinctrl-15 = <&d7_gpio_pullup>;
+ pinctrl-16 = <&d7_gpio_pulldown>;
+
+ pinctrl-17 = <&d8_ehrpwm4_a>;
+ pinctrl-18 = <&d8_gpio>;
+ pinctrl-19 = <&d8_gpio_pullup>;
+ pinctrl-20 = <&d8_gpio_pulldown>;
+
+ pinctrl-21 = <&d9_ehrpwm5_a>;
+ pinctrl-22 = <&d9_gpio>;
+ pinctrl-23 = <&d9_gpio_pullup>;
+ pinctrl-24 = <&d9_gpio_pulldown>;
+
+ d4_ehrpwm0_a: d4-ehrpwm0-a-pins {
+ pinctrl-single,pins = <
+ /* (AG18) EHRPWM0_A */
+ AM65X_IOPAD(0x0084, PIN_OUTPUT, 5)
+ >;
+ };
+
+ d4_gpio: d4-gpio-pins {
+ pinctrl-single,pins = <
+ /* (AG18) GPIO0_33 */
+ AM65X_IOPAD(0x0084, PIN_INPUT, 7)
+ >;
+ };
+
+ d4_gpio_pullup: d4-gpio-pullup-pins {
+ pinctrl-single,pins = <
+ /* (AG18) GPIO0_33 */
+ AM65X_IOPAD(0x0084, PIN_INPUT_PULLUP, 7)
+ >;
+ };
+
+ d4_gpio_pulldown: d4-gpio-pulldown-pins {
+ pinctrl-single,pins = <
+ /* (AG18) GPIO0_33 */
+ AM65X_IOPAD(0x0084, PIN_INPUT_PULLDOWN, 7)
+ >;
+ };
+
+ d5_ehrpwm1_a: d5-ehrpwm1-a-pins {
+ pinctrl-single,pins = <
+ /* (AF17) EHRPWM1_A */
+ AM65X_IOPAD(0x008C, PIN_OUTPUT, 5)
+ >;
+ };
+
+ d5_gpio: d5-gpio-pins {
+ pinctrl-single,pins = <
+ /* (AF17) GPIO0_35 */
+ AM65X_IOPAD(0x008C, PIN_INPUT, 7)
+ >;
+ };
+
+ d5_gpio_pullup: d5-gpio-pullup-pins {
+ pinctrl-single,pins = <
+ /* (AF17) GPIO0_35 */
+ AM65X_IOPAD(0x008C, PIN_INPUT_PULLUP, 7)
+ >;
+ };
+
+ d5_gpio_pulldown: d5-gpio-pulldown-pins {
+ pinctrl-single,pins = <
+ /* (AF17) GPIO0_35 */
+ AM65X_IOPAD(0x008C, PIN_INPUT_PULLDOWN, 7)
+ >;
+ };
+
+ d6_ehrpwm2_a: d6-ehrpwm2-a-pins {
+ pinctrl-single,pins = <
+ /* (AH16) EHRPWM2_A */
+ AM65X_IOPAD(0x0098, PIN_OUTPUT, 5)
+ >;
+ };
+
+ d6_gpio: d6-gpio-pins {
+ pinctrl-single,pins = <
+ /* (AH16) GPIO0_38 */
+ AM65X_IOPAD(0x0098, PIN_INPUT, 7)
+ >;
+ };
+
+ d6_gpio_pullup: d6-gpio-pullup-pins {
+ pinctrl-single,pins = <
+ /* (AH16) GPIO0_38 */
+ AM65X_IOPAD(0x0098, PIN_INPUT_PULLUP, 7)
+ >;
+ };
+
+ d6_gpio_pulldown: d6-gpio-pulldown-pins {
+ pinctrl-single,pins = <
+ /* (AH16) GPIO0_38 */
+ AM65X_IOPAD(0x0098, PIN_INPUT_PULLDOWN, 7)
+ >;
+ };
+
+ d7_ehrpwm3_a: d7-ehrpwm3-a-pins {
+ pinctrl-single,pins = <
+ /* (AH15) EHRPWM3_A */
+ AM65X_IOPAD(0x00AC, PIN_OUTPUT, 5)
+ >;
+ };
+
+ d7_gpio: d7-gpio-pins {
+ pinctrl-single,pins = <
+ /* (AH15) GPIO0_43 */
+ AM65X_IOPAD(0x00AC, PIN_INPUT, 7)
+ >;
+ };
+
+ d7_gpio_pullup: d7-gpio-pullup-pins {
+ pinctrl-single,pins = <
+ /* (AH15) GPIO0_43 */
+ AM65X_IOPAD(0x00AC, PIN_INPUT_PULLUP, 7)
+ >;
+ };
+
+ d7_gpio_pulldown: d7-gpio-pulldown-pins {
+ pinctrl-single,pins = <
+ /* (AH15) GPIO0_43 */
+ AM65X_IOPAD(0x00AC, PIN_INPUT_PULLDOWN, 7)
+ >;
+ };
+
+ d8_ehrpwm4_a: d8-ehrpwm4-a-pins {
+ pinctrl-single,pins = <
+ /* (AG15) EHRPWM4_A */
+ AM65X_IOPAD(0x00C0, PIN_OUTPUT, 5)
+ >;
+ };
+
+ d8_gpio: d8-gpio-pins {
+ pinctrl-single,pins = <
+ /* (AG15) GPIO0_48 */
+ AM65X_IOPAD(0x00C0, PIN_INPUT, 7)
+ >;
+ };
+
+ d8_gpio_pullup: d8-gpio-pullup-pins {
+ pinctrl-single,pins = <
+ /* (AG15) GPIO0_48 */
+ AM65X_IOPAD(0x00C0, PIN_INPUT_PULLUP, 7)
+ >;
+ };
+
+ d8_gpio_pulldown: d8-gpio-pulldown-pins {
+ pinctrl-single,pins = <
+ /* (AG15) GPIO0_48 */
+ AM65X_IOPAD(0x00C0, PIN_INPUT_PULLDOWN, 7)
+ >;
+ };
+
+ d9_ehrpwm5_a: d9-ehrpwm5-a-pins {
+ pinctrl-single,pins = <
+ /* (AD15) EHRPWM5_A */
+ AM65X_IOPAD(0x00CC, PIN_OUTPUT, 5)
+ >;
+ };
+
+ d9_gpio: d9-gpio-pins {
+ pinctrl-single,pins = <
+ /* (AD15) GPIO0_51 */
+ AM65X_IOPAD(0x00CC, PIN_INPUT, 7)
+ >;
+ };
+
+ d9_gpio_pullup: d9-gpio-pullup-pins {
+ pinctrl-single,pins = <
+ /* (AD15) GPIO0_51 */
+ AM65X_IOPAD(0x00CC, PIN_INPUT_PULLUP, 7)
+ >;
+ };
+
+ d9_gpio_pulldown: d9-gpio-pulldown-pins {
+ pinctrl-single,pins = <
+ /* (AD15) GPIO0_51 */
+ AM65X_IOPAD(0x00CC, PIN_INPUT_PULLDOWN, 7)
+ >;
+ };
+};
+
+&main_gpio0 {
+ gpio-line-names =
+ "main_gpio0-base", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "IO4", "", "IO5", "", "", "IO6", "",
+ "", "", "", "IO7", "", "", "", "", "IO8", "",
+ "", "IO9";
+};
+
+&wkup_gpio0 {
+ pinctrl-names = "default";
+ pinctrl-0 =
+ <&arduino_i2c_aio_switch_pins_default>,
+ <&arduino_io_oe_pins_default>,
+ <&push_button_pins_default>,
+ <&db9_com_mode_pins_default>;
+ gpio-line-names =
+ /* 0..9 */
+ "wkup_gpio0-base", "", "", "", "UART0-mode1", "UART0-mode0",
+ "UART0-enable", "UART0-terminate", "", "WIFI-disable",
+ /* 10..19 */
+ "", "", "", "", "", "", "", "", "", "",
+ /* 20..29 */
+ "", "A4A5-I2C-mux", "", "", "", "USER-button", "", "", "","IO0",
+ /* 30..39 */
+ "IO1", "IO2", "", "IO3", "IO17-direction", "A5",
+ "IO16-direction", "IO15-direction", "IO14-direction", "A3",
+ /* 40..49 */
+ "", "IO18-direction", "A4", "A2", "A1", "A0", "", "", "IO13",
+ "IO11",
+ /* 50..51 */
+ "IO12", "IO10";
+};
+
+&wkup_i2c0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&wkup_i2c0_pins_default>;
+ clock-frequency = <400000>;
+};
+
+&mcu_i2c0 {
+ /* D4200 */
+ pcal9535_1: gpio@20 {
+ compatible = "nxp,pcal9535";
+ reg = <0x20>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-line-names =
+ "A0-pull", "A1-pull", "A2-pull", "A3-pull", "A4-pull",
+ "A5-pull", "", "",
+ "IO14-enable", "IO15-enable", "IO16-enable",
+ "IO17-enable", "IO18-enable", "IO19-enable";
+ };
+
+ /* D4201 */
+ pcal9535_2: gpio@21 {
+ compatible = "nxp,pcal9535";
+ reg = <0x21>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-line-names =
+ "IO0-direction", "IO1-direction", "IO2-direction",
+ "IO3-direction", "IO4-direction", "IO5-direction",
+ "IO6-direction", "IO7-direction",
+ "IO8-direction", "IO9-direction", "IO10-direction",
+ "IO11-direction", "IO12-direction", "IO13-direction",
+ "IO19-direction";
+ };
+
+ /* D4202 */
+ pcal9535_3: gpio@25 {
+ compatible = "nxp,pcal9535";
+ reg = <0x25>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-line-names =
+ "IO0-pull", "IO1-pull", "IO2-pull", "IO3-pull",
+ "IO4-pull", "IO5-pull", "IO6-pull", "IO7-pull",
+ "IO8-pull", "IO9-pull", "IO10-pull", "IO11-pull",
+ "IO12-pull", "IO13-pull";
+ };
+};
+
+&mcu_uart0 {
+ status = "okay";
+};
+
+&tscadc1 {
+ status = "okay";
+ adc {
+ ti,adc-channels = <0 1 2 3 4 5>;
+ };
+};
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 1d1979859583..c50a585dd638 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
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) Siemens AG, 2021-2023
*
@@ -8,10 +8,7 @@
* Common bits of the IOT2050 Basic and Advanced variants, PG1
*/
-&dss {
- assigned-clocks = <&k3_clks 67 2>;
- assigned-clock-parents = <&k3_clks 67 5>;
-};
+#include "k3-am65-iot2050-dp.dtsi"
&serdes0 {
status = "disabled";
diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg2.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg2.dtsi
index e9b57b87e42e..e2584a5efe34 100644
--- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg2.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg2.dtsi
@@ -1,6 +1,6 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (c) Siemens AG, 2021
+ * Copyright (c) Siemens AG, 2021-2023
*
* Authors:
* Chao Zeng <chao.zeng@siemens.com>
@@ -9,6 +9,11 @@
* Common bits of the IOT2050 Basic and Advanced variants, PG2
*/
+&mcu_r5fss0 {
+ /* lock-step mode not supported on PG2 boards */
+ ti,cluster-mode = <0>;
+};
+
&main_pmx0 {
cp2102n_reset_pin_default: cp2102n-reset-default-pins {
pinctrl-single,pins = <
@@ -33,21 +38,3 @@
/* Workaround needed to get DP clock of 154Mhz */
assigned-clocks = <&k3_clks 67 0>;
};
-
-&serdes0 {
- assigned-clocks = <&k3_clks 153 4>, <&serdes0 AM654_SERDES_CMU_REFCLK>;
- assigned-clock-parents = <&k3_clks 153 7>, <&k3_clks 153 4>;
-};
-
-&dwc3_0 {
- assigned-clock-parents = <&k3_clks 151 4>, /* set REF_CLK to 20MHz i.e. PER0_PLL/48 */
- <&k3_clks 151 8>; /* set PIPE3_TXB_CLK to WIZ8B2M4VSB */
- phys = <&serdes0 PHY_TYPE_USB3 0>;
- phy-names = "usb3-phy";
-};
-
-&usb0 {
- maximum-speed = "super-speed";
- snps,dis-u1-entry-quirk;
- snps,dis-u2-entry-quirk;
-};
diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi
index 61a634afaa4f..ef34b851e178 100644
--- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi
@@ -1,6 +1,6 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (c) Siemens AG, 2018-2021
+ * Copyright (c) Siemens AG, 2018-2024
*
* Authors:
* Le Jin <le.jin@siemens.com>
@@ -9,6 +9,7 @@
* Common bits of the IOT2050 Basic and Advanced variants, PG1 and PG2
*/
+#include <dt-bindings/leds/common.h>
#include <dt-bindings/phy/phy.h>
#include <dt-bindings/net/ti-dp83867.h>
@@ -75,6 +76,12 @@
alignment = <0x1000>;
no-map;
};
+
+ /* To reserve the power-on(PON) reason for watchdog reset */
+ wdt_reset_memory_region: wdt-memory@a2200000 {
+ reg = <0x00 0xa2200000 0x00 0x1000>;
+ no-map;
+ };
};
leds {
@@ -82,28 +89,46 @@
pinctrl-names = "default";
pinctrl-0 = <&leds_pins_default>;
- status-led-red {
+ led-0 {
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_STATUS;
+ label = "status-led-red";
gpios = <&wkup_gpio0 32 GPIO_ACTIVE_HIGH>;
panic-indicator;
};
- status-led-green {
+ led-1 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_STATUS;
+ label = "status-led-green";
gpios = <&wkup_gpio0 24 GPIO_ACTIVE_HIGH>;
};
- user-led1-red {
+ led-2 {
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_INDICATOR;
+ label = "user-led1-red";
gpios = <&pcal9535_3 14 GPIO_ACTIVE_HIGH>;
};
- user-led1-green {
+ led-3 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_INDICATOR;
+ label = "user-led1-green";
gpios = <&pcal9535_2 15 GPIO_ACTIVE_HIGH>;
};
- user-led2-red {
+ led-4 {
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_INDICATOR;
+ label = "user-led2-red";
gpios = <&wkup_gpio0 17 GPIO_ACTIVE_HIGH>;
};
- user-led2-green {
+ led-5 {
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_INDICATOR;
+ label = "user-led2-green";
gpios = <&wkup_gpio0 22 GPIO_ACTIVE_HIGH>;
};
};
@@ -186,434 +211,6 @@
};
&wkup_pmx0 {
- pinctrl-names =
- "default",
- "d0-uart0-rxd", "d0-gpio", "d0-gpio-pullup", "d0-gpio-pulldown",
- "d1-uart0-txd", "d1-gpio", "d1-gpio-pullup", "d1-gpio-pulldown",
- "d2-uart0-ctsn", "d2-gpio", "d2-gpio-pullup", "d2-gpio-pulldown",
- "d3-uart0-rtsn", "d3-gpio", "d3-gpio-pullup", "d3-gpio-pulldown",
- "d10-spi0-cs0", "d10-gpio", "d10-gpio-pullup", "d10-gpio-pulldown",
- "d11-spi0-d0", "d11-gpio", "d11-gpio-pullup", "d11-gpio-pulldown",
- "d12-spi0-d1", "d12-gpio", "d12-gpio-pullup", "d12-gpio-pulldown",
- "d13-spi0-clk", "d13-gpio", "d13-gpio-pullup", "d13-gpio-pulldown",
- "a0-gpio", "a0-gpio-pullup", "a0-gpio-pulldown",
- "a1-gpio", "a1-gpio-pullup", "a1-gpio-pulldown",
- "a2-gpio", "a2-gpio-pullup", "a2-gpio-pulldown",
- "a3-gpio", "a3-gpio-pullup", "a3-gpio-pulldown",
- "a4-gpio", "a4-gpio-pullup", "a4-gpio-pulldown",
- "a5-gpio", "a5-gpio-pullup", "a5-gpio-pulldown";
-
- pinctrl-0 = <&d0_uart0_rxd>;
- pinctrl-1 = <&d0_uart0_rxd>;
- pinctrl-2 = <&d0_gpio>;
- pinctrl-3 = <&d0_gpio_pullup>;
- pinctrl-4 = <&d0_gpio_pulldown>;
- pinctrl-5 = <&d1_uart0_txd>;
- pinctrl-6 = <&d1_gpio>;
- pinctrl-7 = <&d1_gpio_pullup>;
- pinctrl-8 = <&d1_gpio_pulldown>;
- pinctrl-9 = <&d2_uart0_ctsn>;
- pinctrl-10 = <&d2_gpio>;
- pinctrl-11 = <&d2_gpio_pullup>;
- pinctrl-12 = <&d2_gpio_pulldown>;
- pinctrl-13 = <&d3_uart0_rtsn>;
- pinctrl-14 = <&d3_gpio>;
- pinctrl-15 = <&d3_gpio_pullup>;
- pinctrl-16 = <&d3_gpio_pulldown>;
- pinctrl-17 = <&d10_spi0_cs0>;
- pinctrl-18 = <&d10_gpio>;
- pinctrl-19 = <&d10_gpio_pullup>;
- pinctrl-20 = <&d10_gpio_pulldown>;
- pinctrl-21 = <&d11_spi0_d0>;
- pinctrl-22 = <&d11_gpio>;
- pinctrl-23 = <&d11_gpio_pullup>;
- pinctrl-24 = <&d11_gpio_pulldown>;
- pinctrl-25 = <&d12_spi0_d1>;
- pinctrl-26 = <&d12_gpio>;
- pinctrl-27 = <&d12_gpio_pullup>;
- pinctrl-28 = <&d12_gpio_pulldown>;
- pinctrl-29 = <&d13_spi0_clk>;
- pinctrl-30 = <&d13_gpio>;
- pinctrl-31 = <&d13_gpio_pullup>;
- pinctrl-32 = <&d13_gpio_pulldown>;
- pinctrl-33 = <&a0_gpio>;
- pinctrl-34 = <&a0_gpio_pullup>;
- pinctrl-35 = <&a0_gpio_pulldown>;
- pinctrl-36 = <&a1_gpio>;
- pinctrl-37 = <&a1_gpio_pullup>;
- pinctrl-38 = <&a1_gpio_pulldown>;
- pinctrl-39 = <&a2_gpio>;
- pinctrl-40 = <&a2_gpio_pullup>;
- pinctrl-41 = <&a2_gpio_pulldown>;
- pinctrl-42 = <&a3_gpio>;
- pinctrl-43 = <&a3_gpio_pullup>;
- pinctrl-44 = <&a3_gpio_pulldown>;
- pinctrl-45 = <&a4_gpio>;
- pinctrl-46 = <&a4_gpio_pullup>;
- pinctrl-47 = <&a4_gpio_pulldown>;
- pinctrl-48 = <&a5_gpio>;
- pinctrl-49 = <&a5_gpio_pullup>;
- pinctrl-50 = <&a5_gpio_pulldown>;
-
- d0_uart0_rxd: d0-uart0-rxd-pins {
- pinctrl-single,pins = <
- /* (P4) MCU_UART0_RXD */
- AM65X_WKUP_IOPAD(0x0044, PIN_INPUT, 4)
- >;
- };
-
- d0_gpio: d0-gpio-pins {
- pinctrl-single,pins = <
- /* (P4) WKUP_GPIO0_29 */
- AM65X_WKUP_IOPAD(0x0044, PIN_INPUT, 7)
- >;
- };
-
- d0_gpio_pullup: d0-gpio-pullup-pins {
- pinctrl-single,pins = <
- /* (P4) WKUP_GPIO0_29 */
- AM65X_WKUP_IOPAD(0x0044, PIN_INPUT_PULLUP, 7)
- >;
- };
-
- d0_gpio_pulldown: d0-gpio-pulldown-pins {
- pinctrl-single,pins = <
- /* (P4) WKUP_GPIO0_29 */
- AM65X_WKUP_IOPAD(0x0044, PIN_INPUT_PULLDOWN, 7)
- >;
- };
-
- d1_uart0_txd: d1-uart0-txd-pins {
- pinctrl-single,pins = <
- /* (P5) MCU_UART0_TXD */
- AM65X_WKUP_IOPAD(0x0048, PIN_OUTPUT, 4)
- >;
- };
-
- d1_gpio: d1-gpio-pins {
- pinctrl-single,pins = <
- /* (P5) WKUP_GPIO0_30 */
- AM65X_WKUP_IOPAD(0x0048, PIN_INPUT, 7)
- >;
- };
-
- d1_gpio_pullup: d1-gpio-pullup-pins {
- pinctrl-single,pins = <
- /* (P5) WKUP_GPIO0_30 */
- AM65X_WKUP_IOPAD(0x0048, PIN_INPUT, 7)
- >;
- };
-
- d1_gpio_pulldown: d1-gpio-pulldown-pins {
- pinctrl-single,pins = <
- /* (P5) WKUP_GPIO0_30 */
- AM65X_WKUP_IOPAD(0x0048, PIN_INPUT_PULLDOWN, 7)
- >;
- };
-
- d2_uart0_ctsn: d2-uart0-ctsn-pins {
- pinctrl-single,pins = <
- /* (P1) MCU_UART0_CTSn */
- AM65X_WKUP_IOPAD(0x004C, PIN_INPUT, 4)
- >;
- };
-
- d2_gpio: d2-gpio-pins {
- pinctrl-single,pins = <
- /* (P5) WKUP_GPIO0_31 */
- AM65X_WKUP_IOPAD(0x004C, PIN_INPUT, 7)
- >;
- };
-
- d2_gpio_pullup: d2-gpio-pullup-pins {
- pinctrl-single,pins = <
- /* (P5) WKUP_GPIO0_31 */
- AM65X_WKUP_IOPAD(0x004C, PIN_INPUT, 7)
- >;
- };
-
- d2_gpio_pulldown: d2-gpio-pulldown-pins {
- pinctrl-single,pins = <
- /* (P5) WKUP_GPIO0_31 */
- AM65X_WKUP_IOPAD(0x004C, PIN_INPUT_PULLDOWN, 7)
- >;
- };
-
- d3_uart0_rtsn: d3-uart0-rtsn-pins {
- pinctrl-single,pins = <
- /* (N3) MCU_UART0_RTSn */
- AM65X_WKUP_IOPAD(0x0054, PIN_OUTPUT, 4)
- >;
- };
-
- d3_gpio: d3-gpio-pins {
- pinctrl-single,pins = <
- /* (N3) WKUP_GPIO0_33 */
- AM65X_WKUP_IOPAD(0x0054, PIN_INPUT, 7)
- >;
- };
-
- d3_gpio_pullup: d3-gpio-pullup-pins {
- pinctrl-single,pins = <
- /* (N3) WKUP_GPIO0_33 */
- AM65X_WKUP_IOPAD(0x0054, PIN_INPUT, 7)
- >;
- };
-
- d3_gpio_pulldown: d3-gpio-pulldown-pins {
- pinctrl-single,pins = <
- /* (N3) WKUP_GPIO0_33 */
- AM65X_WKUP_IOPAD(0x0054, PIN_INPUT_PULLDOWN, 7)
- >;
- };
-
- d10_spi0_cs0: d10-spi0-cs0-pins {
- pinctrl-single,pins = <
- /* (Y4) MCU_SPI0_CS0 */
- AM65X_WKUP_IOPAD(0x009c, PIN_OUTPUT, 0)
- >;
- };
-
- d10_gpio: d10-gpio-pins {
- pinctrl-single,pins = <
- /* (Y4) WKUP_GPIO0_51 */
- AM65X_WKUP_IOPAD(0x009c, PIN_INPUT, 7)
- >;
- };
-
- d10_gpio_pullup: d10-gpio-pullup-pins {
- pinctrl-single,pins = <
- /* (Y4) WKUP_GPIO0_51 */
- AM65X_WKUP_IOPAD(0x009c, PIN_INPUT, 7)
- >;
- };
-
- d10_gpio_pulldown: d10-gpio-pulldown-pins {
- pinctrl-single,pins = <
- /* (Y4) WKUP_GPIO0_51 */
- AM65X_WKUP_IOPAD(0x009c, PIN_INPUT_PULLDOWN, 7)
- >;
- };
-
- d11_spi0_d0: d11-spi0-d0-pins {
- pinctrl-single,pins = <
- /* (Y3) MCU_SPI0_D0 */
- AM65X_WKUP_IOPAD(0x0094, PIN_INPUT, 0)
- >;
- };
-
- d11_gpio: d11-gpio-pins {
- pinctrl-single,pins = <
- /* (Y3) WKUP_GPIO0_49 */
- AM65X_WKUP_IOPAD(0x0094, PIN_INPUT, 7)
- >;
- };
-
- d11_gpio_pullup: d11-gpio-pullup-pins {
- pinctrl-single,pins = <
- /* (Y3) WKUP_GPIO0_49 */
- AM65X_WKUP_IOPAD(0x0094, PIN_INPUT, 7)
- >;
- };
-
- d11_gpio_pulldown: d11-gpio-pulldown-pins {
- pinctrl-single,pins = <
- /* (Y3) WKUP_GPIO0_49 */
- AM65X_WKUP_IOPAD(0x0094, PIN_INPUT_PULLDOWN, 7)
- >;
- };
-
- d12_spi0_d1: d12-spi0-d1-pins {
- pinctrl-single,pins = <
- /* (Y2) MCU_SPI0_D1 */
- AM65X_WKUP_IOPAD(0x0098, PIN_INPUT, 0)
- >;
- };
-
- d12_gpio: d12-gpio-pins {
- pinctrl-single,pins = <
- /* (Y2) WKUP_GPIO0_50 */
- AM65X_WKUP_IOPAD(0x0098, PIN_INPUT, 7)
- >;
- };
-
- d12_gpio_pullup: d12-gpio-pullup-pins {
- pinctrl-single,pins = <
- /* (Y2) WKUP_GPIO0_50 */
- AM65X_WKUP_IOPAD(0x0098, PIN_INPUT, 7)
- >;
- };
-
- d12_gpio_pulldown: d12-gpio-pulldown-pins {
- pinctrl-single,pins = <
- /* (Y2) WKUP_GPIO0_50 */
- AM65X_WKUP_IOPAD(0x0098, PIN_INPUT_PULLDOWN, 7)
- >;
- };
-
- d13_spi0_clk: d13-spi0-clk-pins {
- pinctrl-single,pins = <
- /* (Y1) MCU_SPI0_CLK */
- AM65X_WKUP_IOPAD(0x0090, PIN_INPUT, 0)
- >;
- };
-
- d13_gpio: d13-gpio-pins {
- pinctrl-single,pins = <
- /* (Y1) WKUP_GPIO0_48 */
- AM65X_WKUP_IOPAD(0x0090, PIN_INPUT, 7)
- >;
- };
-
- d13_gpio_pullup: d13-gpio-pullup-pins {
- pinctrl-single,pins = <
- /* (Y1) WKUP_GPIO0_48 */
- AM65X_WKUP_IOPAD(0x0090, PIN_INPUT, 7)
- >;
- };
-
- d13_gpio_pulldown: d13-gpio-pulldown-pins {
- pinctrl-single,pins = <
- /* (Y1) WKUP_GPIO0_48 */
- AM65X_WKUP_IOPAD(0x0090, PIN_INPUT_PULLDOWN, 7)
- >;
- };
-
- a0_gpio: a0-gpio-pins {
- pinctrl-single,pins = <
- /* (L6) WKUP_GPIO0_45 */
- AM65X_WKUP_IOPAD(0x0084, PIN_INPUT, 7)
- >;
- };
-
- a0_gpio_pullup: a0-gpio-pullup-pins {
- pinctrl-single,pins = <
- /* (L6) WKUP_GPIO0_45 */
- AM65X_WKUP_IOPAD(0x0084, PIN_INPUT, 7)
- >;
- };
-
- a0_gpio_pulldown: a0-gpio-pulldown-pins {
- pinctrl-single,pins = <
- /* (L6) WKUP_GPIO0_45 */
- AM65X_WKUP_IOPAD(0x0084, PIN_INPUT_PULLDOWN, 7)
- >;
- };
-
- a1_gpio: a1-gpio-pins {
- pinctrl-single,pins = <
- /* (M6) WKUP_GPIO0_44 */
- AM65X_WKUP_IOPAD(0x0080, PIN_INPUT, 7)
- >;
- };
-
- a1_gpio_pullup: a1-gpio-pullup-pins {
- pinctrl-single,pins = <
- /* (M6) WKUP_GPIO0_44 */
- AM65X_WKUP_IOPAD(0x0080, PIN_INPUT, 7)
- >;
- };
-
- a1_gpio_pulldown: a1-gpio-pulldown-pins {
- pinctrl-single,pins = <
- /* (M6) WKUP_GPIO0_44 */
- AM65X_WKUP_IOPAD(0x0080, PIN_INPUT_PULLDOWN, 7)
- >;
- };
-
- a2_gpio: a2-gpio-pins {
- pinctrl-single,pins = <
- /* (L5) WKUP_GPIO0_43 */
- AM65X_WKUP_IOPAD(0x007C, PIN_INPUT, 7)
- >;
- };
-
- a2_gpio_pullup: a2-gpio-pullup-pins {
- pinctrl-single,pins = <
- /* (L5) WKUP_GPIO0_43 */
- AM65X_WKUP_IOPAD(0x007C, PIN_INPUT, 7)
- >;
- };
-
- a2_gpio_pulldown: a2-gpio-pulldown-pins {
- pinctrl-single,pins = <
- /* (L5) WKUP_GPIO0_43 */
- AM65X_WKUP_IOPAD(0x007C, PIN_INPUT_PULLDOWN, 7)
- >;
- };
-
- a3_gpio: a3-gpio-pins {
- pinctrl-single,pins = <
- /* (M5) WKUP_GPIO0_39 */
- AM65X_WKUP_IOPAD(0x006C, PIN_INPUT, 7)
- >;
- };
-
- a3_gpio_pullup: a3-gpio-pullup-pins {
- pinctrl-single,pins = <
- /* (M5) WKUP_GPIO0_39 */
- AM65X_WKUP_IOPAD(0x006C, PIN_INPUT, 7)
- >;
- };
-
- a3_gpio_pulldown: a3-gpio-pulldown-pins {
- pinctrl-single,pins = <
- /* (M5) WKUP_GPIO0_39 */
- AM65X_WKUP_IOPAD(0x006C, PIN_INPUT_PULLDOWN, 7)
- >;
- };
-
- a4_gpio: a4-gpio-pins {
- pinctrl-single,pins = <
- /* (L2) WKUP_GPIO0_42 */
- AM65X_WKUP_IOPAD(0x0078, PIN_INPUT, 7)
- >;
- };
-
- a4_gpio_pullup: a4-gpio-pullup-pins {
- pinctrl-single,pins = <
- /* (L2) WKUP_GPIO0_42 */
- AM65X_WKUP_IOPAD(0x0078, PIN_INPUT, 7)
- >;
- };
-
- a4_gpio_pulldown: a4-gpio-pulldown-pins {
- pinctrl-single,pins = <
- /* (L2) WKUP_GPIO0_42 */
- AM65X_WKUP_IOPAD(0x0078, PIN_INPUT_PULLDOWN, 7)
- >;
- };
-
- a5_gpio: a5-gpio-pins {
- pinctrl-single,pins = <
- /* (N5) WKUP_GPIO0_35 */
- AM65X_WKUP_IOPAD(0x005C, PIN_INPUT, 7)
- >;
- };
-
- a5_gpio_pullup: a5-gpio-pullup-pins {
- pinctrl-single,pins = <
- /* (N5) WKUP_GPIO0_35 */
- AM65X_WKUP_IOPAD(0x005C, PIN_INPUT_PULLUP, 7)
- >;
- };
-
- a5_gpio_pulldown: a5-gpio-pulldown-pins {
- pinctrl-single,pins = <
- /* (N5) WKUP_GPIO0_35 */
- AM65X_WKUP_IOPAD(0x005C, PIN_INPUT_PULLDOWN, 7)
- >;
- };
-
- wkup_i2c0_pins_default: wkup-i2c0-default-pins {
- pinctrl-single,pins = <
- /* (AC7) WKUP_I2C0_SCL */
- AM65X_WKUP_IOPAD(0x00e0, PIN_INPUT, 0)
- /* (AD6) WKUP_I2C0_SDA */
- AM65X_WKUP_IOPAD(0x00e4, PIN_INPUT, 0)
- >;
- };
-
mcu_i2c0_pins_default: mcu-i2c0-default-pins {
pinctrl-single,pins = <
/* (AD8) MCU_I2C0_SCL */
@@ -623,13 +220,6 @@
>;
};
- arduino_i2c_aio_switch_pins_default: arduino-i2c-aio-switch-default-pins {
- pinctrl-single,pins = <
- /* (R2) WKUP_GPIO0_21 */
- AM65X_WKUP_IOPAD(0x0024, PIN_OUTPUT, 7)
- >;
- };
-
push_button_pins_default: push-button-default-pins {
pinctrl-single,pins = <
/* (T1) MCU_OSPI1_CLK.WKUP_GPIO0_25 */
@@ -637,22 +227,6 @@
>;
};
-
- arduino_io_oe_pins_default: arduino-io-oe-default-pins {
- pinctrl-single,pins = <
- /* (N4) WKUP_GPIO0_34 */
- AM65X_WKUP_IOPAD(0x0058, PIN_OUTPUT, 7)
- /* (M2) WKUP_GPIO0_36 */
- AM65X_WKUP_IOPAD(0x0060, PIN_OUTPUT, 7)
- /* (M3) WKUP_GPIO0_37 */
- AM65X_WKUP_IOPAD(0x0064, PIN_OUTPUT, 7)
- /* (M4) WKUP_GPIO0_38 */
- AM65X_WKUP_IOPAD(0x0068, PIN_OUTPUT, 7)
- /* (M1) WKUP_GPIO0_41 */
- AM65X_WKUP_IOPAD(0x0074, PIN_OUTPUT, 7)
- >;
- };
-
mcu_fss0_ospi0_pins_default: mcu-fss0-ospi0-default-pins {
pinctrl-single,pins = <
/* (V1) MCU_OSPI0_CLK */
@@ -716,214 +290,6 @@
};
&main_pmx0 {
- pinctrl-names =
- "default",
- "d4-ehrpwm0-a", "d4-gpio", "d4-gpio-pullup", "d4-gpio-pulldown",
- "d5-ehrpwm1-a", "d5-gpio", "d5-gpio-pullup", "d5-gpio-pulldown",
- "d6-ehrpwm2-a", "d6-gpio", "d6-gpio-pullup", "d6-gpio-pulldown",
- "d7-ehrpwm3-a", "d7-gpio", "d7-gpio-pullup", "d7-gpio-pulldown",
- "d8-ehrpwm4-a", "d8-gpio", "d8-gpio-pullup", "d8-gpio-pulldown",
- "d9-ehrpwm5-a", "d9-gpio", "d9-gpio-pullup", "d9-gpio-pulldown";
-
- pinctrl-0 = <&d4_ehrpwm0_a>;
- pinctrl-1 = <&d4_ehrpwm0_a>;
- pinctrl-2 = <&d4_gpio>;
- pinctrl-3 = <&d4_gpio_pullup>;
- pinctrl-4 = <&d4_gpio_pulldown>;
-
- pinctrl-5 = <&d5_ehrpwm1_a>;
- pinctrl-6 = <&d5_gpio>;
- pinctrl-7 = <&d5_gpio_pullup>;
- pinctrl-8 = <&d5_gpio_pulldown>;
-
- pinctrl-9 = <&d6_ehrpwm2_a>;
- pinctrl-10 = <&d6_gpio>;
- pinctrl-11 = <&d6_gpio_pullup>;
- pinctrl-12 = <&d6_gpio_pulldown>;
-
- pinctrl-13 = <&d7_ehrpwm3_a>;
- pinctrl-14 = <&d7_gpio>;
- pinctrl-15 = <&d7_gpio_pullup>;
- pinctrl-16 = <&d7_gpio_pulldown>;
-
- pinctrl-17 = <&d8_ehrpwm4_a>;
- pinctrl-18 = <&d8_gpio>;
- pinctrl-19 = <&d8_gpio_pullup>;
- pinctrl-20 = <&d8_gpio_pulldown>;
-
- pinctrl-21 = <&d9_ehrpwm5_a>;
- pinctrl-22 = <&d9_gpio>;
- pinctrl-23 = <&d9_gpio_pullup>;
- pinctrl-24 = <&d9_gpio_pulldown>;
-
- d4_ehrpwm0_a: d4-ehrpwm0-a-pins {
- pinctrl-single,pins = <
- /* (AG18) EHRPWM0_A */
- AM65X_IOPAD(0x0084, PIN_OUTPUT, 5)
- >;
- };
-
- d4_gpio: d4-gpio-pins {
- pinctrl-single,pins = <
- /* (AG18) GPIO0_33 */
- AM65X_IOPAD(0x0084, PIN_INPUT, 7)
- >;
- };
-
- d4_gpio_pullup: d4-gpio-pullup-pins {
- pinctrl-single,pins = <
- /* (AG18) GPIO0_33 */
- AM65X_IOPAD(0x0084, PIN_INPUT_PULLUP, 7)
- >;
- };
-
- d4_gpio_pulldown: d4-gpio-pulldown-pins {
- pinctrl-single,pins = <
- /* (AG18) GPIO0_33 */
- AM65X_IOPAD(0x0084, PIN_INPUT_PULLDOWN, 7)
- >;
- };
-
- d5_ehrpwm1_a: d5-ehrpwm1-a-pins {
- pinctrl-single,pins = <
- /* (AF17) EHRPWM1_A */
- AM65X_IOPAD(0x008C, PIN_OUTPUT, 5)
- >;
- };
-
- d5_gpio: d5-gpio-pins {
- pinctrl-single,pins = <
- /* (AF17) GPIO0_35 */
- AM65X_IOPAD(0x008C, PIN_INPUT, 7)
- >;
- };
-
- d5_gpio_pullup: d5-gpio-pullup-pins {
- pinctrl-single,pins = <
- /* (AF17) GPIO0_35 */
- AM65X_IOPAD(0x008C, PIN_INPUT_PULLUP, 7)
- >;
- };
-
- d5_gpio_pulldown: d5-gpio-pulldown-pins {
- pinctrl-single,pins = <
- /* (AF17) GPIO0_35 */
- AM65X_IOPAD(0x008C, PIN_INPUT_PULLDOWN, 7)
- >;
- };
-
- d6_ehrpwm2_a: d6-ehrpwm2-a-pins {
- pinctrl-single,pins = <
- /* (AH16) EHRPWM2_A */
- AM65X_IOPAD(0x0098, PIN_OUTPUT, 5)
- >;
- };
-
- d6_gpio: d6-gpio-pins {
- pinctrl-single,pins = <
- /* (AH16) GPIO0_38 */
- AM65X_IOPAD(0x0098, PIN_INPUT, 7)
- >;
- };
-
- d6_gpio_pullup: d6-gpio-pullup-pins {
- pinctrl-single,pins = <
- /* (AH16) GPIO0_38 */
- AM65X_IOPAD(0x0098, PIN_INPUT_PULLUP, 7)
- >;
- };
-
- d6_gpio_pulldown: d6-gpio-pulldown-pins {
- pinctrl-single,pins = <
- /* (AH16) GPIO0_38 */
- AM65X_IOPAD(0x0098, PIN_INPUT_PULLDOWN, 7)
- >;
- };
-
- d7_ehrpwm3_a: d7-ehrpwm3-a-pins {
- pinctrl-single,pins = <
- /* (AH15) EHRPWM3_A */
- AM65X_IOPAD(0x00AC, PIN_OUTPUT, 5)
- >;
- };
-
- d7_gpio: d7-gpio-pins {
- pinctrl-single,pins = <
- /* (AH15) GPIO0_43 */
- AM65X_IOPAD(0x00AC, PIN_INPUT, 7)
- >;
- };
-
- d7_gpio_pullup: d7-gpio-pullup-pins {
- pinctrl-single,pins = <
- /* (AH15) GPIO0_43 */
- AM65X_IOPAD(0x00AC, PIN_INPUT_PULLUP, 7)
- >;
- };
-
- d7_gpio_pulldown: d7-gpio-pulldown-pins {
- pinctrl-single,pins = <
- /* (AH15) GPIO0_43 */
- AM65X_IOPAD(0x00AC, PIN_INPUT_PULLDOWN, 7)
- >;
- };
-
- d8_ehrpwm4_a: d8-ehrpwm4-a-pins {
- pinctrl-single,pins = <
- /* (AG15) EHRPWM4_A */
- AM65X_IOPAD(0x00C0, PIN_OUTPUT, 5)
- >;
- };
-
- d8_gpio: d8-gpio-pins {
- pinctrl-single,pins = <
- /* (AG15) GPIO0_48 */
- AM65X_IOPAD(0x00C0, PIN_INPUT, 7)
- >;
- };
-
- d8_gpio_pullup: d8-gpio-pullup-pins {
- pinctrl-single,pins = <
- /* (AG15) GPIO0_48 */
- AM65X_IOPAD(0x00C0, PIN_INPUT_PULLUP, 7)
- >;
- };
-
- d8_gpio_pulldown: d8-gpio-pulldown-pins {
- pinctrl-single,pins = <
- /* (AG15) GPIO0_48 */
- AM65X_IOPAD(0x00C0, PIN_INPUT_PULLDOWN, 7)
- >;
- };
-
- d9_ehrpwm5_a: d9-ehrpwm5-a-pins {
- pinctrl-single,pins = <
- /* (AD15) EHRPWM5_A */
- AM65X_IOPAD(0x00CC, PIN_OUTPUT, 5)
- >;
- };
-
- d9_gpio: d9-gpio-pins {
- pinctrl-single,pins = <
- /* (AD15) GPIO0_51 */
- AM65X_IOPAD(0x00CC, PIN_INPUT, 7)
- >;
- };
-
- d9_gpio_pullup: d9-gpio-pullup-pins {
- pinctrl-single,pins = <
- /* (AD15) GPIO0_51 */
- AM65X_IOPAD(0x00CC, PIN_INPUT_PULLUP, 7)
- >;
- };
-
- d9_gpio_pulldown: d9-gpio-pulldown-pins {
- pinctrl-single,pins = <
- /* (AD15) GPIO0_51 */
- AM65X_IOPAD(0x00CC, PIN_INPUT_PULLDOWN, 7)
- >;
- };
-
main_pcie_enable_pins_default: main-pcie-enable-default-pins {
pinctrl-single,pins = <
AM65X_IOPAD(0x01c4, PIN_INPUT_PULLUP, 7) /* (AH13) GPIO1_17 */
@@ -971,45 +337,6 @@
>;
};
- dss_vout1_pins_default: dss-vout1-default-pins {
- pinctrl-single,pins = <
- AM65X_IOPAD(0x0000, PIN_OUTPUT, 1) /* VOUT1_DATA0 */
- AM65X_IOPAD(0x0004, PIN_OUTPUT, 1) /* VOUT1_DATA1 */
- AM65X_IOPAD(0x0008, PIN_OUTPUT, 1) /* VOUT1_DATA2 */
- AM65X_IOPAD(0x000c, PIN_OUTPUT, 1) /* VOUT1_DATA3 */
- AM65X_IOPAD(0x0010, PIN_OUTPUT, 1) /* VOUT1_DATA4 */
- AM65X_IOPAD(0x0014, PIN_OUTPUT, 1) /* VOUT1_DATA5 */
- AM65X_IOPAD(0x0018, PIN_OUTPUT, 1) /* VOUT1_DATA6 */
- AM65X_IOPAD(0x001c, PIN_OUTPUT, 1) /* VOUT1_DATA7 */
- AM65X_IOPAD(0x0020, PIN_OUTPUT, 1) /* VOUT1_DATA8 */
- AM65X_IOPAD(0x0024, PIN_OUTPUT, 1) /* VOUT1_DATA9 */
- AM65X_IOPAD(0x0028, PIN_OUTPUT, 1) /* VOUT1_DATA10 */
- AM65X_IOPAD(0x002c, PIN_OUTPUT, 1) /* VOUT1_DATA11 */
- AM65X_IOPAD(0x0030, PIN_OUTPUT, 1) /* VOUT1_DATA12 */
- AM65X_IOPAD(0x0034, PIN_OUTPUT, 1) /* VOUT1_DATA13 */
- AM65X_IOPAD(0x0038, PIN_OUTPUT, 1) /* VOUT1_DATA14 */
- AM65X_IOPAD(0x003c, PIN_OUTPUT, 1) /* VOUT1_DATA15 */
- AM65X_IOPAD(0x0040, PIN_OUTPUT, 1) /* VOUT1_DATA16 */
- AM65X_IOPAD(0x0044, PIN_OUTPUT, 1) /* VOUT1_DATA17 */
- AM65X_IOPAD(0x0048, PIN_OUTPUT, 1) /* VOUT1_DATA18 */
- AM65X_IOPAD(0x004c, PIN_OUTPUT, 1) /* VOUT1_DATA19 */
- AM65X_IOPAD(0x0050, PIN_OUTPUT, 1) /* VOUT1_DATA20 */
- AM65X_IOPAD(0x0054, PIN_OUTPUT, 1) /* VOUT1_DATA21 */
- AM65X_IOPAD(0x0058, PIN_OUTPUT, 1) /* VOUT1_DATA22 */
- AM65X_IOPAD(0x005c, PIN_OUTPUT, 1) /* VOUT1_DATA23 */
- AM65X_IOPAD(0x0060, PIN_OUTPUT, 1) /* VOUT1_VSYNC */
- AM65X_IOPAD(0x0064, PIN_OUTPUT, 1) /* VOUT1_HSYNC */
- AM65X_IOPAD(0x0068, PIN_OUTPUT, 1) /* VOUT1_PCLK */
- AM65X_IOPAD(0x006c, PIN_OUTPUT, 1) /* VOUT1_DE */
- >;
- };
-
- dp_pins_default: dp-default-pins {
- pinctrl-single,pins = <
- AM65X_IOPAD(0x0078, PIN_OUTPUT, 7) /* (AF18) DP rst_n */
- >;
- };
-
main_i2c2_pins_default: main-i2c2-default-pins {
pinctrl-single,pins = <
AM65X_IOPAD(0x0074, PIN_INPUT, 5) /* (T27) I2C2_SCL */
@@ -1082,57 +409,11 @@
pinctrl-0 = <&main_uart1_pins_default>;
};
-&mcu_uart0 {
- status = "okay";
-};
-
-&main_gpio0 {
- gpio-line-names =
- "main_gpio0-base", "", "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "", "", "",
- "", "", "", "IO4", "", "IO5", "", "", "IO6", "",
- "", "", "", "IO7", "", "", "", "", "IO8", "",
- "", "IO9";
-};
-
&main_gpio1 {
pinctrl-names = "default";
pinctrl-0 = <&main_pcie_enable_pins_default>;
};
-&wkup_gpio0 {
- pinctrl-names = "default";
- pinctrl-0 =
- <&arduino_i2c_aio_switch_pins_default>,
- <&arduino_io_oe_pins_default>,
- <&push_button_pins_default>,
- <&db9_com_mode_pins_default>;
- gpio-line-names =
- /* 0..9 */
- "wkup_gpio0-base", "", "", "", "UART0-mode1", "UART0-mode0",
- "UART0-enable", "UART0-terminate", "", "WIFI-disable",
- /* 10..19 */
- "", "", "", "", "", "", "", "", "", "",
- /* 20..29 */
- "", "A4A5-I2C-mux", "", "", "", "USER-button", "", "", "","IO0",
- /* 30..39 */
- "IO1", "IO2", "", "IO3", "IO17-direction", "A5",
- "IO16-direction", "IO15-direction", "IO14-direction", "A3",
- /* 40..49 */
- "", "IO18-direction", "A4", "A2", "A1", "A0", "", "", "IO13",
- "IO11",
- /* 50..51 */
- "IO12", "IO10";
-};
-
-&wkup_i2c0 {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&wkup_i2c0_pins_default>;
- clock-frequency = <400000>;
-};
-
&mcu_i2c0 {
status = "okay";
pinctrl-names = "default";
@@ -1150,47 +431,6 @@
ti,vsel1-state-high;
ti,enable-vout-discharge;
};
-
- /* D4200 */
- pcal9535_1: gpio@20 {
- compatible = "nxp,pcal9535";
- reg = <0x20>;
- #gpio-cells = <2>;
- gpio-controller;
- gpio-line-names =
- "A0-pull", "A1-pull", "A2-pull", "A3-pull", "A4-pull",
- "A5-pull", "", "",
- "IO14-enable", "IO15-enable", "IO16-enable",
- "IO17-enable", "IO18-enable", "IO19-enable";
- };
-
- /* D4201 */
- pcal9535_2: gpio@21 {
- compatible = "nxp,pcal9535";
- reg = <0x21>;
- #gpio-cells = <2>;
- gpio-controller;
- gpio-line-names =
- "IO0-direction", "IO1-direction", "IO2-direction",
- "IO3-direction", "IO4-direction", "IO5-direction",
- "IO6-direction", "IO7-direction",
- "IO8-direction", "IO9-direction", "IO10-direction",
- "IO11-direction", "IO12-direction", "IO13-direction",
- "IO19-direction";
- };
-
- /* D4202 */
- pcal9535_3: gpio@25 {
- compatible = "nxp,pcal9535";
- reg = <0x25>;
- #gpio-cells = <2>;
- gpio-controller;
- gpio-line-names =
- "IO0-pull", "IO1-pull", "IO2-pull", "IO3-pull",
- "IO4-pull", "IO5-pull", "IO6-pull", "IO7-pull",
- "IO8-pull", "IO9-pull", "IO10-pull", "IO11-pull",
- "IO12-pull", "IO13-pull";
- };
};
&main_i2c0 {
@@ -1233,32 +473,6 @@
#address-cells = <1>;
#size-cells = <0>;
-
- edp-bridge@f {
- compatible = "toshiba,tc358767";
- reg = <0x0f>;
- pinctrl-names = "default";
- pinctrl-0 = <&dp_pins_default>;
- reset-gpios = <&main_gpio0 30 GPIO_ACTIVE_HIGH>;
-
- clock-names = "ref";
- clocks = <&dp_refclk>;
-
- toshiba,hpd-pin = <0>;
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@1 {
- reg = <1>;
-
- bridge_in: endpoint {
- remote-endpoint = <&dpi_out>;
- };
- };
- };
- };
};
&mcu_cpsw {
@@ -1292,13 +506,6 @@
ti,pindir-d0-out-d1-in;
};
-&tscadc1 {
- status = "okay";
- adc {
- ti,adc-channels = <0 1 2 3 4 5>;
- };
-};
-
&ospi0 {
status = "okay";
pinctrl-names = "default";
@@ -1364,26 +571,6 @@
};
};
-&dss {
- pinctrl-names = "default";
- pinctrl-0 = <&dss_vout1_pins_default>;
-
- assigned-clocks = <&k3_clks 67 2>;
- assigned-clock-parents = <&k3_clks 67 5>;
-};
-
-&dss_ports {
- #address-cells = <1>;
- #size-cells = <0>;
- port@1 {
- reg = <1>;
-
- dpi_out: endpoint {
- remote-endpoint = <&bridge_in>;
- };
- };
-};
-
&pcie1_rc {
status = "okay";
pinctrl-names = "default";
@@ -1418,13 +605,17 @@
&mcu_r5fss0_core0 {
memory-region = <&mcu_r5fss0_core0_dma_memory_region>,
<&mcu_r5fss0_core0_memory_region>;
- mboxes = <&mailbox0_cluster0>, <&mbox_mcu_r5fss0_core0>;
+ mboxes = <&mailbox0_cluster0 &mbox_mcu_r5fss0_core0>;
};
&mcu_r5fss0_core1 {
memory-region = <&mcu_r5fss0_core1_dma_memory_region>,
<&mcu_r5fss0_core1_memory_region>;
- mboxes = <&mailbox0_cluster1>, <&mbox_mcu_r5fss0_core1>;
+ mboxes = <&mailbox0_cluster1 &mbox_mcu_r5fss0_core1>;
+};
+
+&mcu_rti1 {
+ memory-region = <&wdt_reset_memory_region>;
};
&icssg0_mdio {
diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-dp.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-dp.dtsi
new file mode 100644
index 000000000000..984cc80913bc
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-dp.dtsi
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) Siemens AG, 2024
+ *
+ * Authors:
+ * Jan Kiszka <jan.kiszka@siemens.com>
+ *
+ * Common bits for IOT2050 variants with Display Port
+ */
+
+&main_pmx0 {
+ dss_vout1_pins_default: dss-vout1-default-pins {
+ pinctrl-single,pins = <
+ AM65X_IOPAD(0x0000, PIN_OUTPUT, 1) /* VOUT1_DATA0 */
+ AM65X_IOPAD(0x0004, PIN_OUTPUT, 1) /* VOUT1_DATA1 */
+ AM65X_IOPAD(0x0008, PIN_OUTPUT, 1) /* VOUT1_DATA2 */
+ AM65X_IOPAD(0x000c, PIN_OUTPUT, 1) /* VOUT1_DATA3 */
+ AM65X_IOPAD(0x0010, PIN_OUTPUT, 1) /* VOUT1_DATA4 */
+ AM65X_IOPAD(0x0014, PIN_OUTPUT, 1) /* VOUT1_DATA5 */
+ AM65X_IOPAD(0x0018, PIN_OUTPUT, 1) /* VOUT1_DATA6 */
+ AM65X_IOPAD(0x001c, PIN_OUTPUT, 1) /* VOUT1_DATA7 */
+ AM65X_IOPAD(0x0020, PIN_OUTPUT, 1) /* VOUT1_DATA8 */
+ AM65X_IOPAD(0x0024, PIN_OUTPUT, 1) /* VOUT1_DATA9 */
+ AM65X_IOPAD(0x0028, PIN_OUTPUT, 1) /* VOUT1_DATA10 */
+ AM65X_IOPAD(0x002c, PIN_OUTPUT, 1) /* VOUT1_DATA11 */
+ AM65X_IOPAD(0x0030, PIN_OUTPUT, 1) /* VOUT1_DATA12 */
+ AM65X_IOPAD(0x0034, PIN_OUTPUT, 1) /* VOUT1_DATA13 */
+ AM65X_IOPAD(0x0038, PIN_OUTPUT, 1) /* VOUT1_DATA14 */
+ AM65X_IOPAD(0x003c, PIN_OUTPUT, 1) /* VOUT1_DATA15 */
+ AM65X_IOPAD(0x0040, PIN_OUTPUT, 1) /* VOUT1_DATA16 */
+ AM65X_IOPAD(0x0044, PIN_OUTPUT, 1) /* VOUT1_DATA17 */
+ AM65X_IOPAD(0x0048, PIN_OUTPUT, 1) /* VOUT1_DATA18 */
+ AM65X_IOPAD(0x004c, PIN_OUTPUT, 1) /* VOUT1_DATA19 */
+ AM65X_IOPAD(0x0050, PIN_OUTPUT, 1) /* VOUT1_DATA20 */
+ AM65X_IOPAD(0x0054, PIN_OUTPUT, 1) /* VOUT1_DATA21 */
+ AM65X_IOPAD(0x0058, PIN_OUTPUT, 1) /* VOUT1_DATA22 */
+ AM65X_IOPAD(0x005c, PIN_OUTPUT, 1) /* VOUT1_DATA23 */
+ AM65X_IOPAD(0x0060, PIN_OUTPUT, 1) /* VOUT1_VSYNC */
+ AM65X_IOPAD(0x0064, PIN_OUTPUT, 1) /* VOUT1_HSYNC */
+ AM65X_IOPAD(0x0068, PIN_OUTPUT, 1) /* VOUT1_PCLK */
+ AM65X_IOPAD(0x006c, PIN_OUTPUT, 1) /* VOUT1_DE */
+ >;
+ };
+
+ dp_pins_default: dp-default-pins {
+ pinctrl-single,pins = <
+ AM65X_IOPAD(0x0078, PIN_OUTPUT, 7) /* (AF18) DP rst_n */
+ >;
+ };
+};
+
+&main_i2c3 {
+ edp-bridge@f {
+ compatible = "toshiba,tc358767";
+ reg = <0x0f>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&dp_pins_default>;
+ reset-gpios = <&main_gpio0 30 GPIO_ACTIVE_HIGH>;
+
+ clock-names = "ref";
+ clocks = <&dp_refclk>;
+
+ toshiba,hpd-pin = <0>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@1 {
+ reg = <1>;
+
+ bridge_in: endpoint {
+ remote-endpoint = <&dpi_out>;
+ };
+ };
+ };
+ };
+};
+
+&dss {
+ pinctrl-names = "default";
+ pinctrl-0 = <&dss_vout1_pins_default>;
+
+ assigned-clocks = <&k3_clks 67 2>;
+ assigned-clock-parents = <&k3_clks 67 5>;
+};
+
+&dss_ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@1 {
+ reg = <1>;
+
+ dpi_out: endpoint {
+ remote-endpoint = <&bridge_in>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-usb3.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-usb3.dtsi
new file mode 100644
index 000000000000..e5bd7c301b12
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-usb3.dtsi
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) Siemens AG, 2024
+ *
+ * Authors:
+ * Jan Kiszka <jan.kiszka@siemens.com>
+ *
+ * Common bits for IOT2050 variants with USB3 support
+ */
+
+&serdes0 {
+ assigned-clocks = <&k3_clks 153 4>, <&serdes0 AM654_SERDES_CMU_REFCLK>;
+ assigned-clock-parents = <&k3_clks 153 7>, <&k3_clks 153 4>;
+};
+
+&dwc3_0 {
+ assigned-clock-parents = <&k3_clks 151 4>, /* set REF_CLK to 20MHz i.e. PER0_PLL/48 */
+ <&k3_clks 151 8>; /* set PIPE3_TXB_CLK to WIZ8B2M4VSB */
+ phys = <&serdes0 PHY_TYPE_USB3 0>;
+ phy-names = "usb3-phy";
+};
+
+&usb0 {
+ maximum-speed = "super-speed";
+ snps,dis-u1-entry-quirk;
+ snps,dis-u2-entry-quirk;
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
index fcea54465636..ff857117d719 100644
--- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for AM6 SoC Family Main Domain peripherals
*
- * Copyright (C) 2016-2018 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2016-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
#include <dt-bindings/phy/phy-am654-serdes.h>
@@ -886,20 +886,6 @@
status = "disabled";
};
- pcie0_ep: pcie-ep@5500000 {
- compatible = "ti,am654-pcie-ep";
- reg = <0x0 0x5500000 0x0 0x1000>, <0x0 0x5501000 0x0 0x1000>, <0x0 0x10000000 0x0 0x8000000>, <0x0 0x5506000 0x0 0x1000>;
- reg-names = "app", "dbics", "addr_space", "atu";
- power-domains = <&k3_pds 120 TI_SCI_PD_EXCLUSIVE>;
- ti,syscon-pcie-mode = <&scm_conf 0x4060>;
- num-ib-windows = <16>;
- num-ob-windows = <16>;
- max-link-speed = <2>;
- dma-coherent;
- interrupts = <GIC_SPI 340 IRQ_TYPE_EDGE_RISING>;
- status = "disabled";
- };
-
pcie1_rc: pcie@5600000 {
compatible = "ti,am654-pcie-rc";
reg = <0x0 0x5600000 0x0 0x1000>, <0x0 0x5601000 0x0 0x1000>, <0x0 0x18000000 0x0 0x2000>, <0x0 0x5606000 0x0 0x1000>;
@@ -921,20 +907,6 @@
status = "disabled";
};
- pcie1_ep: pcie-ep@5600000 {
- compatible = "ti,am654-pcie-ep";
- reg = <0x0 0x5600000 0x0 0x1000>, <0x0 0x5601000 0x0 0x1000>, <0x0 0x18000000 0x0 0x4000000>, <0x0 0x5606000 0x0 0x1000>;
- reg-names = "app", "dbics", "addr_space", "atu";
- power-domains = <&k3_pds 121 TI_SCI_PD_EXCLUSIVE>;
- ti,syscon-pcie-mode = <&scm_conf 0x4070>;
- num-ib-windows = <16>;
- num-ob-windows = <16>;
- max-link-speed = <2>;
- dma-coherent;
- interrupts = <GIC_SPI 355 IRQ_TYPE_EDGE_RISING>;
- status = "disabled";
- };
-
mcasp0: mcasp@2b00000 {
compatible = "ti,am33xx-mcasp-audio";
reg = <0x0 0x02b00000 0x0 0x2000>,
@@ -1019,9 +991,10 @@
<0x0 0x04a07000 0x0 0x1000>, /* ovr1 */
<0x0 0x04a08000 0x0 0x1000>, /* ovr2 */
<0x0 0x04a0a000 0x0 0x1000>, /* vp1 */
- <0x0 0x04a0b000 0x0 0x1000>; /* vp2 */
+ <0x0 0x04a0b000 0x0 0x1000>, /* vp2 */
+ <0x0 0x04a01000 0x0 0x1000>; /* common1 */
reg-names = "common", "vidl1", "vid",
- "ovr1", "ovr2", "vp1", "vp2";
+ "ovr1", "ovr2", "vp1", "vp2", "common1";
ti,am65x-oldi-io-ctrl = <&dss_oldi_io_ctrl>;
@@ -1050,6 +1023,13 @@
};
};
+ gpu: gpu@7000000 {
+ compatible = "ti,am6548-gpu", "img,powervr-sgx544";
+ reg = <0x0 0x7000000 0x0 0x10000>;
+ interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
+ power-domains = <&k3_pds 65 TI_SCI_PD_EXCLUSIVE>;
+ };
+
ehrpwm0: pwm@3000000 {
compatible = "ti,am654-ehrpwm", "ti,am3352-ehrpwm";
#pwm-cells = <3>;
diff --git a/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi
index ecd7356f3315..6ff3ccc39fb4 100644
--- a/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for AM6 SoC Family MCU Domain peripherals
*
- * Copyright (C) 2016-2020 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2016-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
&cbass_mcu {
diff --git a/arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi
index f037b36243ce..37527890ddea 100644
--- a/arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for AM6 SoC Family Wakeup Domain peripherals
*
- * Copyright (C) 2016-2018 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2016-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
&cbass_wakeup {
diff --git a/arch/arm64/boot/dts/ti/k3-am65.dtsi b/arch/arm64/boot/dts/ti/k3-am65.dtsi
index 4d7b6155a76b..c59baebc5a25 100644
--- a/arch/arm64/boot/dts/ti/k3-am65.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am65.dtsi
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for AM6 SoC Family
*
- * Copyright (C) 2016-2018 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2016-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
#include <dt-bindings/gpio/gpio.h>
diff --git a/arch/arm64/boot/dts/ti/k3-am652.dtsi b/arch/arm64/boot/dts/ti/k3-am652.dtsi
index 0f22e00faa90..cbb3caaf82c3 100644
--- a/arch/arm64/boot/dts/ti/k3-am652.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am652.dtsi
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for AM65 SoC family in Dual core configuration
*
- * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
#include "k3-am65.dtsi"
diff --git a/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-common.dtsi b/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-common.dtsi
index 1d6cddb11991..eed6fe70d297 100644
--- a/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-common.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-common.dtsi
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) Siemens AG, 2018-2021
*
@@ -11,6 +11,7 @@
#include "k3-am652.dtsi"
#include "k3-am65-iot2050-common.dtsi"
+#include "k3-am65-iot2050-arduino-connector.dtsi"
/ {
memory@80000000 {
@@ -40,8 +41,3 @@
pinctrl-names = "default";
pinctrl-0 = <&main_uart0_pins_default>;
};
-
-&mcu_r5fss0 {
- /* lock-step mode not supported on Basic boards */
- ti,cluster-mode = <0>;
-};
diff --git a/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-pg2.dts b/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-pg2.dts
index c62549a4b436..c1faf9497b63 100644
--- a/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-pg2.dts
+++ b/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-pg2.dts
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) Siemens AG, 2018-2021
*
@@ -17,6 +17,8 @@
#include "k3-am6528-iot2050-basic-common.dtsi"
#include "k3-am65-iot2050-common-pg2.dtsi"
+#include "k3-am65-iot2050-dp.dtsi"
+#include "k3-am65-iot2050-usb3.dtsi"
/ {
compatible = "siemens,iot2050-basic-pg2", "ti,am654";
diff --git a/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic.dts b/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic.dts
index 87928ff28214..29a31891b3db 100644
--- a/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic.dts
+++ b/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic.dts
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) Siemens AG, 2018-2021
*
@@ -22,3 +22,8 @@
compatible = "siemens,iot2050-basic", "ti,am654";
model = "SIMATIC IOT2050 Basic";
};
+
+&mcu_r5fss0 {
+ /* lock-step mode not supported on this board */
+ ti,cluster-mode = <0>;
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am654-base-board-rocktech-rk101-panel.dtso b/arch/arm64/boot/dts/ti/k3-am654-base-board-rocktech-rk101-panel.dtso
index 3be92c39ecba..364c57b3b3a0 100644
--- a/arch/arm64/boot/dts/ti/k3-am654-base-board-rocktech-rk101-panel.dtso
+++ b/arch/arm64/boot/dts/ti/k3-am654-base-board-rocktech-rk101-panel.dtso
@@ -1,10 +1,10 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/**
* OLDI-LCD1EVM Rocktech integrated panel and touch DT overlay for AM654-EVM.
* Panel Link: https://www.digimax.it/en/tft-lcd/20881-RK101II01D-CT
* AM654 LCD EVM: https://www.ti.com/tool/TMDSLCD1EVM
*
- * Copyright (C) 2023 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
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 822c288d2797..aba0c52b1213 100644
--- a/arch/arm64/boot/dts/ti/k3-am654-base-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-am654-base-board.dts
@@ -1,6 +1,6 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
- * Copyright (C) 2016-2020 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2016-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
@@ -531,13 +531,13 @@
&mcu_r5fss0_core0 {
memory-region = <&mcu_r5fss0_core0_dma_memory_region>,
<&mcu_r5fss0_core0_memory_region>;
- mboxes = <&mailbox0_cluster0>, <&mbox_mcu_r5fss0_core0>;
+ mboxes = <&mailbox0_cluster0 &mbox_mcu_r5fss0_core0>;
};
&mcu_r5fss0_core1 {
memory-region = <&mcu_r5fss0_core1_dma_memory_region>,
<&mcu_r5fss0_core1_memory_region>;
- mboxes = <&mailbox0_cluster1>, <&mbox_mcu_r5fss0_core1>;
+ mboxes = <&mailbox0_cluster1 &mbox_mcu_r5fss0_core1>;
};
&ospi0 {
diff --git a/arch/arm64/boot/dts/ti/k3-am654-icssg2.dtso b/arch/arm64/boot/dts/ti/k3-am654-icssg2.dtso
index ec8cf20ca3ac..0a6e75265ba9 100644
--- a/arch/arm64/boot/dts/ti/k3-am654-icssg2.dtso
+++ b/arch/arm64/boot/dts/ti/k3-am654-icssg2.dtso
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/**
* DT overlay for IDK application board on AM654 EVM
*
- * Copyright (C) 2018-2023 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2018-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
diff --git a/arch/arm64/boot/dts/ti/k3-am654-idk.dtso b/arch/arm64/boot/dts/ti/k3-am654-idk.dtso
index 150428dfce6f..8bdb87fcbde0 100644
--- a/arch/arm64/boot/dts/ti/k3-am654-idk.dtso
+++ b/arch/arm64/boot/dts/ti/k3-am654-idk.dtso
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/**
* DT overlay for IDK application board on AM654 EVM
*
- * Copyright (C) 2018-2023 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2018-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
diff --git a/arch/arm64/boot/dts/ti/k3-am654-industrial-thermal.dtsi b/arch/arm64/boot/dts/ti/k3-am654-industrial-thermal.dtsi
index 9021c738056b..de5a2ed907a7 100644
--- a/arch/arm64/boot/dts/ti/k3-am654-industrial-thermal.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am654-industrial-thermal.dtsi
@@ -1,4 +1,7 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2020-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
#include <dt-bindings/thermal/thermal.h>
diff --git a/arch/arm64/boot/dts/ti/k3-am654-pcie-usb2.dtso b/arch/arm64/boot/dts/ti/k3-am654-pcie-usb2.dtso
new file mode 100644
index 000000000000..c3cb752f8cd7
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am654-pcie-usb2.dtso
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/**
+ * DT overlay for SERDES personality card: 2lane PCIe + USB2.0 Host on AM654 EVM
+ *
+ * Copyright (C) 2018-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/phy/phy-am654-serdes.h>
+#include "k3-pinctrl.h"
+
+&serdes0 {
+ assigned-clocks = <&k3_clks 153 4>,
+ <&serdes0 AM654_SERDES_CMU_REFCLK>,
+ <&serdes0 AM654_SERDES_RO_REFCLK>;
+ assigned-clock-parents = <&k3_clks 153 8>,
+ <&k3_clks 153 4>,
+ <&k3_clks 153 4>;
+ status = "okay";
+};
+
+&serdes1 {
+ assigned-clocks = <&serdes1 AM654_SERDES_CMU_REFCLK>;
+ assigned-clock-parents = <&serdes0 AM654_SERDES_RO_REFCLK>;
+ status = "okay";
+};
+
+&pcie0_rc {
+ num-lanes = <2>;
+ phys = <&serdes0 PHY_TYPE_PCIE 1>, <&serdes1 PHY_TYPE_PCIE 1>;
+ phy-names = "pcie-phy0", "pcie-phy1";
+ reset-gpios = <&pca9555 5 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&main_pmx0 {
+ usb0_pins_default: usb0-default-pins {
+ pinctrl-single,pins = <
+ AM65X_IOPAD(0x02bc, PIN_OUTPUT, 0) /* (AD9) USB0_DRVVBUS */
+ >;
+ };
+};
+
+&dwc3_0 {
+ status = "okay";
+};
+
+&usb0_phy {
+ status = "okay";
+};
+
+&usb0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_pins_default>;
+ dr_mode = "host";
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am654-pcie-usb3.dtso b/arch/arm64/boot/dts/ti/k3-am654-pcie-usb3.dtso
new file mode 100644
index 000000000000..333e423e8bb6
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am654-pcie-usb3.dtso
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/**
+ * DT overlay for SERDES personality card: 1lane PCIe + USB3.0 DRD on AM654 EVM
+ *
+ * Copyright (C) 2018-2024 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/phy/phy-am654-serdes.h>
+
+#include "k3-pinctrl.h"
+
+&serdes1 {
+ status = "okay";
+};
+
+&pcie1_rc {
+ num-lanes = <1>;
+ phys = <&serdes1 PHY_TYPE_PCIE 0>;
+ phy-names = "pcie-phy0";
+ reset-gpios = <&pca9555 5 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&main_pmx0 {
+ usb0_pins_default: usb0-default-pins {
+ pinctrl-single,pins = <
+ AM65X_IOPAD(0x02bc, PIN_OUTPUT, 0) /* (AD9) USB0_DRVVBUS */
+ >;
+ };
+};
+
+&serdes0 {
+ status = "okay";
+ assigned-clocks = <&k3_clks 153 4>, <&serdes0 AM654_SERDES_CMU_REFCLK>;
+ assigned-clock-parents = <&k3_clks 153 7>, <&k3_clks 153 4>;
+};
+
+&dwc3_0 {
+ status = "okay";
+ assigned-clock-parents = <&k3_clks 151 4>, /* set REF_CLK to 20MHz i.e. PER0_PLL/48 */
+ <&k3_clks 151 8>; /* set PIPE3_TXB_CLK to WIZ8B2M4VSB */
+ phys = <&serdes0 PHY_TYPE_USB3 0>;
+ phy-names = "usb3-phy";
+};
+
+&usb0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb0_pins_default>;
+ dr_mode = "host";
+ maximum-speed = "super-speed";
+ snps,dis-u1-entry-quirk;
+ snps,dis-u2-entry-quirk;
+};
+
+&usb0_phy {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am654.dtsi b/arch/arm64/boot/dts/ti/k3-am654.dtsi
index 888567b921f0..bb77c8454734 100644
--- a/arch/arm64/boot/dts/ti/k3-am654.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am654.dtsi
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for AM6 SoC family in Quad core configuration
*
- * Copyright (C) 2016-2018 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2016-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
#include "k3-am65.dtsi"
diff --git a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-common.dtsi b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-common.dtsi
index 3864ec54e371..ae842b85b70d 100644
--- a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-common.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-common.dtsi
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) Siemens AG, 2018-2021
*
diff --git a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts
index bd6f2e696e94..cc619bbec181 100644
--- a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts
+++ b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-m2.dts
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) Siemens AG, 2018-2023
*
@@ -15,17 +15,14 @@
#include "k3-am6548-iot2050-advanced-common.dtsi"
#include "k3-am65-iot2050-common-pg2.dtsi"
+#include "k3-am65-iot2050-arduino-connector.dtsi"
+#include "k3-am65-iot2050-dp.dtsi"
/ {
compatible = "siemens,iot2050-advanced-m2", "ti,am654";
model = "SIMATIC IOT2050 Advanced M2";
};
-&mcu_r5fss0 {
- /* lock-step mode not supported on this board */
- ti,cluster-mode = <0>;
-};
-
&main_pmx0 {
main_bkey_pcie_reset: main-bkey-pcie-reset-default-pins {
pinctrl-single,pins = <
@@ -96,16 +93,3 @@
&pcie1_rc {
status = "disabled";
};
-
-&dwc3_0 {
- assigned-clock-parents = <&k3_clks 151 4>, /* set REF_CLK to 20MHz i.e. PER0_PLL/48 */
- <&k3_clks 151 9>; /* set PIPE3_TXB_CLK to CLK_12M_RC/256 (for HS only) */
- /delete-property/ phys;
- /delete-property/ phy-names;
-};
-
-&usb0 {
- maximum-speed = "high-speed";
- /delete-property/ snps,dis-u1-entry-quirk;
- /delete-property/ snps,dis-u2-entry-quirk;
-};
diff --git a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-pg2.dts b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-pg2.dts
index f00dc86d01b9..ec721275e8e2 100644
--- a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-pg2.dts
+++ b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-pg2.dts
@@ -1,6 +1,6 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (c) Siemens AG, 2018-2021
+ * Copyright (c) Siemens AG, 2018-2023
*
* Authors:
* Le Jin <le.jin@siemens.com>
@@ -17,13 +17,11 @@
#include "k3-am6548-iot2050-advanced-common.dtsi"
#include "k3-am65-iot2050-common-pg2.dtsi"
+#include "k3-am65-iot2050-arduino-connector.dtsi"
+#include "k3-am65-iot2050-dp.dtsi"
+#include "k3-am65-iot2050-usb3.dtsi"
/ {
compatible = "siemens,iot2050-advanced-pg2", "ti,am654";
model = "SIMATIC IOT2050 Advanced PG2";
};
-
-&mcu_r5fss0 {
- /* lock-step mode not supported on this board */
- ti,cluster-mode = <0>;
-};
diff --git a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-sm.dts b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-sm.dts
new file mode 100644
index 000000000000..b829f4bcab69
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-sm.dts
@@ -0,0 +1,189 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) Siemens AG, 2023
+ *
+ * Authors:
+ * Baocheng Su <baocheng.su@siemens.com>
+ * Chao Zeng <chao.zeng@siemens.com>
+ * Huaqian Li <huaqian.li@siemens.com>
+ *
+ * AM6548-based (quad-core) IOT2050 SM variant, Product Generation 2
+ * 4 GB RAM, 16 GB eMMC, USB-serial converter on connector X30
+ *
+ * Product homepage:
+ * https://new.siemens.com/global/en/products/automation/pc-based/iot-gateways/simatic-iot2050.html
+ */
+
+/dts-v1/;
+
+#include "k3-am6548-iot2050-advanced-common.dtsi"
+#include "k3-am65-iot2050-common-pg2.dtsi"
+
+/ {
+ compatible = "siemens,iot2050-advanced-sm", "ti,am654";
+ model = "SIMATIC IOT2050 Advanced SM";
+
+ memory@80000000 {
+ device_type = "memory";
+ /* 4G RAM */
+ reg = <0x00000000 0x80000000 0x00000000 0x80000000>,
+ <0x00000008 0x80000000 0x00000000 0x80000000>;
+ };
+
+ aliases {
+ spi1 = &main_spi0;
+ };
+
+ leds {
+ pinctrl-0 = <&leds_pins_default>, <&user1_led_pins>;
+
+ led-2 {
+ gpios = <&wkup_gpio0 52 GPIO_ACTIVE_HIGH>;
+ };
+
+ led-3 {
+ gpios = <&wkup_gpio0 53 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&main_pmx0 {
+ main_pcie_enable_pins_default: main-pcie-enable-default-pins {
+ pinctrl-single,pins = <
+ AM65X_IOPAD(0x01d8, PIN_OUTPUT, 7) /* (AH12) GPIO1_22 */
+ >;
+ };
+
+ main_spi0_pins: main-spi0-default-pins {
+ pinctrl-single,pins = <
+ AM65X_IOPAD(0x01c4, PIN_INPUT, 0) /* (AH13) SPI0_CLK */
+ AM65X_IOPAD(0x01c8, PIN_INPUT, 0) /* (AE13) SPI0_D0 */
+ AM65X_IOPAD(0x01cc, PIN_INPUT, 0) /* (AD13) SPI0_D1 */
+ AM65X_IOPAD(0x01bc, PIN_OUTPUT, 0) /* (AG13) SPI0_CS0 */
+ >;
+ };
+};
+
+&main_pmx1 {
+ asic_spi_mux_ctrl_pin: asic-spi-mux-ctrl-default-pins {
+ pinctrl-single,pins = <
+ AM65X_IOPAD(0x0010, PIN_OUTPUT, 7) /* (D21) GPIO1_86 */
+ >;
+ };
+};
+
+&wkup_pmx0 {
+ user1_led_pins: user1-led-default-pins {
+ pinctrl-single,pins = <
+ /* (AB1) WKUP_UART0_RXD:WKUP_GPIO0_52, as USER 1 led red */
+ AM65X_WKUP_IOPAD(0x00a0, PIN_OUTPUT, 7)
+ /* (AB5) WKUP_UART0_TXD:WKUP_GPIO0_53, as USER 1 led green */
+ AM65X_WKUP_IOPAD(0x00a4, PIN_OUTPUT, 7)
+ >;
+ };
+
+ soc_asic_pins: soc-asic-default-pins {
+ pinctrl-single,pins = <
+ AM65X_WKUP_IOPAD(0x0044, PIN_INPUT, 7) /* (P4) WKUP_GPIO0_29 */
+ AM65X_WKUP_IOPAD(0x0048, PIN_INPUT, 7) /* (P5) WKUP_GPIO0_30 */
+ AM65X_WKUP_IOPAD(0x004c, PIN_INPUT, 7) /* (P1) WKUP_GPIO0_31 */
+ >;
+ };
+};
+
+&main_gpio0 {
+ gpio-line-names = "main_gpio0-base";
+};
+
+&main_gpio1 {
+ pinctrl-names = "default";
+ pinctrl-0 =
+ <&cp2102n_reset_pin_default>,
+ <&main_pcie_enable_pins_default>,
+ <&asic_spi_mux_ctrl_pin>;
+ gpio-line-names =
+ /* 0..9 */
+ "", "", "", "", "", "", "", "", "", "",
+ /* 10..19 */
+ "", "", "", "", "", "", "", "", "", "",
+ /* 20..29 */
+ "", "", "", "", "CP2102N-RESET", "", "", "", "", "",
+ /* 30..39 */
+ "", "", "", "", "", "", "", "", "", "",
+ /* 40..49 */
+ "", "", "", "", "", "", "", "", "", "",
+ /* 50..59 */
+ "", "", "", "", "", "", "", "", "", "",
+ /* 60..69 */
+ "", "", "", "", "", "", "", "", "", "",
+ /* 70..79 */
+ "", "", "", "", "", "", "", "", "", "",
+ /* 80..86 */
+ "", "", "", "", "", "", "ASIC-spi-mux-ctrl";
+};
+
+&wkup_gpio0 {
+ pinctrl-names = "default";
+ pinctrl-0 =
+ <&push_button_pins_default>,
+ <&db9_com_mode_pins_default>,
+ <&soc_asic_pins>;
+ gpio-line-names =
+ /* 0..9 */
+ "wkup_gpio0-base", "", "", "", "UART0-mode1", "UART0-mode0",
+ "UART0-enable", "UART0-terminate", "", "WIFI-disable",
+ /* 10..19 */
+ "", "", "", "", "", "", "", "", "", "",
+ /* 20..29 */
+ "", "", "", "", "", "USER-button", "", "", "","ASIC-gpio-0",
+ /* 30..31 */
+ "ASIC-gpio-1", "ASIC-gpio-2";
+};
+
+&main_spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_spi0_pins>;
+
+ #address-cells = <1>;
+ #size-cells= <0>;
+};
+
+&mcu_spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcu_spi0_pins_default>;
+};
+
+&main_i2c3 {
+ accelerometer: lsm6dso@6a {
+ compatible = "st,lsm6dso";
+ reg = <0x6a>;
+ };
+};
+
+&dss {
+ status = "disabled";
+};
+
+&serdes0 {
+ assigned-clocks = <&k3_clks 153 4>, <&serdes0 AM654_SERDES_CMU_REFCLK>;
+ assigned-clock-parents = <&k3_clks 153 8>, <&k3_clks 153 4>;
+};
+
+&serdes1 {
+ status = "disabled";
+};
+
+&pcie0_rc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&minipcie_pins_default>;
+
+ num-lanes = <1>;
+ phys = <&serdes0 PHY_TYPE_PCIE 1>;
+ phy-names = "pcie-phy0";
+ reset-gpios = <&wkup_gpio0 27 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+};
+
+&pcie1_rc {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced.dts b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced.dts
index 077f165bdc68..649652a540ef 100644
--- a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced.dts
+++ b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced.dts
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) Siemens AG, 2018-2021
*
@@ -17,6 +17,7 @@
#include "k3-am6548-iot2050-advanced-common.dtsi"
#include "k3-am65-iot2050-common-pg1.dtsi"
+#include "k3-am65-iot2050-arduino-connector.dtsi"
/ {
compatible = "siemens,iot2050-advanced", "ti,am654";
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 d0cfdeac21fb..d743f023cdd9 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
@@ -1,6 +1,6 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
- * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
*
* Base Board: https://www.ti.com/lit/zip/SPRR463
*/
@@ -169,6 +169,13 @@
};
};
};
+
+ csi_mux: mux-controller {
+ compatible = "gpio-mux";
+ #mux-state-cells = <1>;
+ mux-gpios = <&exp3 1 GPIO_ACTIVE_HIGH>;
+ idle-state = <0>;
+ };
};
&main_pmx0 {
@@ -186,6 +193,13 @@
>;
};
+ main_i2c1_pins_default: main-i2c1-default-pins {
+ pinctrl-single,pins = <
+ J721S2_IOPAD(0x0ac, PIN_INPUT, 13) /* (AC25) MCASP0_AXR15.I2C1_SCL */
+ J721S2_IOPAD(0x0b0, PIN_INPUT, 13) /* (AD26) MCASP1_AXR3.I2C1_SDA */
+ >;
+ };
+
main_mmc1_pins_default: main-mmc1-default-pins {
pinctrl-single,pins = <
J721S2_IOPAD(0x104, PIN_INPUT, 0) /* (P23) MMC1_CLK */
@@ -431,6 +445,42 @@
};
};
+&main_i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_i2c1_pins_default>;
+ status = "okay";
+
+ exp3: gpio@20 {
+ compatible = "ti,tca6408";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-line-names = "CSI_VIO_SEL", "CSI_SEL_FPC_EXPn",
+ "IO_EXP_CSI2_EXP_RSTz","CSI0_B_GPIO1",
+ "CSI1_B_GPIO1";
+ };
+
+ i2c-mux@70 {
+ compatible = "nxp,pca9543";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x70>;
+
+ cam0_i2c: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+
+ cam1_i2c: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+
+ };
+};
+
&main_i2c4 {
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 20861a0a46b0..0f4a5da0ebc4 100644
--- a/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am68-sk-som.dtsi
@@ -1,6 +1,6 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
- * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
@@ -209,51 +209,51 @@
};
&mcu_r5fss0_core0 {
- mboxes = <&mailbox0_cluster0>, <&mbox_mcu_r5fss0_core0>;
+ mboxes = <&mailbox0_cluster0 &mbox_mcu_r5fss0_core0>;
memory-region = <&mcu_r5fss0_core0_dma_memory_region>,
<&mcu_r5fss0_core0_memory_region>;
};
&mcu_r5fss0_core1 {
- mboxes = <&mailbox0_cluster0>, <&mbox_mcu_r5fss0_core1>;
+ mboxes = <&mailbox0_cluster0 &mbox_mcu_r5fss0_core1>;
memory-region = <&mcu_r5fss0_core1_dma_memory_region>,
<&mcu_r5fss0_core1_memory_region>;
};
&main_r5fss0_core0 {
- mboxes = <&mailbox0_cluster1>, <&mbox_main_r5fss0_core0>;
+ mboxes = <&mailbox0_cluster1 &mbox_main_r5fss0_core0>;
memory-region = <&main_r5fss0_core0_dma_memory_region>,
<&main_r5fss0_core0_memory_region>;
};
&main_r5fss0_core1 {
- mboxes = <&mailbox0_cluster1>, <&mbox_main_r5fss0_core1>;
+ mboxes = <&mailbox0_cluster1 &mbox_main_r5fss0_core1>;
memory-region = <&main_r5fss0_core1_dma_memory_region>,
<&main_r5fss0_core1_memory_region>;
};
&main_r5fss1_core0 {
- mboxes = <&mailbox0_cluster2>, <&mbox_main_r5fss1_core0>;
+ mboxes = <&mailbox0_cluster2 &mbox_main_r5fss1_core0>;
memory-region = <&main_r5fss1_core0_dma_memory_region>,
<&main_r5fss1_core0_memory_region>;
};
&main_r5fss1_core1 {
- mboxes = <&mailbox0_cluster2>, <&mbox_main_r5fss1_core1>;
+ mboxes = <&mailbox0_cluster2 &mbox_main_r5fss1_core1>;
memory-region = <&main_r5fss1_core1_dma_memory_region>,
<&main_r5fss1_core1_memory_region>;
};
&c71_0 {
status = "okay";
- mboxes = <&mailbox0_cluster4>, <&mbox_c71_0>;
+ mboxes = <&mailbox0_cluster4 &mbox_c71_0>;
memory-region = <&c71_0_dma_memory_region>,
<&c71_0_memory_region>;
};
&c71_1 {
status = "okay";
- mboxes = <&mailbox0_cluster4>, <&mbox_c71_1>;
+ mboxes = <&mailbox0_cluster4 &mbox_c71_1>;
memory-region = <&c71_1_dma_memory_region>,
<&c71_1_memory_region>;
};
diff --git a/arch/arm64/boot/dts/ti/k3-am69-sk.dts b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
index 8da591579868..50de2a448a3a 100644
--- a/arch/arm64/boot/dts/ti/k3-am69-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am69-sk.dts
@@ -1,6 +1,6 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
- * Copyright (C) 2022-2023 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
*
* Design Files: https://www.ti.com/lit/zip/SPRR466
* TRM: https://www.ti.com/lit/zip/spruj52
@@ -33,6 +33,7 @@
memory@80000000 {
device_type = "memory";
+ bootph-all;
/* 32G RAM */
reg = <0x00 0x80000000 0x00 0x80000000>,
<0x08 0x80000000 0x07 0x80000000>;
@@ -321,6 +322,38 @@
};
};
};
+
+ csi_mux: mux-controller {
+ compatible = "gpio-mux";
+ #mux-state-cells = <1>;
+ mux-gpios = <&exp2 1 GPIO_ACTIVE_HIGH>;
+ idle-state = <0>;
+ };
+
+ transceiver1: can-phy0 {
+ compatible = "ti,tcan1042";
+ #phy-cells = <0>;
+ max-bitrate = <5000000>;
+ };
+
+ transceiver2: can-phy1 {
+ compatible = "ti,tcan1042";
+ #phy-cells = <0>;
+ max-bitrate = <5000000>;
+ };
+
+ transceiver3: can-phy2 {
+ compatible = "ti,tcan1042";
+ #phy-cells = <0>;
+ max-bitrate = <5000000>;
+ };
+
+ transceiver4: can-phy3 {
+ compatible = "ti,tcan1042";
+ #phy-cells = <0>;
+ max-bitrate = <5000000>;
+ };
+
};
&main_pmx0 {
@@ -340,6 +373,13 @@
>;
};
+ main_i2c1_pins_default: main-i2c1-default-pins {
+ pinctrl-single,pins = <
+ J784S4_IOPAD(0x0ac, PIN_INPUT_PULLUP, 13) /* (AE34) MCASP0_AXR15.I2C1_SCL */
+ J784S4_IOPAD(0x0b0, PIN_INPUT_PULLUP, 13) /* (AL33) MCASP1_AXR3.I2C1_SDA */
+ >;
+ };
+
main_mmc1_pins_default: main-mmc1-default-pins {
bootph-all;
pinctrl-single,pins = <
@@ -429,6 +469,40 @@
J784S4_IOPAD(0x000, PIN_INPUT, 7) /* (AN35) EXTINTN.GPIO0_0 */
>;
};
+
+ main_mcan6_pins_default: main-mcan6-default-pins {
+ pinctrl-single,pins = <
+ J784S4_IOPAD(0x098, PIN_INPUT, 0) /* (AH36) MCAN6_RX */
+ J784S4_IOPAD(0x094, PIN_OUTPUT, 0) /* (AG35) MCAN6_TX */
+ >;
+ };
+
+ main_mcan7_pins_default: main-mcan7-default-pins {
+ pinctrl-single,pins = <
+ J784S4_IOPAD(0x0A0, PIN_INPUT, 0) /* (AD34) MCAN7_RX */
+ J784S4_IOPAD(0x09C, PIN_OUTPUT, 0) /* (AF35) MCAN7_TX */
+ >;
+ };
+
+};
+
+&wkup_pmx0 {
+ bootph-all;
+ mcu_fss0_ospi0_pins_default: mcu-fss0-ospi0-default-pins {
+ pinctrl-single,pins = <
+ J784S4_WKUP_IOPAD(0x000, PIN_OUTPUT, 0) /* (E32) MCU_OSPI0_CLK */
+ J784S4_WKUP_IOPAD(0x02c, PIN_OUTPUT, 0) /* (A32) MCU_OSPI0_CSn0 */
+ J784S4_WKUP_IOPAD(0x00c, PIN_INPUT, 0) /* (B33) MCU_OSPI0_D0 */
+ J784S4_WKUP_IOPAD(0x010, PIN_INPUT, 0) /* (B32) MCU_OSPI0_D1 */
+ J784S4_WKUP_IOPAD(0x014, PIN_INPUT, 0) /* (C33) MCU_OSPI0_D2 */
+ J784S4_WKUP_IOPAD(0x018, PIN_INPUT, 0) /* (C35) MCU_OSPI0_D3 */
+ J784S4_WKUP_IOPAD(0x01c, PIN_INPUT, 0) /* (D33) MCU_OSPI0_D4 */
+ J784S4_WKUP_IOPAD(0x020, PIN_INPUT, 0) /* (D34) MCU_OSPI0_D5 */
+ J784S4_WKUP_IOPAD(0x024, PIN_INPUT, 0) /* (E34) MCU_OSPI0_D6 */
+ J784S4_WKUP_IOPAD(0x028, PIN_INPUT, 0) /* (E33) MCU_OSPI0_D7 */
+ J784S4_WKUP_IOPAD(0x008, PIN_INPUT, 0) /* (C34) MCU_OSPI0_DQS */
+ >;
+ };
};
&wkup_pmx2 {
@@ -525,6 +599,21 @@
J784S4_WKUP_IOPAD(0x090, PIN_INPUT, 7) /* (H37) WKUP_GPIO0_14 */
>;
};
+
+ mcu_mcan0_pins_default: mcu-mcan0-default-pins {
+ pinctrl-single,pins = <
+ J784S4_WKUP_IOPAD(0x054, PIN_INPUT, 0) /* (F38) MCU_MCAN0_RX */
+ J784S4_WKUP_IOPAD(0x050, PIN_OUTPUT, 0) /* (K33) MCU_MCAN0_TX */
+ >;
+ };
+
+ mcu_mcan1_pins_default: mcu-mcan1-default-pins {
+ pinctrl-single,pins = <
+ J784S4_WKUP_IOPAD(0x06c, PIN_INPUT, 0) /* (K36) WKUP_GPIO0_5.MCU_MCAN1_RX */
+ J784S4_WKUP_IOPAD(0x068, PIN_OUTPUT, 0)/* (H35) WKUP_GPIO0_4.MCU_MCAN1_TX */
+ >;
+ };
+
};
&wkup_pmx3 {
@@ -646,7 +735,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pmic_irq_pins_default>;
interrupt-parent = <&wkup_gpio0>;
- interrupts = <39 IRQ_TYPE_EDGE_FALLING>;
+ interrupts = <83 IRQ_TYPE_EDGE_FALLING>;
gpio-controller;
#gpio-cells = <2>;
ti,primary-pmic;
@@ -774,6 +863,42 @@
};
};
+&main_i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_i2c1_pins_default>;
+ clock-frequency = <400000>;
+ status = "okay";
+
+ exp2: gpio@21 {
+ compatible = "ti,tca6408";
+ reg = <0x21>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-line-names = "CSI_VIO_SEL", "CSI_MUX_SEL_2", "CSI2_RSTz",
+ "IO_EXP_CAM0_GPIO1", "IO_EXP_CAM1_GPIO1";
+ };
+
+ i2c-mux@70 {
+ compatible = "nxp,pca9543";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x70>;
+
+ cam0_i2c: i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ };
+
+ cam1_i2c: i2c@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ };
+
+ };
+};
+
&main_sdhci0 {
bootph-all;
/* eMMC */
@@ -822,77 +947,77 @@
};
&mcu_r5fss0_core0 {
- mboxes = <&mailbox0_cluster0>, <&mbox_mcu_r5fss0_core0>;
+ mboxes = <&mailbox0_cluster0 &mbox_mcu_r5fss0_core0>;
memory-region = <&mcu_r5fss0_core0_dma_memory_region>,
<&mcu_r5fss0_core0_memory_region>;
};
&mcu_r5fss0_core1 {
- mboxes = <&mailbox0_cluster0>, <&mbox_mcu_r5fss0_core1>;
+ mboxes = <&mailbox0_cluster0 &mbox_mcu_r5fss0_core1>;
memory-region = <&mcu_r5fss0_core1_dma_memory_region>,
<&mcu_r5fss0_core1_memory_region>;
};
&main_r5fss0_core0 {
- mboxes = <&mailbox0_cluster1>, <&mbox_main_r5fss0_core0>;
+ mboxes = <&mailbox0_cluster1 &mbox_main_r5fss0_core0>;
memory-region = <&main_r5fss0_core0_dma_memory_region>,
<&main_r5fss0_core0_memory_region>;
};
&main_r5fss0_core1 {
- mboxes = <&mailbox0_cluster1>, <&mbox_main_r5fss0_core1>;
+ mboxes = <&mailbox0_cluster1 &mbox_main_r5fss0_core1>;
memory-region = <&main_r5fss0_core1_dma_memory_region>,
<&main_r5fss0_core1_memory_region>;
};
&main_r5fss1_core0 {
- mboxes = <&mailbox0_cluster2>, <&mbox_main_r5fss1_core0>;
+ mboxes = <&mailbox0_cluster2 &mbox_main_r5fss1_core0>;
memory-region = <&main_r5fss1_core0_dma_memory_region>,
<&main_r5fss1_core0_memory_region>;
};
&main_r5fss1_core1 {
- mboxes = <&mailbox0_cluster2>, <&mbox_main_r5fss1_core1>;
+ mboxes = <&mailbox0_cluster2 &mbox_main_r5fss1_core1>;
memory-region = <&main_r5fss1_core1_dma_memory_region>,
<&main_r5fss1_core1_memory_region>;
};
&main_r5fss2_core0 {
- mboxes = <&mailbox0_cluster3>, <&mbox_main_r5fss2_core0>;
+ mboxes = <&mailbox0_cluster3 &mbox_main_r5fss2_core0>;
memory-region = <&main_r5fss2_core0_dma_memory_region>,
<&main_r5fss2_core0_memory_region>;
};
&main_r5fss2_core1 {
- mboxes = <&mailbox0_cluster3>, <&mbox_main_r5fss2_core1>;
+ mboxes = <&mailbox0_cluster3 &mbox_main_r5fss2_core1>;
memory-region = <&main_r5fss2_core1_dma_memory_region>,
<&main_r5fss2_core1_memory_region>;
};
&c71_0 {
status = "okay";
- mboxes = <&mailbox0_cluster4>, <&mbox_c71_0>;
+ mboxes = <&mailbox0_cluster4 &mbox_c71_0>;
memory-region = <&c71_0_dma_memory_region>,
<&c71_0_memory_region>;
};
&c71_1 {
status = "okay";
- mboxes = <&mailbox0_cluster4>, <&mbox_c71_1>;
+ mboxes = <&mailbox0_cluster4 &mbox_c71_1>;
memory-region = <&c71_1_dma_memory_region>,
<&c71_1_memory_region>;
};
&c71_2 {
status = "okay";
- mboxes = <&mailbox0_cluster5>, <&mbox_c71_2>;
+ mboxes = <&mailbox0_cluster5 &mbox_c71_2>;
memory-region = <&c71_2_dma_memory_region>,
<&c71_2_memory_region>;
};
&c71_3 {
status = "okay";
- mboxes = <&mailbox0_cluster5>, <&mbox_c71_3>;
+ mboxes = <&mailbox0_cluster5 &mbox_c71_3>;
memory-region = <&c71_3_dma_memory_region>,
<&c71_3_memory_region>;
};
@@ -918,13 +1043,9 @@
pinctrl-names = "default";
pinctrl-0 = <&dss_vout0_pins_default>;
assigned-clocks = <&k3_clks 218 2>,
- <&k3_clks 218 5>,
- <&k3_clks 218 14>,
- <&k3_clks 218 18>;
+ <&k3_clks 218 5>;
assigned-clock-parents = <&k3_clks 218 3>,
- <&k3_clks 218 7>,
- <&k3_clks 218 16>,
- <&k3_clks 218 22>;
+ <&k3_clks 218 7>;
};
&serdes_wiz4 {
@@ -992,3 +1113,93 @@
};
};
};
+
+&mcu_mcan0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcu_mcan0_pins_default>;
+ phys = <&transceiver1>;
+};
+
+&mcu_mcan1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcu_mcan1_pins_default>;
+ phys = <&transceiver2>;
+};
+
+&main_mcan6 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mcan6_pins_default>;
+ phys = <&transceiver3>;
+};
+
+&main_mcan7 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mcan7_pins_default>;
+ phys = <&transceiver4>;
+};
+
+&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 0x100000>;
+ };
+
+ partition@100000 {
+ label = "ospi.tispl";
+ reg = <0x100000 0x200000>;
+ };
+
+ partition@300000 {
+ label = "ospi.u-boot";
+ reg = <0x300000 0x400000>;
+ };
+
+ partition@700000 {
+ label = "ospi.env";
+ reg = <0x700000 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>;
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
index cee2b4b0eb87..6593c5da82c0 100644
--- a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
@@ -1,6 +1,6 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
- * Copyright (C) 2020 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2020-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
@@ -88,27 +88,56 @@
states = <1800000 0x0>,
<3300000 0x1>;
};
+
+ transceiver1: can-phy1 {
+ compatible = "ti,tcan1043";
+ #phy-cells = <0>;
+ max-bitrate = <5000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcu_mcan0_gpio_pins_default>;
+ standby-gpios = <&wkup_gpio0 58 GPIO_ACTIVE_LOW>;
+ enable-gpios = <&wkup_gpio0 0 GPIO_ACTIVE_HIGH>;
+ };
+
+ transceiver2: can-phy2 {
+ 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>;
+ };
+
+ transceiver3: can-phy3 {
+ compatible = "ti,tcan1043";
+ #phy-cells = <0>;
+ max-bitrate = <5000000>;
+ standby-gpios = <&exp2 7 GPIO_ACTIVE_LOW>;
+ enable-gpios = <&exp2 6 GPIO_ACTIVE_HIGH>;
+ mux-states = <&mux0 1>;
+ };
};
&wkup_pmx0 {
+};
+
+&wkup_pmx2 {
mcu_uart0_pins_default: mcu-uart0-default-pins {
pinctrl-single,pins = <
- J721E_WKUP_IOPAD(0xf4, PIN_INPUT, 0) /* (D20) MCU_UART0_RXD */
- J721E_WKUP_IOPAD(0xf0, PIN_OUTPUT, 0) /* (D19) MCU_UART0_TXD */
- J721E_WKUP_IOPAD(0xf8, PIN_INPUT, 0) /* (E20) MCU_UART0_CTSn */
- J721E_WKUP_IOPAD(0xfc, PIN_OUTPUT, 0) /* (E21) MCU_UART0_RTSn */
+ J721E_WKUP_IOPAD(0x90, PIN_INPUT, 0) /* (E20) MCU_UART0_CTSn */
+ J721E_WKUP_IOPAD(0x94, PIN_OUTPUT, 0) /* (E21) MCU_UART0_RTSn */
+ J721E_WKUP_IOPAD(0x8c, PIN_INPUT, 0) /* (D20) MCU_UART0_RXD */
+ J721E_WKUP_IOPAD(0x88, PIN_OUTPUT, 0) /* (D19) MCU_UART0_TXD */
>;
};
wkup_uart0_pins_default: wkup-uart0-default-pins {
pinctrl-single,pins = <
- J721E_WKUP_IOPAD(0xb0, PIN_INPUT, 0) /* (B14) WKUP_UART0_RXD */
- J721E_WKUP_IOPAD(0xb4, PIN_OUTPUT, 0) /* (A14) WKUP_UART0_TXD */
+ J721E_WKUP_IOPAD(0x48, PIN_INPUT, 0) /* (B14) WKUP_UART0_RXD */
+ J721E_WKUP_IOPAD(0x4c, PIN_OUTPUT, 0) /* (A14) WKUP_UART0_TXD */
>;
};
-};
-&wkup_pmx2 {
mcu_cpsw_pins_default: mcu-cpsw-default-pins {
pinctrl-single,pins = <
J721E_WKUP_IOPAD(0x0000, PIN_OUTPUT, 0) /* MCU_RGMII1_TX_CTL */
@@ -138,6 +167,33 @@
J721E_WKUP_IOPAD(0x0030, PIN_INPUT, 0) /* (L4) MCU_MDIO0_MDIO */
>;
};
+
+ mcu_mcan0_pins_default: mcu-mcan0-default-pins {
+ pinctrl-single,pins = <
+ J721E_WKUP_IOPAD(0x54, PIN_INPUT, 0) /* (A17) MCU_MCAN0_RX */
+ J721E_WKUP_IOPAD(0x50, PIN_OUTPUT, 0) /* (A16) MCU_MCAN0_TX */
+ >;
+ };
+
+ mcu_mcan1_pins_default: mcu-mcan1-default-pins {
+ pinctrl-single,pins = <
+ J721E_WKUP_IOPAD(0x6c, PIN_INPUT, 0) /* (B16) WKUP_GPIO0_5.MCU_MCAN1_RX */
+ J721E_WKUP_IOPAD(0x68, PIN_OUTPUT, 0) /* (D13) WKUP_GPIO0_4.MCU_MCAN1_TX */
+ >;
+ };
+
+ mcu_mcan0_gpio_pins_default: mcu-mcan0-gpio-default-pins {
+ pinctrl-single,pins = <
+ J721E_WKUP_IOPAD(0x58, PIN_INPUT, 7) /* (B18) WKUP_GPIO0_0 */
+ J721E_WKUP_IOPAD(0x40, PIN_INPUT, 7) /* (B17) MCU_SPI0_D1 */
+ >;
+ };
+
+ mcu_mcan1_gpio_pins_default: mcu-mcan1-gpio-default-pins {
+ pinctrl-single,pins = <
+ J721E_WKUP_IOPAD(0x60, PIN_INPUT, 7) /* (D14) WKUP_GPIO0_2 */
+ >;
+ };
};
&main_pmx0 {
@@ -189,6 +245,13 @@
J721E_IOPAD(0xd0, PIN_OUTPUT, 7) /* (T5) SPI0_D1.GPIO0_55 */
>;
};
+
+ main_mcan3_pins_default: main-mcan3-default-pins {
+ pinctrl-single,pins = <
+ J721E_IOPAD(0x3c, PIN_INPUT, 0) /* (W16) MCAN3_RX */
+ J721E_IOPAD(0x38, PIN_OUTPUT, 0) /* (Y21) MCAN3_TX */
+ >;
+ };
};
&main_pmx1 {
@@ -210,7 +273,6 @@
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&mcu_uart0_pins_default>;
- clock-frequency = <96000000>;
};
&main_uart0 {
@@ -382,15 +444,30 @@
};
&pcie1_rc {
+ status = "okay";
reset-gpios = <&exp1 2 GPIO_ACTIVE_HIGH>;
phys = <&serdes0_pcie_link>;
phy-names = "pcie-phy";
num-lanes = <2>;
};
-&pcie1_ep {
- phys = <&serdes0_pcie_link>;
- phy-names = "pcie-phy";
- num-lanes = <2>;
- status = "disabled";
+&mcu_mcan0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcu_mcan0_pins_default>;
+ phys = <&transceiver1>;
+};
+
+&mcu_mcan1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcu_mcan1_pins_default>;
+ phys = <&transceiver2>;
+};
+
+&main_mcan3 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mcan3_pins_default>;
+ phys = <&transceiver3>;
};
diff --git a/arch/arm64/boot/dts/ti/k3-j7200-evm-quad-port-eth-exp.dtso b/arch/arm64/boot/dts/ti/k3-j7200-evm-quad-port-eth-exp.dtso
index 32d905235ed7..6432ca08ee8e 100644
--- a/arch/arm64/boot/dts/ti/k3-j7200-evm-quad-port-eth-exp.dtso
+++ b/arch/arm64/boot/dts/ti/k3-j7200-evm-quad-port-eth-exp.dtso
@@ -1,9 +1,9 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/**
* DT Overlay for CPSW5G in QSGMII mode using J7 Quad Port ETH EXP Add-On Ethernet Card with
* J7200 board.
*
- * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
diff --git a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
index da67bf8fe703..657f9cc9f4ea 100644
--- a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for J7200 SoC Family Main Domain peripherals
*
- * Copyright (C) 2020-2021 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2020-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
/ {
@@ -33,10 +33,11 @@
ranges = <0x00 0x00 0x00100000 0x1c000>;
serdes_ln_ctrl: mux-controller@4080 {
- compatible = "mmio-mux";
+ compatible = "reg-mux";
+ reg = <0x4080 0x20>;
#mux-control-cells = <1>;
- mux-reg-masks = <0x4080 0x3>, <0x4084 0x3>, /* SERDES0 lane0/1 select */
- <0x4088 0x3>, <0x408c 0x3>; /* SERDES0 lane2/3 select */
+ mux-reg-masks = <0x0 0x3>, <0x4 0x3>, /* SERDES0 lane0/1 select */
+ <0x8 0x3>, <0xc 0x3>; /* SERDES0 lane2/3 select */
};
cpsw0_phy_gmii_sel: phy@4044 {
@@ -47,9 +48,10 @@
};
usb_serdes_mux: mux-controller@4000 {
- compatible = "mmio-mux";
+ compatible = "reg-mux";
+ reg = <0x4000 0x4>;
#mux-control-cells = <1>;
- mux-reg-masks = <0x4000 0x8000000>; /* USB0 to SERDES0 lane 1/3 mux */
+ mux-reg-masks = <0x0 0x8000000>; /* USB0 to SERDES0 lane 1/3 mux */
};
};
@@ -399,7 +401,7 @@
/* TIMERIO pad input CTRLMMR_TIMER*_CTRL registers */
main_timerio_input: pinctrl@104200 {
- compatible = "pinctrl-single";
+ compatible = "ti,j7200-padconf", "pinctrl-single";
reg = <0x0 0x104200 0x0 0x50>;
#pinctrl-cells = <1>;
pinctrl-single,register-width = <32>;
@@ -408,7 +410,7 @@
/* TIMERIO pad output CTCTRLMMR_TIMERIO*_CTRL registers */
main_timerio_output: pinctrl@104280 {
- compatible = "pinctrl-single";
+ compatible = "ti,j7200-padconf", "pinctrl-single";
reg = <0x0 0x104280 0x0 0x20>;
#pinctrl-cells = <1>;
pinctrl-single,register-width = <32>;
@@ -416,7 +418,7 @@
};
main_pmx0: pinctrl@11c000 {
- compatible = "pinctrl-single";
+ compatible = "ti,j7200-padconf", "pinctrl-single";
/* Proxy 0 addressing */
reg = <0x00 0x11c000 0x00 0x10c>;
#pinctrl-cells = <1>;
@@ -425,7 +427,7 @@
};
main_pmx1: pinctrl@11c11c {
- compatible = "pinctrl-single";
+ compatible = "ti,j7200-padconf", "pinctrl-single";
/* Proxy 0 addressing */
reg = <0x00 0x11c11c 0x00 0xc>;
#pinctrl-cells = <1>;
@@ -770,26 +772,7 @@
ranges = <0x01000000 0x0 0x18001000 0x00 0x18001000 0x0 0x0010000>,
<0x02000000 0x0 0x18011000 0x00 0x18011000 0x0 0x7fef000>;
dma-ranges = <0x02000000 0x0 0x0 0x0 0x0 0x10000 0x0>;
- };
-
- pcie1_ep: pcie-ep@2910000 {
- compatible = "ti,j7200-pcie-ep", "ti,j721e-pcie-ep";
- reg = <0x00 0x02910000 0x00 0x1000>,
- <0x00 0x02917000 0x00 0x400>,
- <0x00 0x0d800000 0x00 0x00800000>,
- <0x00 0x18000000 0x00 0x08000000>;
- reg-names = "intd_cfg", "user_cfg", "reg", "mem";
- interrupt-names = "link_state";
- interrupts = <GIC_SPI 330 IRQ_TYPE_EDGE_RISING>;
- ti,syscon-pcie-ctrl = <&scm_conf 0x4074>;
- max-link-speed = <3>;
- num-lanes = <4>;
- power-domains = <&k3_pds 240 TI_SCI_PD_EXCLUSIVE>;
- clocks = <&k3_clks 240 6>;
- clock-names = "fck";
- max-functions = /bits/ 8 <6>;
- max-virtual-functions = /bits/ 8 <4 4 4 4 0 0>;
- dma-coherent;
+ status = "disabled";
};
usbss0: cdns-usb@4104000 {
@@ -895,6 +878,276 @@
status = "disabled";
};
+ main_mcan0: can@2701000 {
+ compatible = "bosch,m_can";
+ reg = <0x00 0x02701000 0x00 0x200>,
+ <0x00 0x02708000 0x00 0x8000>;
+ reg-names = "m_can", "message_ram";
+ power-domains = <&k3_pds 156 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 156 0>, <&k3_clks 156 2>;
+ clock-names = "hclk", "cclk";
+ interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+ status = "disabled";
+ };
+
+ main_mcan1: can@2711000 {
+ compatible = "bosch,m_can";
+ reg = <0x00 0x02711000 0x00 0x200>,
+ <0x00 0x02718000 0x00 0x8000>;
+ reg-names = "m_can", "message_ram";
+ power-domains = <&k3_pds 158 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 158 0>, <&k3_clks 158 2>;
+ clock-names = "hclk", "cclk";
+ interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+ status = "disabled";
+ };
+
+ main_mcan2: can@2721000 {
+ compatible = "bosch,m_can";
+ reg = <0x00 0x02721000 0x00 0x200>,
+ <0x00 0x02728000 0x00 0x8000>;
+ reg-names = "m_can", "message_ram";
+ power-domains = <&k3_pds 160 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 160 0>, <&k3_clks 160 2>;
+ clock-names = "hclk", "cclk";
+ interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+ status = "disabled";
+ };
+
+ main_mcan3: can@2731000 {
+ compatible = "bosch,m_can";
+ reg = <0x00 0x02731000 0x00 0x200>,
+ <0x00 0x02738000 0x00 0x8000>;
+ reg-names = "m_can", "message_ram";
+ power-domains = <&k3_pds 161 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 161 0>, <&k3_clks 161 2>;
+ clock-names = "hclk", "cclk";
+ interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+ status = "disabled";
+ };
+
+ main_mcan4: can@2741000 {
+ compatible = "bosch,m_can";
+ reg = <0x00 0x02741000 0x00 0x200>,
+ <0x00 0x02748000 0x00 0x8000>;
+ reg-names = "m_can", "message_ram";
+ power-domains = <&k3_pds 162 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 162 0>, <&k3_clks 162 2>;
+ clock-names = "hclk", "cclk";
+ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+ status = "disabled";
+ };
+
+ main_mcan5: can@2751000 {
+ compatible = "bosch,m_can";
+ reg = <0x00 0x02751000 0x00 0x200>,
+ <0x00 0x02758000 0x00 0x8000>;
+ reg-names = "m_can", "message_ram";
+ power-domains = <&k3_pds 163 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 163 0>, <&k3_clks 163 2>;
+ clock-names = "hclk", "cclk";
+ interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+ status = "disabled";
+ };
+
+ main_mcan6: can@2761000 {
+ compatible = "bosch,m_can";
+ reg = <0x00 0x02761000 0x00 0x200>,
+ <0x00 0x02768000 0x00 0x8000>;
+ reg-names = "m_can", "message_ram";
+ power-domains = <&k3_pds 164 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 164 0>, <&k3_clks 164 2>;
+ clock-names = "hclk", "cclk";
+ interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+ status = "disabled";
+ };
+
+ main_mcan7: can@2771000 {
+ compatible = "bosch,m_can";
+ reg = <0x00 0x02771000 0x00 0x200>,
+ <0x00 0x02778000 0x00 0x8000>;
+ reg-names = "m_can", "message_ram";
+ power-domains = <&k3_pds 165 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 165 0>, <&k3_clks 165 2>;
+ clock-names = "hclk", "cclk";
+ interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+ status = "disabled";
+ };
+
+ main_mcan8: can@2781000 {
+ compatible = "bosch,m_can";
+ reg = <0x00 0x02781000 0x00 0x200>,
+ <0x00 0x02788000 0x00 0x8000>;
+ reg-names = "m_can", "message_ram";
+ power-domains = <&k3_pds 166 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 166 0>, <&k3_clks 166 2>;
+ clock-names = "hclk", "cclk";
+ interrupts = <GIC_SPI 576 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 577 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+ status = "disabled";
+ };
+
+ main_mcan9: can@2791000 {
+ compatible = "bosch,m_can";
+ reg = <0x00 0x02791000 0x00 0x200>,
+ <0x00 0x02798000 0x00 0x8000>;
+ reg-names = "m_can", "message_ram";
+ power-domains = <&k3_pds 167 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 167 0>, <&k3_clks 167 2>;
+ clock-names = "hclk", "cclk";
+ interrupts = <GIC_SPI 579 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 580 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+ status = "disabled";
+ };
+
+ main_mcan10: can@27a1000 {
+ compatible = "bosch,m_can";
+ reg = <0x00 0x027a1000 0x00 0x200>,
+ <0x00 0x027a8000 0x00 0x8000>;
+ reg-names = "m_can", "message_ram";
+ power-domains = <&k3_pds 168 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 168 0>, <&k3_clks 168 2>;
+ clock-names = "hclk", "cclk";
+ interrupts = <GIC_SPI 582 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 583 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+ status = "disabled";
+ };
+
+ main_mcan11: can@27b1000 {
+ compatible = "bosch,m_can";
+ reg = <0x00 0x027b1000 0x00 0x200>,
+ <0x00 0x027b8000 0x00 0x8000>;
+ reg-names = "m_can", "message_ram";
+ power-domains = <&k3_pds 169 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 169 0>, <&k3_clks 169 2>;
+ clock-names = "hclk", "cclk";
+ interrupts = <GIC_SPI 585 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 586 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+ status = "disabled";
+ };
+
+ main_mcan12: can@27c1000 {
+ compatible = "bosch,m_can";
+ reg = <0x00 0x027c1000 0x00 0x200>,
+ <0x00 0x027c8000 0x00 0x8000>;
+ reg-names = "m_can", "message_ram";
+ power-domains = <&k3_pds 170 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 170 0>, <&k3_clks 170 2>;
+ clock-names = "hclk", "cclk";
+ interrupts = <GIC_SPI 588 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 589 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+ status = "disabled";
+ };
+
+ main_mcan13: can@27d1000 {
+ compatible = "bosch,m_can";
+ reg = <0x00 0x027d1000 0x00 0x200>,
+ <0x00 0x027d8000 0x00 0x8000>;
+ reg-names = "m_can", "message_ram";
+ power-domains = <&k3_pds 171 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 171 0>, <&k3_clks 171 2>;
+ clock-names = "hclk", "cclk";
+ interrupts = <GIC_SPI 591 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 592 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+ status = "disabled";
+ };
+
+ main_mcan14: can@2681000 {
+ compatible = "bosch,m_can";
+ reg = <0x00 0x02681000 0x00 0x200>,
+ <0x00 0x02688000 0x00 0x8000>;
+ reg-names = "m_can", "message_ram";
+ power-domains = <&k3_pds 150 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 150 0>, <&k3_clks 150 2>;
+ clock-names = "hclk", "cclk";
+ interrupts = <GIC_SPI 594 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 595 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+ status = "disabled";
+ };
+
+ main_mcan15: can@2691000 {
+ compatible = "bosch,m_can";
+ reg = <0x00 0x02691000 0x00 0x200>,
+ <0x00 0x02698000 0x00 0x8000>;
+ reg-names = "m_can", "message_ram";
+ power-domains = <&k3_pds 151 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 151 0>, <&k3_clks 151 2>;
+ clock-names = "hclk", "cclk";
+ interrupts = <GIC_SPI 597 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 598 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+ status = "disabled";
+ };
+
+ main_mcan16: can@26a1000 {
+ compatible = "bosch,m_can";
+ reg = <0x00 0x026a1000 0x00 0x200>,
+ <0x00 0x026a8000 0x00 0x8000>;
+ reg-names = "m_can", "message_ram";
+ power-domains = <&k3_pds 152 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 152 0>, <&k3_clks 152 2>;
+ clock-names = "hclk", "cclk";
+ interrupts = <GIC_SPI 784 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 785 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+ status = "disabled";
+ };
+
+ main_mcan17: can@26b1000 {
+ compatible = "bosch,m_can";
+ reg = <0x00 0x026b1000 0x00 0x200>,
+ <0x00 0x026b8000 0x00 0x8000>;
+ reg-names = "m_can", "message_ram";
+ power-domains = <&k3_pds 153 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 153 0>, <&k3_clks 153 2>;
+ clock-names = "hclk", "cclk";
+ interrupts = <GIC_SPI 787 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 788 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+ status = "disabled";
+ };
+
main_spi0: spi@2100000 {
compatible = "ti,am654-mcspi","ti,omap4-mcspi";
reg = <0x00 0x02100000 0x00 0x400>;
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 60b26374ae0c..7cf21c99956e 100644
--- a/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for J7200 SoC Family MCU/WAKEUP Domain peripherals
*
- * Copyright (C) 2020-2021 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2020-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
&cbass_mcu_wakeup {
@@ -192,7 +192,7 @@
/* MCU_TIMERIO pad input CTRLMMR_MCU_TIMER*_CTRL registers */
mcu_timerio_input: pinctrl@40f04200 {
- compatible = "pinctrl-single";
+ compatible = "ti,j7200-padconf", "pinctrl-single";
reg = <0x0 0x40f04200 0x0 0x28>;
#pinctrl-cells = <1>;
pinctrl-single,register-width = <32>;
@@ -202,7 +202,7 @@
/* MCU_TIMERIO pad output CTRLMMR_MCU_TIMERIO*_CTRL registers */
mcu_timerio_output: pinctrl@40f04280 {
- compatible = "pinctrl-single";
+ compatible = "ti,j7200-padconf", "pinctrl-single";
reg = <0x0 0x40f04280 0x0 0x28>;
#pinctrl-cells = <1>;
pinctrl-single,register-width = <32>;
@@ -211,7 +211,7 @@
};
wkup_pmx0: pinctrl@4301c000 {
- compatible = "pinctrl-single";
+ compatible = "ti,j7200-padconf", "pinctrl-single";
/* Proxy 0 addressing */
reg = <0x00 0x4301c000 0x00 0x34>;
#pinctrl-cells = <1>;
@@ -220,7 +220,7 @@
};
wkup_pmx1: pinctrl@4301c038 {
- compatible = "pinctrl-single";
+ compatible = "ti,j7200-padconf", "pinctrl-single";
/* Proxy 0 addressing */
reg = <0x00 0x4301c038 0x00 0x8>;
#pinctrl-cells = <1>;
@@ -229,7 +229,7 @@
};
wkup_pmx2: pinctrl@4301c068 {
- compatible = "pinctrl-single";
+ compatible = "ti,j7200-padconf", "pinctrl-single";
/* Proxy 0 addressing */
reg = <0x00 0x4301c068 0x00 0xec>;
#pinctrl-cells = <1>;
@@ -238,7 +238,7 @@
};
wkup_pmx3: pinctrl@4301c174 {
- compatible = "pinctrl-single";
+ compatible = "ti,j7200-padconf", "pinctrl-single";
/* Proxy 0 addressing */
reg = <0x00 0x4301c174 0x00 0x20>;
#pinctrl-cells = <1>;
@@ -518,17 +518,18 @@
status = "disabled";
};
- fss: syscon@47000000 {
- compatible = "syscon", "simple-mfd";
+ fss: bus@47000000 {
+ compatible = "simple-bus";
reg = <0x00 0x47000000 0x00 0x100>;
#address-cells = <2>;
#size-cells = <2>;
ranges;
- hbmc_mux: hbmc-mux {
- compatible = "mmio-mux";
+ hbmc_mux: mux-controller@47000004 {
+ compatible = "reg-mux";
+ reg = <0x00 0x47000004 0x00 0x4>;
#mux-control-cells = <1>;
- mux-reg-masks = <0x4 0x2>; /* HBMC select */
+ mux-reg-masks = <0x0 0x2>; /* HBMC select */
};
hbmc: hyperbus@47034000 {
@@ -655,4 +656,34 @@
ti,esm-pins = <95>;
bootph-pre-ram;
};
+
+ mcu_mcan0: can@40528000 {
+ compatible = "bosch,m_can";
+ reg = <0x00 0x40528000 0x00 0x200>,
+ <0x00 0x40500000 0x00 0x8000>;
+ reg-names = "m_can", "message_ram";
+ power-domains = <&k3_pds 172 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 172 0>, <&k3_clks 172 2>;
+ clock-names = "hclk", "cclk";
+ interrupts = <GIC_SPI 832 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 833 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+ status = "disabled";
+ };
+
+ mcu_mcan1: can@40568000 {
+ compatible = "bosch,m_can";
+ reg = <0x00 0x40568000 0x00 0x200>,
+ <0x00 0x40540000 0x00 0x8000>;
+ reg-names = "m_can", "message_ram";
+ power-domains = <&k3_pds 173 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 173 0>, <&k3_clks 173 2>;
+ clock-names = "hclk", "cclk";
+ interrupts = <GIC_SPI 835 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 836 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "int0", "int1";
+ bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+ status = "disabled";
+ };
};
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 ea47f10d393a..7e6a584ac6f0 100644
--- a/arch/arm64/boot/dts/ti/k3-j7200-som-p0.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j7200-som-p0.dtsi
@@ -1,10 +1,12 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
- * Copyright (C) 2020-2021 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2020-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+
#include "k3-j7200.dtsi"
/ {
@@ -80,6 +82,25 @@
no-map;
};
};
+
+ mux0: mux-controller {
+ compatible = "gpio-mux";
+ #mux-state-cells = <1>;
+ mux-gpios = <&exp_som 1 GPIO_ACTIVE_HIGH>;
+ };
+
+ mux1: mux-controller {
+ compatible = "gpio-mux";
+ #mux-state-cells = <1>;
+ mux-gpios = <&exp_som 2 GPIO_ACTIVE_HIGH>;
+ };
+
+ transceiver0: can-phy0 {
+ /* standby pin has been grounded by default */
+ compatible = "ti,tcan1042";
+ #phy-cells = <0>;
+ max-bitrate = <5000000>;
+ };
};
&wkup_pmx0 {
@@ -142,6 +163,13 @@
J721E_IOPAD(0xd8, PIN_INPUT_PULLUP, 0) /* (W2) I2C0_SDA */
>;
};
+
+ main_mcan0_pins_default: main-mcan0-default-pins {
+ pinctrl-single,pins = <
+ J721E_IOPAD(0x24, PIN_INPUT, 0) /* (V20) MCAN0_RX */
+ J721E_IOPAD(0x20, PIN_OUTPUT, 0) /* (V18) MCAN0_TX */
+ >;
+ };
};
&hbmc {
@@ -222,25 +250,25 @@
};
&mcu_r5fss0_core0 {
- mboxes = <&mailbox0_cluster0>, <&mbox_mcu_r5fss0_core0>;
+ mboxes = <&mailbox0_cluster0 &mbox_mcu_r5fss0_core0>;
memory-region = <&mcu_r5fss0_core0_dma_memory_region>,
<&mcu_r5fss0_core0_memory_region>;
};
&mcu_r5fss0_core1 {
- mboxes = <&mailbox0_cluster0>, <&mbox_mcu_r5fss0_core1>;
+ mboxes = <&mailbox0_cluster0 &mbox_mcu_r5fss0_core1>;
memory-region = <&mcu_r5fss0_core1_dma_memory_region>,
<&mcu_r5fss0_core1_memory_region>;
};
&main_r5fss0_core0 {
- mboxes = <&mailbox0_cluster1>, <&mbox_main_r5fss0_core0>;
+ mboxes = <&mailbox0_cluster1 &mbox_main_r5fss0_core0>;
memory-region = <&main_r5fss0_core0_dma_memory_region>,
<&main_r5fss0_core0_memory_region>;
};
&main_r5fss0_core1 {
- mboxes = <&mailbox0_cluster1>, <&mbox_main_r5fss0_core1>;
+ mboxes = <&mailbox0_cluster1 &mbox_main_r5fss0_core1>;
memory-region = <&main_r5fss0_core1_dma_memory_region>,
<&main_r5fss0_core1_memory_region>;
};
@@ -478,3 +506,10 @@
};
};
};
+
+&main_mcan0 {
+ status = "okay";
+ pinctrl-0 = <&main_mcan0_pins_default>;
+ pinctrl-names = "default";
+ phys = <&transceiver0>;
+};
diff --git a/arch/arm64/boot/dts/ti/k3-j7200-thermal.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-thermal.dtsi
index e7e3a643a6f0..2d22a95a6fdb 100644
--- a/arch/arm64/boot/dts/ti/k3-j7200-thermal.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j7200-thermal.dtsi
@@ -1,4 +1,7 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
#include <dt-bindings/thermal/thermal.h>
diff --git a/arch/arm64/boot/dts/ti/k3-j7200.dtsi b/arch/arm64/boot/dts/ti/k3-j7200.dtsi
index ef73e6d7e858..d411911fdf71 100644
--- a/arch/arm64/boot/dts/ti/k3-j7200.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j7200.dtsi
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for J7200 SoC Family
*
- * Copyright (C) 2020 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2020-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
#include <dt-bindings/interrupt-controller/irq.h>
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts
index 2f954729f353..a2925555fe81 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts
+++ b/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts
@@ -1,9 +1,9 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* https://beagleboard.org/ai-64
- * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/
- * Copyright (C) 2022 Jason Kridner, BeagleBoard.org Foundation
- * Copyright (C) 2022 Robert Nelson, BeagleBoard.org Foundation
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2022-2024 Jason Kridner, BeagleBoard.org Foundation
+ * Copyright (C) 2022-2024 Robert Nelson, BeagleBoard.org Foundation
*/
/dts-v1/;
@@ -936,58 +936,58 @@
};
&mcu_r5fss0_core0 {
- mboxes = <&mailbox0_cluster0>, <&mbox_mcu_r5fss0_core0>;
+ mboxes = <&mailbox0_cluster0 &mbox_mcu_r5fss0_core0>;
memory-region = <&mcu_r5fss0_core0_dma_memory_region>,
<&mcu_r5fss0_core0_memory_region>;
};
&mcu_r5fss0_core1 {
- mboxes = <&mailbox0_cluster0>, <&mbox_mcu_r5fss0_core1>;
+ mboxes = <&mailbox0_cluster0 &mbox_mcu_r5fss0_core1>;
memory-region = <&mcu_r5fss0_core1_dma_memory_region>,
<&mcu_r5fss0_core1_memory_region>;
};
&main_r5fss0_core0 {
- mboxes = <&mailbox0_cluster1>, <&mbox_main_r5fss0_core0>;
+ mboxes = <&mailbox0_cluster1 &mbox_main_r5fss0_core0>;
memory-region = <&main_r5fss0_core0_dma_memory_region>,
<&main_r5fss0_core0_memory_region>;
};
&main_r5fss0_core1 {
- mboxes = <&mailbox0_cluster1>, <&mbox_main_r5fss0_core1>;
+ mboxes = <&mailbox0_cluster1 &mbox_main_r5fss0_core1>;
memory-region = <&main_r5fss0_core1_dma_memory_region>,
<&main_r5fss0_core1_memory_region>;
};
&main_r5fss1_core0 {
- mboxes = <&mailbox0_cluster2>, <&mbox_main_r5fss1_core0>;
+ mboxes = <&mailbox0_cluster2 &mbox_main_r5fss1_core0>;
memory-region = <&main_r5fss1_core0_dma_memory_region>,
<&main_r5fss1_core0_memory_region>;
};
&main_r5fss1_core1 {
- mboxes = <&mailbox0_cluster2>, <&mbox_main_r5fss1_core1>;
+ mboxes = <&mailbox0_cluster2 &mbox_main_r5fss1_core1>;
memory-region = <&main_r5fss1_core1_dma_memory_region>,
<&main_r5fss1_core1_memory_region>;
};
&c66_0 {
status = "okay";
- mboxes = <&mailbox0_cluster3>, <&mbox_c66_0>;
+ mboxes = <&mailbox0_cluster3 &mbox_c66_0>;
memory-region = <&c66_0_dma_memory_region>,
<&c66_0_memory_region>;
};
&c66_1 {
status = "okay";
- mboxes = <&mailbox0_cluster3>, <&mbox_c66_1>;
+ mboxes = <&mailbox0_cluster3 &mbox_c66_1>;
memory-region = <&c66_1_dma_memory_region>,
<&c66_1_memory_region>;
};
&c71_0 {
status = "okay";
- mboxes = <&mailbox0_cluster4>, <&mbox_c71_0>;
+ mboxes = <&mailbox0_cluster4 &mbox_c71_0>;
memory-region = <&c71_0_dma_memory_region>,
<&c71_0_memory_region>;
};
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts
index fe5207ac7d85..8230d53cd696 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts
@@ -1,6 +1,6 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
- * Copyright (C) 2019 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2019-2024 Texas Instruments Incorporated - https://www.ti.com/
*
* Product Link: https://www.ti.com/tool/J721EXCPXEVM
*/
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-evm-gesi-exp-board.dtso b/arch/arm64/boot/dts/ti/k3-j721e-evm-gesi-exp-board.dtso
index 6a7d37575da1..f84aa9f94547 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-evm-gesi-exp-board.dtso
+++ b/arch/arm64/boot/dts/ti/k3-j721e-evm-gesi-exp-board.dtso
@@ -1,11 +1,11 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/**
* DT Overlay for CPSW9G in RGMII mode using J7 GESI EXP BRD board with
* J721E board.
*
* GESI Board Product Link: https://www.ti.com/tool/J7EXPCXEVM
*
- * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-evm-pcie0-ep.dtso b/arch/arm64/boot/dts/ti/k3-j721e-evm-pcie0-ep.dtso
index 0c82a13b65a4..4062709d6579 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-evm-pcie0-ep.dtso
+++ b/arch/arm64/boot/dts/ti/k3-j721e-evm-pcie0-ep.dtso
@@ -1,11 +1,11 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/**
* DT Overlay for enabling PCIE0 instance in Endpoint Configuration with the
* J7 common processor board.
*
* J7 Common Processor Board Product Link: https://www.ti.com/tool/J721EXCPXEVM
*
- * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-evm-quad-port-eth-exp.dtso b/arch/arm64/boot/dts/ti/k3-j721e-evm-quad-port-eth-exp.dtso
index d4c51ffc3d6b..8376fa4b6ee1 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-evm-quad-port-eth-exp.dtso
+++ b/arch/arm64/boot/dts/ti/k3-j721e-evm-quad-port-eth-exp.dtso
@@ -1,9 +1,9 @@
-// SPDX-License-Identifier: GPL-2.0
+// 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
* J721E board.
*
- * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
index 2569b4c08ffb..c7eafbc862f9 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for J721E SoC Family Main Domain peripherals
*
- * Copyright (C) 2016-2020 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2016-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
#include <dt-bindings/phy/phy.h>
#include <dt-bindings/phy/phy-ti.h>
@@ -45,15 +45,15 @@
ranges = <0x0 0x0 0x00100000 0x1c000>;
serdes_ln_ctrl: mux-controller@4080 {
- compatible = "mmio-mux";
- reg = <0x00004080 0x50>;
+ compatible = "reg-mux";
+ reg = <0x4080 0x50>;
#mux-control-cells = <1>;
- mux-reg-masks = <0x4080 0x3>, <0x4084 0x3>, /* SERDES0 lane0/1 select */
- <0x4090 0x3>, <0x4094 0x3>, /* SERDES1 lane0/1 select */
- <0x40a0 0x3>, <0x40a4 0x3>, /* SERDES2 lane0/1 select */
- <0x40b0 0x3>, <0x40b4 0x3>, /* SERDES3 lane0/1 select */
- <0x40c0 0x3>, <0x40c4 0x3>, <0x40c8 0x3>, <0x40cc 0x3>;
- /* SERDES4 lane0/1/2/3 select */
+ mux-reg-masks = <0x0 0x3>, <0x4 0x3>, /* SERDES0 lane0/1 select */
+ <0x10 0x3>, <0x14 0x3>, /* SERDES1 lane0/1 select */
+ <0x20 0x3>, <0x24 0x3>, /* SERDES2 lane0/1 select */
+ <0x30 0x3>, <0x34 0x3>, /* SERDES3 lane0/1 select */
+ <0x40 0x3>, <0x44 0x3>, /* SERDES4 lane0/1 select */
+ <0x48 0x3>, <0x4c 0x3>; /* SERDES4 lane2/3 select */
idle-states = <J721E_SERDES0_LANE0_PCIE0_LANE0>, <J721E_SERDES0_LANE1_PCIE0_LANE1>,
<J721E_SERDES1_LANE0_PCIE1_LANE0>, <J721E_SERDES1_LANE1_PCIE1_LANE1>,
<J721E_SERDES2_LANE0_PCIE2_LANE0>, <J721E_SERDES2_LANE1_PCIE2_LANE1>,
@@ -70,10 +70,11 @@
};
usb_serdes_mux: mux-controller@4000 {
- compatible = "mmio-mux";
+ compatible = "reg-mux";
+ reg = <0x4000 0x20>;
#mux-control-cells = <1>;
- mux-reg-masks = <0x4000 0x8000000>, /* USB0 to SERDES0/3 mux */
- <0x4010 0x8000000>; /* USB1 to SERDES1/2 mux */
+ mux-reg-masks = <0x0 0x8000000>, /* USB0 to SERDES0/3 mux */
+ <0x10 0x8000000>; /* USB1 to SERDES1/2 mux */
};
ehrpwm_tbclk: clock-controller@4140 {
@@ -572,6 +573,128 @@
pinctrl-single,function-mask = <0x0000001f>;
};
+ ti_csi2rx0: ticsi2rx@4500000 {
+ compatible = "ti,j721e-csi2rx-shim";
+ reg = <0x0 0x4500000 0x0 0x1000>;
+ ranges;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ dmas = <&main_udmap 0x4940>;
+ dma-names = "rx0";
+ power-domains = <&k3_pds 26 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+
+ cdns_csi2rx0: csi-bridge@4504000 {
+ compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+ reg = <0x0 0x4504000 0x0 0x1000>;
+ clocks = <&k3_clks 26 2>, <&k3_clks 26 0>, <&k3_clks 26 2>,
+ <&k3_clks 26 2>, <&k3_clks 26 3>, <&k3_clks 26 3>;
+ 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";
+ };
+ };
+ };
+ };
+
+ ti_csi2rx1: ticsi2rx@4510000 {
+ compatible = "ti,j721e-csi2rx-shim";
+ reg = <0x0 0x4510000 0x0 0x1000>;
+ ranges;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ dmas = <&main_udmap 0x4960>;
+ dma-names = "rx0";
+ power-domains = <&k3_pds 27 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+
+ cdns_csi2rx1: csi-bridge@4514000 {
+ compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+ reg = <0x0 0x4514000 0x0 0x1000>;
+ clocks = <&k3_clks 27 2>, <&k3_clks 27 0>, <&k3_clks 27 2>,
+ <&k3_clks 27 2>, <&k3_clks 27 3>, <&k3_clks 27 3>;
+ clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+ "pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+ phys = <&dphy1>;
+ phy-names = "dphy";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csi1_port0: port@0 {
+ reg = <0>;
+ status = "disabled";
+ };
+
+ csi1_port1: port@1 {
+ reg = <1>;
+ status = "disabled";
+ };
+
+ csi1_port2: port@2 {
+ reg = <2>;
+ status = "disabled";
+ };
+
+ csi1_port3: port@3 {
+ reg = <3>;
+ status = "disabled";
+ };
+
+ csi1_port4: port@4 {
+ reg = <4>;
+ status = "disabled";
+ };
+ };
+ };
+ };
+
+ dphy0: phy@4580000 {
+ compatible = "cdns,dphy-rx";
+ reg = <0x0 0x4580000 0x0 0x1100>;
+ #phy-cells = <0>;
+ power-domains = <&k3_pds 147 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+ };
+
+ dphy1: phy@4590000 {
+ compatible = "cdns,dphy-rx";
+ reg = <0x0 0x4590000 0x0 0x1100>;
+ #phy-cells = <0>;
+ power-domains = <&k3_pds 148 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+ };
+
serdes_wiz0: wiz@5000000 {
compatible = "ti,j721e-wiz-16g";
#address-cells = <1>;
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 a74912d9e4da..4618b697fbc4 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for J721E SoC Family MCU/WAKEUP Domain peripherals
*
- * Copyright (C) 2016-2020 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2016-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
&cbass_mcu_wakeup {
@@ -353,9 +353,9 @@
hbmc_mux: mux-controller@47000004 {
compatible = "reg-mux";
- reg = <0x00 0x47000004 0x00 0x2>;
+ reg = <0x00 0x47000004 0x00 0x4>;
#mux-control-cells = <1>;
- mux-reg-masks = <0x4 0x2>; /* HBMC select */
+ mux-reg-masks = <0x0 0x2>; /* HBMC select */
};
hbmc: hyperbus@47034000 {
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-sk-csi2-dual-imx219.dtso b/arch/arm64/boot/dts/ti/k3-j721e-sk-csi2-dual-imx219.dtso
new file mode 100644
index 000000000000..47bb5480b5b0
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-j721e-sk-csi2-dual-imx219.dtso
@@ -0,0 +1,165 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/**
+ * DT Overlay for dual RPi Camera V2.1 (Sony IMX219) interfaced with CSI2
+ * on J721E SK, AM68 SK or AM69-SK board.
+ * https://datasheets.raspberrypi.org/camera/camera-v2-schematic.pdf
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "k3-pinctrl.h"
+
+&{/} {
+ clk_imx219_fixed: imx219-xclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+ };
+};
+
+&csi_mux {
+ idle-state = <1>;
+};
+
+/* CAM0 I2C */
+&cam0_i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ imx219_0: imx219-0@10 {
+ compatible = "sony,imx219";
+ reg = <0x10>;
+
+ clocks = <&clk_imx219_fixed>;
+ clock-names = "xclk";
+
+ port {
+ csi2_cam0: endpoint {
+ remote-endpoint = <&csi2rx0_in_sensor>;
+ link-frequencies = /bits/ 64 <456000000>;
+ clock-lanes = <0>;
+ data-lanes = <1 2>;
+ };
+ };
+ };
+};
+
+/* CAM1 I2C */
+&cam1_i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ imx219_1: imx219-1@10 {
+ compatible = "sony,imx219";
+ reg = <0x10>;
+
+ clocks = <&clk_imx219_fixed>;
+ clock-names = "xclk";
+
+ port {
+ csi2_cam1: endpoint {
+ remote-endpoint = <&csi2rx1_in_sensor>;
+ link-frequencies = /bits/ 64 <456000000>;
+ clock-lanes = <0>;
+ data-lanes = <1 2>;
+ };
+ };
+ };
+};
+
+
+&cdns_csi2rx0 {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csi0_port0: port@0 {
+ reg = <0>;
+ status = "okay";
+
+ csi2rx0_in_sensor: endpoint {
+ remote-endpoint = <&csi2_cam0>;
+ bus-type = <4>; /* CSI2 DPHY. */
+ clock-lanes = <0>;
+ data-lanes = <1 2>;
+ };
+ };
+
+ 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 {
+ status = "okay";
+};
+
+&ti_csi2rx0 {
+ status = "okay";
+};
+
+&cdns_csi2rx1 {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csi1_port0: port@0 {
+ reg = <0>;
+ status = "okay";
+
+ csi2rx1_in_sensor: endpoint {
+ remote-endpoint = <&csi2_cam1>;
+ bus-type = <4>; /* CSI2 DPHY. */
+ clock-lanes = <0>;
+ data-lanes = <1 2>;
+ };
+ };
+
+ csi1_port1: port@1 {
+ reg = <1>;
+ status = "disabled";
+ };
+
+ csi1_port2: port@2 {
+ reg = <2>;
+ status = "disabled";
+ };
+
+ csi1_port3: port@3 {
+ reg = <3>;
+ status = "disabled";
+ };
+
+ csi1_port4: port@4 {
+ reg = <4>;
+ status = "disabled";
+ };
+ };
+};
+
+&dphy1 {
+ status = "okay";
+};
+
+&ti_csi2rx1 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
index 188dfe291a32..0c4575ad8d7c 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
@@ -1,6 +1,6 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
- * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2021-2024 Texas Instruments Incorporated - https://www.ti.com/
*
* J721E SK URL: https://www.ti.com/tool/SK-TDA4VM
*/
@@ -286,6 +286,15 @@
};
};
};
+
+ csi_mux: mux-controller {
+ compatible = "gpio-mux";
+ #mux-state-cells = <1>;
+ mux-gpios = <&main_gpio0 88 GPIO_ACTIVE_HIGH>;
+ idle-state = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_csi_mux_sel_pins_default>;
+ };
};
&main_pmx0 {
@@ -352,6 +361,12 @@
>;
};
+ main_csi_mux_sel_pins_default: main-csi-mux-sel-default-pins {
+ pinctrl-single,pins = <
+ J721E_IOPAD(0x164, PIN_OUTPUT, 7) /* (V29) RGMII5_TD2 */
+ >;
+ };
+
dp0_pins_default: dp0-default-pins {
pinctrl-single,pins = <
J721E_IOPAD(0x1c4, PIN_INPUT, 5) /* SPI0_CS1.DP0_HPD */
@@ -574,7 +589,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pmic_irq_pins_default>;
interrupt-parent = <&wkup_gpio0>;
- interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
+ interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
gpio-controller;
#gpio-cells = <2>;
ti,primary-pmic;
@@ -651,7 +666,7 @@
reg = <0x4c>;
system-power-controller;
interrupt-parent = <&wkup_gpio0>;
- interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
+ interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
gpio-controller;
#gpio-cells = <2>;
buck1234-supply = <&vsys_3v3>;
@@ -858,14 +873,14 @@
reg = <0x70>;
/* CSI0 I2C */
- i2c@0 {
+ cam0_i2c: i2c@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
};
/* CSI1 I2C */
- i2c@1 {
+ cam1_i2c: i2c@1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
@@ -1168,58 +1183,58 @@
};
&mcu_r5fss0_core0 {
- mboxes = <&mailbox0_cluster0>, <&mbox_mcu_r5fss0_core0>;
+ mboxes = <&mailbox0_cluster0 &mbox_mcu_r5fss0_core0>;
memory-region = <&mcu_r5fss0_core0_dma_memory_region>,
<&mcu_r5fss0_core0_memory_region>;
};
&mcu_r5fss0_core1 {
- mboxes = <&mailbox0_cluster0>, <&mbox_mcu_r5fss0_core1>;
+ mboxes = <&mailbox0_cluster0 &mbox_mcu_r5fss0_core1>;
memory-region = <&mcu_r5fss0_core1_dma_memory_region>,
<&mcu_r5fss0_core1_memory_region>;
};
&main_r5fss0_core0 {
- mboxes = <&mailbox0_cluster1>, <&mbox_main_r5fss0_core0>;
+ mboxes = <&mailbox0_cluster1 &mbox_main_r5fss0_core0>;
memory-region = <&main_r5fss0_core0_dma_memory_region>,
<&main_r5fss0_core0_memory_region>;
};
&main_r5fss0_core1 {
- mboxes = <&mailbox0_cluster1>, <&mbox_main_r5fss0_core1>;
+ mboxes = <&mailbox0_cluster1 &mbox_main_r5fss0_core1>;
memory-region = <&main_r5fss0_core1_dma_memory_region>,
<&main_r5fss0_core1_memory_region>;
};
&main_r5fss1_core0 {
- mboxes = <&mailbox0_cluster2>, <&mbox_main_r5fss1_core0>;
+ mboxes = <&mailbox0_cluster2 &mbox_main_r5fss1_core0>;
memory-region = <&main_r5fss1_core0_dma_memory_region>,
<&main_r5fss1_core0_memory_region>;
};
&main_r5fss1_core1 {
- mboxes = <&mailbox0_cluster2>, <&mbox_main_r5fss1_core1>;
+ mboxes = <&mailbox0_cluster2 &mbox_main_r5fss1_core1>;
memory-region = <&main_r5fss1_core1_dma_memory_region>,
<&main_r5fss1_core1_memory_region>;
};
&c66_0 {
status = "okay";
- mboxes = <&mailbox0_cluster3>, <&mbox_c66_0>;
+ mboxes = <&mailbox0_cluster3 &mbox_c66_0>;
memory-region = <&c66_0_dma_memory_region>,
<&c66_0_memory_region>;
};
&c66_1 {
status = "okay";
- mboxes = <&mailbox0_cluster3>, <&mbox_c66_1>;
+ mboxes = <&mailbox0_cluster3 &mbox_c66_1>;
memory-region = <&c66_1_dma_memory_region>,
<&c66_1_memory_region>;
};
&c71_0 {
status = "okay";
- mboxes = <&mailbox0_cluster4>, <&mbox_c71_0>;
+ mboxes = <&mailbox0_cluster4 &mbox_c71_0>;
memory-region = <&c71_0_dma_memory_region>,
<&c71_0_memory_region>;
};
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-som-p0.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-som-p0.dtsi
index a75611eec791..1fae6495db07 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-som-p0.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721e-som-p0.dtsi
@@ -1,6 +1,6 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
- * Copyright (C) 2019-2020 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2019-2024 Texas Instruments Incorporated - https://www.ti.com/
*
* Product Link: https://www.ti.com/tool/J721EXSOMXEVM
*/
@@ -549,58 +549,58 @@
};
&mcu_r5fss0_core0 {
- mboxes = <&mailbox0_cluster0>, <&mbox_mcu_r5fss0_core0>;
+ mboxes = <&mailbox0_cluster0 &mbox_mcu_r5fss0_core0>;
memory-region = <&mcu_r5fss0_core0_dma_memory_region>,
<&mcu_r5fss0_core0_memory_region>;
};
&mcu_r5fss0_core1 {
- mboxes = <&mailbox0_cluster0>, <&mbox_mcu_r5fss0_core1>;
+ mboxes = <&mailbox0_cluster0 &mbox_mcu_r5fss0_core1>;
memory-region = <&mcu_r5fss0_core1_dma_memory_region>,
<&mcu_r5fss0_core1_memory_region>;
};
&main_r5fss0_core0 {
- mboxes = <&mailbox0_cluster1>, <&mbox_main_r5fss0_core0>;
+ mboxes = <&mailbox0_cluster1 &mbox_main_r5fss0_core0>;
memory-region = <&main_r5fss0_core0_dma_memory_region>,
<&main_r5fss0_core0_memory_region>;
};
&main_r5fss0_core1 {
- mboxes = <&mailbox0_cluster1>, <&mbox_main_r5fss0_core1>;
+ mboxes = <&mailbox0_cluster1 &mbox_main_r5fss0_core1>;
memory-region = <&main_r5fss0_core1_dma_memory_region>,
<&main_r5fss0_core1_memory_region>;
};
&main_r5fss1_core0 {
- mboxes = <&mailbox0_cluster2>, <&mbox_main_r5fss1_core0>;
+ mboxes = <&mailbox0_cluster2 &mbox_main_r5fss1_core0>;
memory-region = <&main_r5fss1_core0_dma_memory_region>,
<&main_r5fss1_core0_memory_region>;
};
&main_r5fss1_core1 {
- mboxes = <&mailbox0_cluster2>, <&mbox_main_r5fss1_core1>;
+ mboxes = <&mailbox0_cluster2 &mbox_main_r5fss1_core1>;
memory-region = <&main_r5fss1_core1_dma_memory_region>,
<&main_r5fss1_core1_memory_region>;
};
&c66_0 {
status = "okay";
- mboxes = <&mailbox0_cluster3>, <&mbox_c66_0>;
+ mboxes = <&mailbox0_cluster3 &mbox_c66_0>;
memory-region = <&c66_0_dma_memory_region>,
<&c66_0_memory_region>;
};
&c66_1 {
status = "okay";
- mboxes = <&mailbox0_cluster3>, <&mbox_c66_1>;
+ mboxes = <&mailbox0_cluster3 &mbox_c66_1>;
memory-region = <&c66_1_dma_memory_region>,
<&c66_1_memory_region>;
};
&c71_0 {
status = "okay";
- mboxes = <&mailbox0_cluster4>, <&mbox_c71_0>;
+ mboxes = <&mailbox0_cluster4 &mbox_c71_0>;
memory-region = <&c71_0_dma_memory_region>,
<&c71_0_memory_region>;
};
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-thermal.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-thermal.dtsi
index c2523279001b..927f7614ae7a 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-thermal.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721e-thermal.dtsi
@@ -1,4 +1,7 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
#include <dt-bindings/thermal/thermal.h>
diff --git a/arch/arm64/boot/dts/ti/k3-j721e.dtsi b/arch/arm64/boot/dts/ti/k3-j721e.dtsi
index a200810df54a..5a72c518ceb6 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721e.dtsi
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for J721E SoC Family
*
- * Copyright (C) 2016-2019 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2016-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
#include <dt-bindings/interrupt-controller/irq.h>
diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
index c6b85bbf9a17..c5a0b7cbb14f 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
@@ -1,6 +1,6 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
- * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2021-2024 Texas Instruments Incorporated - https://www.ti.com/
*
* Common Processor Board: https://www.ti.com/tool/J721EXCPXEVM
*/
@@ -147,6 +147,13 @@
>;
};
+ main_i2c5_pins_default: main-i2c5-default-pins {
+ pinctrl-single,pins = <
+ J721S2_IOPAD(0x01c, PIN_INPUT, 8) /* (Y24) MCAN15_TX.I2C5_SCL */
+ J721S2_IOPAD(0x018, PIN_INPUT, 8) /* (W23) MCAN14_RX.I2C5_SDA */
+ >;
+ };
+
main_mmc1_pins_default: main-mmc1-default-pins {
pinctrl-single,pins = <
J721S2_IOPAD(0x104, PIN_INPUT, 0) /* (P23) MMC1_CLK */
@@ -190,8 +197,6 @@
&wkup_pmx2 {
wkup_uart0_pins_default: wkup-uart0-default-pins {
pinctrl-single,pins = <
- J721S2_WKUP_IOPAD(0x070, PIN_INPUT, 0) /* (E25) WKUP_GPIO0_6.WKUP_UART0_CTSn */
- J721S2_WKUP_IOPAD(0x074, PIN_OUTPUT, 0) /* (F28) WKUP_GPIO0_7.WKUP_UART0_RTSn */
J721S2_WKUP_IOPAD(0x048, PIN_INPUT, 0) /* (D28) WKUP_UART0_RXD */
J721S2_WKUP_IOPAD(0x04c, PIN_OUTPUT, 0) /* (D27) WKUP_UART0_TXD */
>;
@@ -356,6 +361,24 @@
};
};
+&main_i2c5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_i2c5_pins_default>;
+ clock-frequency = <400000>;
+ status = "okay";
+
+ exp5: gpio@20 {
+ compatible = "ti,tca6408";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-line-names = "CSI2_EXP_RSTZ", "CSI2_EXP_A_GPIO0",
+ "CSI2_EXP_A_GPIO1", "CSI2_EXP_A_GPIO2",
+ "CSI2_EXP_B_GPIO1", "CSI2_EXP_B_GPIO2",
+ "CSI2_EXP_B_GPIO3", "CSI2_EXP_B_GPIO4";
+ };
+};
+
&main_sdhci0 {
/* eMMC */
status = "okay";
diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-evm-gesi-exp-board.dtso b/arch/arm64/boot/dts/ti/k3-j721s2-evm-gesi-exp-board.dtso
index b78feea31b54..1be28283c7d9 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2-evm-gesi-exp-board.dtso
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-evm-gesi-exp-board.dtso
@@ -1,10 +1,10 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/**
* DT Overlay for MAIN CPSW2G using GESI Expansion Board with J7 common processor board.
*
* GESI Board Product Link: https://www.ti.com/tool/J7EXPCXEVM
*
- * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-evm-pcie1-ep.dtso b/arch/arm64/boot/dts/ti/k3-j721s2-evm-pcie1-ep.dtso
index 43568eb67d93..5ff390915b75 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2-evm-pcie1-ep.dtso
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-evm-pcie1-ep.dtso
@@ -1,11 +1,11 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/**
* DT Overlay for enabling PCIE1 instance in Endpoint Configuration with the
* J7 common processor board.
*
* J7 Common Processor Board Product Link: https://www.ti.com/tool/J721EXCPXEVM
*
- * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
index ea7f2b2ab165..b70c8615e3c1 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for J721S2 SoC Family Main Domain peripherals
*
- * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2021-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
#include <dt-bindings/phy/phy-cadence.h>
@@ -45,7 +45,7 @@
ranges = <0x00 0x00 0x00104000 0x18000>;
usb_serdes_mux: mux-controller@0 {
- compatible = "mmio-mux";
+ compatible = "reg-mux";
reg = <0x0 0x4>;
#mux-control-cells = <1>;
mux-reg-masks = <0x0 0x8000000>; /* USB0 to SERDES0 lane 1/3 mux */
@@ -58,11 +58,11 @@
};
serdes_ln_ctrl: mux-controller@80 {
- compatible = "mmio-mux";
+ compatible = "reg-mux";
reg = <0x80 0x10>;
#mux-control-cells = <1>;
- mux-reg-masks = <0x80 0x3>, <0x84 0x3>, /* SERDES0 lane0/1 select */
- <0x88 0x3>, <0x8c 0x3>; /* SERDES0 lane2/3 select */
+ mux-reg-masks = <0x0 0x3>, <0x4 0x3>, /* SERDES0 lane0/1 select */
+ <0x8 0x3>, <0xc 0x3>; /* SERDES0 lane2/3 select */
};
ehrpwm_tbclk: clock-controller@140 {
@@ -716,6 +716,14 @@
status = "disabled";
};
+ vpu: video-codec@4210000 {
+ compatible = "ti,j721s2-wave521c", "cnm,wave521c";
+ reg = <0x00 0x4210000 0x00 0x10000>;
+ interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&k3_clks 179 2>;
+ power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>;
+ };
+
main_sdhci0: mmc@4f80000 {
compatible = "ti,j721e-sdhci-8bit";
reg = <0x00 0x04f80000 0x00 0x1000>,
@@ -1122,7 +1130,6 @@
ti,sci-dev-id = <225>;
ti,sci-rm-range-rchan = <0x21>;
ti,sci-rm-range-tchan = <0x22>;
- status = "disabled";
};
cpts@310d0000 {
@@ -1233,6 +1240,128 @@
};
};
+ ti_csi2rx0: ticsi2rx@4500000 {
+ compatible = "ti,j721e-csi2rx-shim";
+ reg = <0x00 0x04500000 0x00 0x1000>;
+ ranges;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ dmas = <&main_bcdma_csi 0 0x4940 0>;
+ dma-names = "rx0";
+ power-domains = <&k3_pds 38 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+
+ cdns_csi2rx0: csi-bridge@4504000 {
+ compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+ reg = <0x00 0x04504000 0x00 0x1000>;
+ clocks = <&k3_clks 38 3>, <&k3_clks 38 1>, <&k3_clks 38 3>,
+ <&k3_clks 38 3>, <&k3_clks 38 4>, <&k3_clks 38 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";
+ };
+ };
+ };
+ };
+
+ ti_csi2rx1: ticsi2rx@4510000 {
+ compatible = "ti,j721e-csi2rx-shim";
+ reg = <0x00 0x04510000 0x00 0x1000>;
+ ranges;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ dmas = <&main_bcdma_csi 0 0x4960 0>;
+ dma-names = "rx0";
+ power-domains = <&k3_pds 39 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+
+ cdns_csi2rx1: csi-bridge@4514000 {
+ compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+ reg = <0x00 0x04514000 0x00 0x1000>;
+ clocks = <&k3_clks 39 3>, <&k3_clks 39 1>, <&k3_clks 39 3>,
+ <&k3_clks 39 3>, <&k3_clks 39 4>, <&k3_clks 39 4>;
+ clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+ "pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+ phys = <&dphy1>;
+ phy-names = "dphy";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csi1_port0: port@0 {
+ reg = <0>;
+ status = "disabled";
+ };
+
+ csi1_port1: port@1 {
+ reg = <1>;
+ status = "disabled";
+ };
+
+ csi1_port2: port@2 {
+ reg = <2>;
+ status = "disabled";
+ };
+
+ csi1_port3: port@3 {
+ reg = <3>;
+ status = "disabled";
+ };
+
+ csi1_port4: port@4 {
+ reg = <4>;
+ status = "disabled";
+ };
+ };
+ };
+ };
+
+ dphy0: phy@4580000 {
+ compatible = "cdns,dphy-rx";
+ reg = <0x00 0x04580000 0x00 0x1100>;
+ #phy-cells = <0>;
+ power-domains = <&k3_pds 152 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+ };
+
+ dphy1: phy@4590000 {
+ compatible = "cdns,dphy-rx";
+ reg = <0x00 0x04590000 0x00 0x1100>;
+ #phy-cells = <0>;
+ power-domains = <&k3_pds 153 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+ };
+
serdes_wiz0: wiz@5060000 {
compatible = "ti,j721s2-wiz-10g";
#address-cells = <1>;
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 80aa33c58a45..eaf7f709440e 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for J721S2 SoC Family MCU/WAKEUP Domain peripherals
*
- * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2021-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
&cbass_mcu_wakeup {
@@ -663,7 +663,7 @@
compatible = "ti,j7200-vtm";
reg = <0x00 0x42040000 0x0 0x350>,
<0x00 0x42050000 0x0 0x350>;
- power-domains = <&k3_pds 154 TI_SCI_PD_SHARED>;
+ power-domains = <&k3_pds 180 TI_SCI_PD_SHARED>;
#thermal-sensor-cells = <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 da3237b23b63..623c8421525d 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2-som-p0.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-som-p0.dtsi
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* SoM: https://www.ti.com/lit/zip/sprr439
*
- * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2021-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
/dts-v1/;
@@ -504,51 +504,51 @@
};
&mcu_r5fss0_core0 {
- mboxes = <&mailbox0_cluster0>, <&mbox_mcu_r5fss0_core0>;
+ mboxes = <&mailbox0_cluster0 &mbox_mcu_r5fss0_core0>;
memory-region = <&mcu_r5fss0_core0_dma_memory_region>,
<&mcu_r5fss0_core0_memory_region>;
};
&mcu_r5fss0_core1 {
- mboxes = <&mailbox0_cluster0>, <&mbox_mcu_r5fss0_core1>;
+ mboxes = <&mailbox0_cluster0 &mbox_mcu_r5fss0_core1>;
memory-region = <&mcu_r5fss0_core1_dma_memory_region>,
<&mcu_r5fss0_core1_memory_region>;
};
&main_r5fss0_core0 {
- mboxes = <&mailbox0_cluster1>, <&mbox_main_r5fss0_core0>;
+ mboxes = <&mailbox0_cluster1 &mbox_main_r5fss0_core0>;
memory-region = <&main_r5fss0_core0_dma_memory_region>,
<&main_r5fss0_core0_memory_region>;
};
&main_r5fss0_core1 {
- mboxes = <&mailbox0_cluster1>, <&mbox_main_r5fss0_core1>;
+ mboxes = <&mailbox0_cluster1 &mbox_main_r5fss0_core1>;
memory-region = <&main_r5fss0_core1_dma_memory_region>,
<&main_r5fss0_core1_memory_region>;
};
&main_r5fss1_core0 {
- mboxes = <&mailbox0_cluster2>, <&mbox_main_r5fss1_core0>;
+ mboxes = <&mailbox0_cluster2 &mbox_main_r5fss1_core0>;
memory-region = <&main_r5fss1_core0_dma_memory_region>,
<&main_r5fss1_core0_memory_region>;
};
&main_r5fss1_core1 {
- mboxes = <&mailbox0_cluster2>, <&mbox_main_r5fss1_core1>;
+ mboxes = <&mailbox0_cluster2 &mbox_main_r5fss1_core1>;
memory-region = <&main_r5fss1_core1_dma_memory_region>,
<&main_r5fss1_core1_memory_region>;
};
&c71_0 {
status = "okay";
- mboxes = <&mailbox0_cluster4>, <&mbox_c71_0>;
+ mboxes = <&mailbox0_cluster4 &mbox_c71_0>;
memory-region = <&c71_0_dma_memory_region>,
<&c71_0_memory_region>;
};
&c71_1 {
status = "okay";
- mboxes = <&mailbox0_cluster4>, <&mbox_c71_1>;
+ mboxes = <&mailbox0_cluster4 &mbox_c71_1>;
memory-region = <&c71_1_dma_memory_region>,
<&c71_1_memory_region>;
};
diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-thermal.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2-thermal.dtsi
index f7b1a15b8fa0..e3ef61c1658f 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2-thermal.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721s2-thermal.dtsi
@@ -1,4 +1,7 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
#include <dt-bindings/thermal/thermal.h>
diff --git a/arch/arm64/boot/dts/ti/k3-j721s2.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2.dtsi
index 1f636acd4eee..be4502fe1c9d 100644
--- a/arch/arm64/boot/dts/ti/k3-j721s2.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721s2.dtsi
@@ -1,10 +1,10 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for J721S2 SoC Family
*
* TRM (SPRUJ28 NOVEMBER 2021): https://www.ti.com/lit/pdf/spruj28
*
- * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2021-2024 Texas Instruments Incorporated - https://www.ti.com/
*
*/
diff --git a/arch/arm64/boot/dts/ti/k3-j722s-evm.dts b/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
new file mode 100644
index 000000000000..cee3a8661d5e
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
@@ -0,0 +1,383 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Device Tree file for the J722S EVM
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ * Schematics: https://www.ti.com/lit/zip/sprr495
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/net/ti-dp83867.h>
+#include "k3-j722s.dtsi"
+
+/ {
+ compatible = "ti,j722s-evm", "ti,j722s";
+ model = "Texas Instruments J722S EVM";
+
+ aliases {
+ serial0 = &wkup_uart0;
+ serial2 = &main_uart0;
+ mmc0 = &sdhci0;
+ mmc1 = &sdhci1;
+ };
+
+ chosen {
+ stdout-path = &main_uart0;
+ };
+
+ memory@80000000 {
+ /* 8G RAM */
+ reg = <0x00000000 0x80000000 0x00000000 0x80000000>,
+ <0x00000008 0x80000000 0x00000001 0x80000000>;
+ device_type = "memory";
+ bootph-pre-ram;
+ };
+
+ reserved_memory: reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ secure_tfa_ddr: tfa@9e780000 {
+ reg = <0x00 0x9e780000 0x00 0x80000>;
+ no-map;
+ };
+
+ secure_ddr: optee@9e800000 {
+ reg = <0x00 0x9e800000 0x00 0x01800000>;
+ no-map;
+ };
+
+ wkup_r5fss0_core0_memory_region: r5f-memory@a0100000 {
+ compatible = "shared-dma-pool";
+ reg = <0x00 0xa0100000 0x00 0xf00000>;
+ no-map;
+ };
+
+ };
+
+ vmain_pd: regulator-0 {
+ /* TPS65988 PD CONTROLLER OUTPUT */
+ compatible = "regulator-fixed";
+ regulator-name = "vmain_pd";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ regulator-boot-on;
+ bootph-all;
+ };
+
+ vsys_5v0: regulator-vsys5v0 {
+ /* Output of LM5140 */
+ compatible = "regulator-fixed";
+ regulator-name = "vsys_5v0";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vmain_pd>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vdd_mmc1: regulator-mmc1 {
+ /* TPS22918DBVR */
+ compatible = "regulator-fixed";
+ regulator-name = "vdd_mmc1";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ enable-active-high;
+ gpio = <&exp1 15 GPIO_ACTIVE_HIGH>;
+ bootph-all;
+ };
+
+ vdd_sd_dv: regulator-TLV71033 {
+ compatible = "regulator-gpio";
+ regulator-name = "tlv71033";
+ pinctrl-names = "default";
+ pinctrl-0 = <&vdd_sd_dv_pins_default>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ vin-supply = <&vsys_5v0>;
+ gpios = <&main_gpio0 70 GPIO_ACTIVE_HIGH>;
+ states = <1800000 0x0>,
+ <3300000 0x1>;
+ };
+
+ vsys_io_1v8: regulator-vsys-io-1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "vsys_io_1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vsys_io_1v2: regulator-vsys-io-1v2 {
+ compatible = "regulator-fixed";
+ regulator-name = "vsys_io_1v2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+};
+
+&main_pmx0 {
+
+ main_i2c0_pins_default: main-i2c0-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x01e0, PIN_INPUT_PULLUP, 0) /* (D23) I2C0_SCL */
+ J722S_IOPAD(0x01e4, PIN_INPUT_PULLUP, 0) /* (B22) I2C0_SDA */
+ >;
+ bootph-all;
+ };
+
+ main_uart0_pins_default: main-uart0-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x01c8, PIN_INPUT, 0) /* (A22) UART0_RXD */
+ J722S_IOPAD(0x01cc, PIN_OUTPUT, 0) /* (B22) UART0_TXD */
+ >;
+ bootph-all;
+ };
+
+ vdd_sd_dv_pins_default: vdd-sd-dv-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x0120, PIN_INPUT, 7) /* (F27) MMC2_CMD.GPIO0_70 */
+ >;
+ bootph-all;
+ };
+
+ main_mmc1_pins_default: main-mmc1-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x023c, PIN_INPUT, 0) /* (H22) MMC1_CMD */
+ J722S_IOPAD(0x0234, PIN_OUTPUT, 0) /* (H24) MMC1_CLK */
+ J722S_IOPAD(0x0230, PIN_INPUT, 0) /* (H23) MMC1_DAT0 */
+ J722S_IOPAD(0x022c, PIN_INPUT_PULLUP, 0) /* (H20) MMC1_DAT1 */
+ J722S_IOPAD(0x0228, PIN_INPUT_PULLUP, 0) /* (J23) MMC1_DAT2 */
+ J722S_IOPAD(0x0224, PIN_INPUT_PULLUP, 0) /* (H25) MMC1_DAT3 */
+ J722S_IOPAD(0x0240, PIN_INPUT, 0) /* (B24) MMC1_SDCD */
+ >;
+ bootph-all;
+ };
+
+ mdio_pins_default: mdio-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x0160, PIN_OUTPUT, 0) /* (AC24) MDIO0_MDC */
+ J722S_IOPAD(0x015c, PIN_INPUT, 0) /* (AD25) MDIO0_MDIO */
+ >;
+ };
+
+ ospi0_pins_default: ospi0-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x0000, PIN_OUTPUT, 0) /* (L24) OSPI0_CLK */
+ J722S_IOPAD(0x002c, PIN_OUTPUT, 0) /* (K26) OSPI0_CSn0 */
+ J722S_IOPAD(0x000c, PIN_INPUT, 0) /* (K27) OSPI0_D0 */
+ J722S_IOPAD(0x0010, PIN_INPUT, 0) /* (L27) OSPI0_D1 */
+ J722S_IOPAD(0x0014, PIN_INPUT, 0) /* (L26) OSPI0_D2 */
+ J722S_IOPAD(0x0018, PIN_INPUT, 0) /* (L25) OSPI0_D3 */
+ J722S_IOPAD(0x001c, PIN_INPUT, 0) /* (L21) OSPI0_D4 */
+ J722S_IOPAD(0x0020, PIN_INPUT, 0) /* (M26) OSPI0_D5 */
+ J722S_IOPAD(0x0024, PIN_INPUT, 0) /* (N27) OSPI0_D6 */
+ J722S_IOPAD(0x0028, PIN_INPUT, 0) /* (M27) OSPI0_D7 */
+ J722S_IOPAD(0x0008, PIN_INPUT, 0) /* (L22) OSPI0_DQS */
+ >;
+ bootph-all;
+ };
+
+ rgmii1_pins_default: rgmii1-default-pins {
+ pinctrl-single,pins = <
+ J722S_IOPAD(0x014c, PIN_INPUT, 0) /* (AC25) RGMII1_RD0 */
+ J722S_IOPAD(0x0150, PIN_INPUT, 0) /* (AD27) RGMII1_RD1 */
+ J722S_IOPAD(0x0154, PIN_INPUT, 0) /* (AE24) RGMII1_RD2 */
+ J722S_IOPAD(0x0158, PIN_INPUT, 0) /* (AE26) RGMII1_RD3 */
+ J722S_IOPAD(0x0148, PIN_INPUT, 0) /* (AE27) RGMII1_RXC */
+ J722S_IOPAD(0x0144, PIN_INPUT, 0) /* (AD23) RGMII1_RX_CTL */
+ J722S_IOPAD(0x0134, PIN_OUTPUT, 0) /* (AF27) RGMII1_TD0 */
+ J722S_IOPAD(0x0138, PIN_OUTPUT, 0) /* (AE23) RGMII1_TD1 */
+ J722S_IOPAD(0x013c, PIN_OUTPUT, 0) /* (AG25) RGMII1_TD2 */
+ J722S_IOPAD(0x0140, PIN_OUTPUT, 0) /* (AF24) RGMII1_TD3 */
+ J722S_IOPAD(0x0130, PIN_OUTPUT, 0) /* (AG26) RGMII1_TXC */
+ J722S_IOPAD(0x012c, PIN_OUTPUT, 0) /* (AF25) RGMII1_TX_CTL */
+ >;
+ };
+};
+
+&cpsw3g {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&rgmii1_pins_default>;
+};
+
+&cpsw3g_mdio {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mdio_pins_default>;
+
+ cpsw3g_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;
+ };
+};
+
+&cpsw_port1 {
+ phy-mode = "rgmii-rxid";
+ phy-handle = <&cpsw3g_phy0>;
+};
+
+&cpsw_port2 {
+ status = "disabled";
+};
+
+&main_gpio1 {
+ status = "okay";
+};
+
+&main_uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_uart0_pins_default>;
+ status = "okay";
+ bootph-all;
+};
+
+&mcu_pmx0 {
+
+ wkup_uart0_pins_default: wkup-uart0-default-pins {
+ pinctrl-single,pins = <
+ J722S_MCU_IOPAD(0x02c, PIN_INPUT, 0) /* (C7) WKUP_UART0_CTSn */
+ J722S_MCU_IOPAD(0x030, PIN_OUTPUT, 0) /* (C6) WKUP_UART0_RTSn */
+ J722S_MCU_IOPAD(0x024, PIN_INPUT, 0) /* (D8) WKUP_UART0_RXD */
+ J722S_MCU_IOPAD(0x028, PIN_OUTPUT, 0) /* (D7) WKUP_UART0_TXD */
+ >;
+ bootph-all;
+ };
+
+ wkup_i2c0_pins_default: wkup-i2c0-default-pins {
+ pinctrl-single,pins = <
+ J722S_MCU_IOPAD(0x04c, PIN_INPUT_PULLUP, 0) /* (C7) WKUP_I2C0_SCL */
+ J722S_MCU_IOPAD(0x050, PIN_INPUT_PULLUP, 0) /* (C6) WKUP_I2C1_SDA */
+ >;
+ bootph-all;
+ };
+};
+
+&wkup_uart0 {
+ /* WKUP UART0 is used by Device Manager firmware */
+ pinctrl-names = "default";
+ pinctrl-0 = <&wkup_uart0_pins_default>;
+ status = "reserved";
+ bootph-all;
+};
+
+&wkup_i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&wkup_i2c0_pins_default>;
+ clock-frequency = <400000>;
+ status = "okay";
+ bootph-all;
+};
+
+&main_i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_i2c0_pins_default>;
+ clock-frequency = <400000>;
+ status = "okay";
+ bootph-all;
+
+ exp1: gpio@23 {
+ compatible = "ti,tca6424";
+ reg = <0x23>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-line-names = "TRC_MUX_SEL", "OSPI/ONAND_MUX_SEL",
+ "MCASP1_FET_SEL", "CTRL_PM_I2C_OE#",
+ "CSI_VIO_SEL", "USB2.0_MUX_SEL",
+ "CSI01_MUX_SEL_2", "CSI23_MUX_SEL_2",
+ "LMK1_OE1", "LMK1_OE0",
+ "LMK2_OE0", "LMK2_OE1",
+ "GPIO_RGMII1_RST#", "GPIO_AUD_RSTn",
+ "GPIO_eMMC_RSTn", "GPIO_uSD_PWR_EN",
+ "USER_LED2", "MCAN0_STB",
+ "PCIe0_1L_RC_RSTz", "PCIe0_1L_PRSNT#",
+ "ENET1_EXP_SPARE2", "ENET1_EXP_PWRDN",
+ "PD_I2ENET1_I2CMUX_SELC_IRQ", "ENET1_EXP_RESETZ";
+ };
+};
+
+&ospi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ospi0_pins_default>;
+ status = "okay";
+
+ 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>;
+ bootph-all;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "ospi.tiboot3";
+ reg = <0x00 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@6c0000 {
+ label = "ospi.env.backup";
+ reg = <0x6c0000 0x40000>;
+ };
+
+ partition@800000 {
+ label = "ospi.rootfs";
+ reg = <0x800000 0x37c0000>;
+ };
+
+ partition@3fc0000 {
+ label = "ospi.phypattern";
+ reg = <0x3fc0000 0x40000>;
+ };
+ };
+ };
+
+};
+
+&sdhci1 {
+ /* SD/MMC */
+ vmmc-supply = <&vdd_mmc1>;
+ vqmmc-supply = <&vdd_sd_dv>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_mmc1_pins_default>;
+ ti,driver-strength-ohm = <50>;
+ disable-wp;
+ no-1-8-v;
+ status = "okay";
+ bootph-all;
+};
diff --git a/arch/arm64/boot/dts/ti/k3-j722s.dtsi b/arch/arm64/boot/dts/ti/k3-j722s.dtsi
new file mode 100644
index 000000000000..c75744edb143
--- /dev/null
+++ b/arch/arm64/boot/dts/ti/k3-j722s.dtsi
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Device Tree Source for J722S SoC Family
+ *
+ * Copyright (C) 2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/soc/ti,sci_pm_domain.h>
+
+#include "k3-am62p5.dtsi"
+
+/ {
+ model = "Texas Instruments K3 J722S SoC";
+ compatible = "ti,j722s";
+
+ cbass_main: bus@f0000 {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ ranges = <0x00 0x000f0000 0x00 0x000f0000 0x00 0x00030000>, /* Main MMRs */
+ <0x00 0x00420000 0x00 0x00420000 0x00 0x00001000>, /* ESM0 */
+ <0x00 0x00600000 0x00 0x00600000 0x00 0x00001100>, /* GPIO */
+ <0x00 0x00703000 0x00 0x00703000 0x00 0x00000200>, /* USB0 debug trace */
+ <0x00 0x0070c000 0x00 0x0070c000 0x00 0x00000200>, /* USB1 debug trace */
+ <0x00 0x00a40000 0x00 0x00a40000 0x00 0x00000800>, /* Timesync router */
+ <0x00 0x01000000 0x00 0x01000000 0x00 0x01b28400>, /* First peripheral window */
+ <0x00 0x08000000 0x00 0x08000000 0x00 0x00200000>, /* Main CPSW */
+ <0x00 0x0d000000 0x00 0x0d000000 0x00 0x00800000>, /* PCIE_0 */
+ <0x00 0x0e000000 0x00 0x0e000000 0x00 0x01d20000>, /* Second peripheral window */
+ <0x00 0x0fd80000 0x00 0x0fd80000 0x00 0x00080000>, /* GPU */
+ <0x00 0x0fd20000 0x00 0x0fd20000 0x00 0x00000100>, /* JPEGENC0_CORE */
+ <0x00 0x0fd20200 0x00 0x0fd20200 0x00 0x00000200>, /* JPEGENC0_CORE_MMU */
+ <0x00 0x20000000 0x00 0x20000000 0x00 0x0a008000>, /* Third peripheral window */
+ <0x00 0x30040000 0x00 0x30040000 0x00 0x00080000>, /* PRUSS-M */
+ <0x00 0x301C0000 0x00 0x301C0000 0x00 0x00001000>, /* DPHY-TX */
+ <0x00 0x30101000 0x00 0x30101000 0x00 0x00080100>, /* CSI window */
+ <0x00 0x30200000 0x00 0x30200000 0x00 0x00010000>, /* DSS */
+ <0x00 0x30210000 0x00 0x30210000 0x00 0x00010000>, /* VPU */
+ <0x00 0x30220000 0x00 0x30220000 0x00 0x00010000>, /* DSS1 */
+ <0x00 0x30270000 0x00 0x30270000 0x00 0x00010000>, /* DSI-base1 */
+ <0x00 0x30500000 0x00 0x30500000 0x00 0x00100000>, /* DSI-base2 */
+ <0x00 0x31000000 0x00 0x31000000 0x00 0x00050000>, /* USB0 DWC3 Core window */
+ <0x00 0x31200000 0x00 0x31200000 0x00 0x00040000>, /* USB1 DWC3 Core window */
+ <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 0x06408000>, /* DMSS */
+ <0x00 0x60000000 0x00 0x60000000 0x00 0x08000000>, /* FSS0 DAT1 */
+ <0x00 0x68000000 0x00 0x68000000 0x00 0x08000000>, /* PCIe0 DAT0 */
+ <0x00 0x70000000 0x00 0x70000000 0x00 0x00040000>, /* OCSRAM */
+ <0x00 0x78400000 0x00 0x78400000 0x00 0x00008000>, /* MAIN R5FSS0 ATCM */
+ <0x00 0x78500000 0x00 0x78500000 0x00 0x00008000>, /* MAIN R5FSS0 BTCM */
+ <0x00 0x7e000000 0x00 0x7e000000 0x00 0x00200000>, /* C7X_0 L2SRAM */
+ <0x00 0x7e200000 0x00 0x7e200000 0x00 0x00200000>, /* C7X_1 L2SRAM */
+ <0x01 0x00000000 0x01 0x00000000 0x00 0x00310000>, /* A53 PERIPHBASE */
+ <0x05 0x00000000 0x05 0x00000000 0x01 0x00000000>, /* FSS0 DAT3 */
+ <0x06 0x00000000 0x06 0x00000000 0x01 0x00000000>, /* PCIe0 DAT1 */
+
+ /* MCU Domain Range */
+ <0x00 0x04000000 0x00 0x04000000 0x00 0x01ff1400>,
+ <0x00 0x79000000 0x00 0x79000000 0x00 0x00008000>,
+ <0x00 0x79020000 0x00 0x79020000 0x00 0x00008000>,
+ <0x00 0x79100000 0x00 0x79100000 0x00 0x00040000>,
+ <0x00 0x79140000 0x00 0x79140000 0x00 0x00040000>,
+
+ /* Wakeup Domain Range */
+ <0x00 0x00b00000 0x00 0x00b00000 0x00 0x00002400>,
+ <0x00 0x2b000000 0x00 0x2b000000 0x00 0x00300400>,
+ <0x00 0x43000000 0x00 0x43000000 0x00 0x00020000>,
+ <0x00 0x78000000 0x00 0x78000000 0x00 0x00008000>,
+ <0x00 0x78100000 0x00 0x78100000 0x00 0x00008000>;
+ };
+};
+
+/* Main domain overrides */
+
+&inta_main_dmss {
+ ti,interrupt-ranges = <7 71 21>;
+};
+
+&oc_sram {
+ reg = <0x00 0x70000000 0x00 0x40000>;
+ ranges = <0x00 0x00 0x70000000 0x40000>;
+};
diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
index f34b92acc56d..81fd7afac8c5 100644
--- a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
@@ -1,6 +1,6 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
- * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
*
* EVM Board Schematics: https://www.ti.com/lit/zip/sprr458
*/
@@ -31,6 +31,7 @@
memory@80000000 {
device_type = "memory";
+ bootph-all;
/* 32G RAM */
reg = <0x00 0x80000000 0x00 0x80000000>,
<0x08 0x80000000 0x07 0x80000000>;
@@ -296,6 +297,13 @@
>;
};
+ main_i2c5_pins_default: main-i2c5-default-pins {
+ pinctrl-single,pins = <
+ J784S4_IOPAD(0x01c, PIN_INPUT, 8) /* (AG34) MCAN15_TX.I2C5_SCL */
+ J784S4_IOPAD(0x018, PIN_INPUT, 8) /* (AK36) MCAN14_RX.I2C5_SDA */
+ >;
+ };
+
main_mmc1_pins_default: main-mmc1-default-pins {
bootph-all;
pinctrl-single,pins = <
@@ -335,8 +343,6 @@
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 */
>;
@@ -760,6 +766,24 @@
};
};
+&main_i2c5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&main_i2c5_pins_default>;
+ clock-frequency = <400000>;
+ status = "okay";
+
+ exp5: gpio@20 {
+ compatible = "ti,tca6408";
+ reg = <0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-line-names = "CSI2_EXP_RSTZ", "CSI2_EXP_A_GPIO0",
+ "CSI2_EXP_A_GPIO1", "CSI2_EXP_A_GPIO3",
+ "CSI2_EXP_B_GPIO1", "CSI2_EXP_B_GPIO2",
+ "CSI2_EXP_B_GPIO3", "CSI2_EXP_B_GPIO4";
+ };
+};
+
&main_sdhci0 {
bootph-all;
/* eMMC */
diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
index f2b720ed1e4f..b67c37460a73 100644
--- a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for J784S4 SoC Family Main Domain peripherals
*
- * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
#include <dt-bindings/mux/mux.h>
@@ -52,12 +52,12 @@
compatible = "reg-mux";
reg = <0x00004080 0x30>;
#mux-control-cells = <1>;
- mux-reg-masks = <0x4080 0x3>, <0x4084 0x3>, /* SERDES0 lane0/1 select */
- <0x4088 0x3>, <0x408c 0x3>, /* SERDES0 lane2/3 select */
- <0x4090 0x3>, <0x4094 0x3>, /* SERDES1 lane0/1 select */
- <0x4098 0x3>, <0x409c 0x3>, /* SERDES1 lane2/3 select */
- <0x40a0 0x3>, <0x40a4 0x3>, /* SERDES2 lane0/1 select */
- <0x40a8 0x3>, <0x40ac 0x3>; /* SERDES2 lane2/3 select */
+ mux-reg-masks = <0x0 0x3>, <0x4 0x3>, /* SERDES0 lane0/1 select */
+ <0x8 0x3>, <0xc 0x3>, /* SERDES0 lane2/3 select */
+ <0x10 0x3>, <0x14 0x3>, /* SERDES1 lane0/1 select */
+ <0x18 0x3>, <0x1c 0x3>, /* SERDES1 lane2/3 select */
+ <0x20 0x3>, <0x24 0x3>, /* SERDES2 lane0/1 select */
+ <0x28 0x3>, <0x2c 0x3>; /* SERDES2 lane2/3 select */
idle-states = <J784S4_SERDES0_LANE0_PCIE1_LANE0>,
<J784S4_SERDES0_LANE1_PCIE1_LANE1>,
<J784S4_SERDES0_LANE2_IP3_UNUSED>,
@@ -662,6 +662,204 @@
status = "disabled";
};
+ ti_csi2rx0: ticsi2rx@4500000 {
+ compatible = "ti,j721e-csi2rx-shim";
+ reg = <0x00 0x04500000 0x00 0x00001000>;
+ ranges;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ dmas = <&main_bcdma_csi 0 0x4940 0>;
+ dma-names = "rx0";
+ power-domains = <&k3_pds 72 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+
+ cdns_csi2rx0: csi-bridge@4504000 {
+ compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+ reg = <0x00 0x04504000 0x00 0x00001000>;
+ clocks = <&k3_clks 72 2>, <&k3_clks 72 0>, <&k3_clks 72 2>,
+ <&k3_clks 72 2>, <&k3_clks 72 3>, <&k3_clks 72 3>;
+ 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";
+ };
+ };
+ };
+ };
+
+ ti_csi2rx1: ticsi2rx@4510000 {
+ compatible = "ti,j721e-csi2rx-shim";
+ reg = <0x00 0x04510000 0x00 0x1000>;
+ ranges;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ dmas = <&main_bcdma_csi 0 0x4960 0>;
+ dma-names = "rx0";
+ power-domains = <&k3_pds 73 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+
+ cdns_csi2rx1: csi-bridge@4514000 {
+ compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+ reg = <0x00 0x04514000 0x00 0x00001000>;
+ clocks = <&k3_clks 73 2>, <&k3_clks 73 0>, <&k3_clks 73 2>,
+ <&k3_clks 73 2>, <&k3_clks 73 3>, <&k3_clks 73 3>;
+ clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+ "pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+ phys = <&dphy1>;
+ phy-names = "dphy";
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csi1_port0: port@0 {
+ reg = <0>;
+ status = "disabled";
+ };
+
+ csi1_port1: port@1 {
+ reg = <1>;
+ status = "disabled";
+ };
+
+ csi1_port2: port@2 {
+ reg = <2>;
+ status = "disabled";
+ };
+
+ csi1_port3: port@3 {
+ reg = <3>;
+ status = "disabled";
+ };
+
+ csi1_port4: port@4 {
+ reg = <4>;
+ status = "disabled";
+ };
+ };
+ };
+ };
+
+ ti_csi2rx2: ticsi2rx@4520000 {
+ compatible = "ti,j721e-csi2rx-shim";
+ reg = <0x00 0x04520000 0x00 0x00001000>;
+ ranges;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ dmas = <&main_bcdma_csi 0 0x4980 0>;
+ dma-names = "rx0";
+ power-domains = <&k3_pds 74 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+
+ cdns_csi2rx2: csi-bridge@4524000 {
+ compatible = "ti,j721e-csi2rx", "cdns,csi2rx";
+ reg = <0x00 0x04524000 0x00 0x00001000>;
+ clocks = <&k3_clks 74 2>, <&k3_clks 74 0>, <&k3_clks 74 2>,
+ <&k3_clks 74 2>, <&k3_clks 74 3>, <&k3_clks 74 3>;
+ clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+ "pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+ phys = <&dphy2>;
+ phy-names = "dphy";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ csi2_port0: port@0 {
+ reg = <0>;
+ status = "disabled";
+ };
+
+ csi2_port1: port@1 {
+ reg = <1>;
+ status = "disabled";
+ };
+
+ csi2_port2: port@2 {
+ reg = <2>;
+ status = "disabled";
+ };
+
+ csi2_port3: port@3 {
+ reg = <3>;
+ status = "disabled";
+ };
+
+ csi2_port4: port@4 {
+ reg = <4>;
+ status = "disabled";
+ };
+ };
+ };
+ };
+
+ dphy0: phy@4580000 {
+ compatible = "cdns,dphy-rx";
+ reg = <0x00 0x04580000 0x00 0x00001100>;
+ #phy-cells = <0>;
+ power-domains = <&k3_pds 212 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+ };
+
+ dphy1: phy@4590000 {
+ compatible = "cdns,dphy-rx";
+ reg = <0x00 0x04590000 0x00 0x00001100>;
+ #phy-cells = <0>;
+ power-domains = <&k3_pds 213 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+ };
+
+ dphy2: phy@45a0000 {
+ compatible = "cdns,dphy-rx";
+ reg = <0x00 0x045a0000 0x00 0x00001100>;
+ #phy-cells = <0>;
+ power-domains = <&k3_pds 214 TI_SCI_PD_EXCLUSIVE>;
+ status = "disabled";
+ };
+
+ vpu0: video-codec@4210000 {
+ compatible = "ti,j721s2-wave521c", "cnm,wave521c";
+ reg = <0x00 0x4210000 0x00 0x10000>;
+ interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&k3_clks 241 2>;
+ power-domains = <&k3_pds 241 TI_SCI_PD_EXCLUSIVE>;
+ };
+
+ vpu1: video-codec@4220000 {
+ compatible = "ti,j721s2-wave521c", "cnm,wave521c";
+ reg = <0x00 0x4220000 0x00 0x10000>;
+ interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&k3_clks 242 2>;
+ power-domains = <&k3_pds 242 TI_SCI_PD_EXCLUSIVE>;
+ };
+
main_sdhci0: mmc@4f80000 {
compatible = "ti,j721e-sdhci-8bit";
reg = <0x00 0x04f80000 0x00 0x1000>,
@@ -1224,7 +1422,6 @@
ti,sci-dev-id = <281>;
ti,sci-rm-range-rchan = <0x21>;
ti,sci-rm-range-tchan = <0x22>;
- status = "disabled";
};
cpts@310d0000 {
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 3902a921d7e5..77a8d99139ec 100644
--- a/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for J784S4 SoC Family MCU/WAKEUP Domain peripherals
*
- * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
&cbass_mcu_wakeup {
@@ -628,7 +628,7 @@
compatible = "ti,j7200-vtm";
reg = <0x00 0x42040000 0x00 0x350>,
<0x00 0x42050000 0x00 0x350>;
- power-domains = <&k3_pds 154 TI_SCI_PD_SHARED>;
+ power-domains = <&k3_pds 243 TI_SCI_PD_SHARED>;
#thermal-sensor-cells = <1>;
};
diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-thermal.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4-thermal.dtsi
index f7b1a15b8fa0..e3ef61c1658f 100644
--- a/arch/arm64/boot/dts/ti/k3-j784s4-thermal.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-thermal.dtsi
@@ -1,4 +1,7 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
+ */
#include <dt-bindings/thermal/thermal.h>
diff --git a/arch/arm64/boot/dts/ti/k3-j784s4.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4.dtsi
index 4398c3a463e1..6e2e92ffe745 100644
--- a/arch/arm64/boot/dts/ti/k3-j784s4.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j784s4.dtsi
@@ -1,10 +1,10 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Device Tree Source for J784S4 SoC Family
*
* TRM (SPRUJ43 JULY 2022): https://www.ti.com/lit/zip/spruj52
*
- * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/
*
*/
@@ -235,6 +235,8 @@
ranges = <0x00 0x00100000 0x00 0x00100000 0x00 0x00020000>, /* ctrl mmr */
<0x00 0x00600000 0x00 0x00600000 0x00 0x00031100>, /* GPIO */
<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 0x10000000 0x00 0x10000000 0x00 0x08000000>, /* PCIe0 DAT0 */
<0x00 0x18000000 0x00 0x18000000 0x00 0x08000000>, /* PCIe1 DAT0 */
diff --git a/arch/arm64/boot/dts/ti/k3-pinctrl.h b/arch/arm64/boot/dts/ti/k3-pinctrl.h
index 2a4e0e084d69..4cd2df467d0b 100644
--- a/arch/arm64/boot/dts/ti/k3-pinctrl.h
+++ b/arch/arm64/boot/dts/ti/k3-pinctrl.h
@@ -1,9 +1,9 @@
-/* SPDX-License-Identifier: GPL-2.0 */
+/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
/*
* This header provides constants for pinctrl bindings for TI's K3 SoC
* family.
*
- * Copyright (C) 2018-2023 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2018-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
#ifndef DTS_ARM64_TI_K3_PINCTRL_H
#define DTS_ARM64_TI_K3_PINCTRL_H
@@ -59,6 +59,9 @@
#define J721S2_IOPAD(pa, val, muxmode) (((pa) & 0x1fff)) ((val) | (muxmode))
#define J721S2_WKUP_IOPAD(pa, val, muxmode) (((pa) & 0x1fff)) ((val) | (muxmode))
+#define J722S_IOPAD(pa, val, muxmode) (((pa) & 0x1fff)) ((val) | (muxmode))
+#define J722S_MCU_IOPAD(pa, val, muxmode) (((pa) & 0x1fff)) ((val) | (muxmode))
+
#define J784S4_IOPAD(pa, val, muxmode) (((pa) & 0x1fff)) ((val) | (muxmode))
#define J784S4_WKUP_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 21b4886c47ba..a011ad893b44 100644
--- a/arch/arm64/boot/dts/ti/k3-serdes.h
+++ b/arch/arm64/boot/dts/ti/k3-serdes.h
@@ -1,8 +1,8 @@
-/* SPDX-License-Identifier: GPL-2.0 */
+/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
/*
* This header provides constants for SERDES MUX for TI SoCs
*
- * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
+ * Copyright (C) 2023-2024 Texas Instruments Incorporated - https://www.ti.com/
*/
#ifndef 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 ccaca29200bb..dd4569e7bd95 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
@@ -230,18 +230,30 @@
&uart0 {
clocks = <&zynqmp_clk UART0_REF>, <&zynqmp_clk LPD_LSBUS>;
+ assigned-clocks = <&zynqmp_clk UART0_REF>;
};
&uart1 {
clocks = <&zynqmp_clk UART1_REF>, <&zynqmp_clk LPD_LSBUS>;
+ assigned-clocks = <&zynqmp_clk UART1_REF>;
};
-&dwc3_0 {
+&usb0 {
clocks = <&zynqmp_clk USB0_BUS_REF>, <&zynqmp_clk USB3_DUAL_REF>;
+ assigned-clocks = <&zynqmp_clk USB0_BUS_REF>, <&zynqmp_clk USB3_DUAL_REF>;
};
-&dwc3_1 {
+&dwc3_0 {
+ clocks = <&zynqmp_clk USB3_DUAL_REF>;
+};
+
+&usb1 {
clocks = <&zynqmp_clk USB1_BUS_REF>, <&zynqmp_clk USB3_DUAL_REF>;
+ assigned-clocks = <&zynqmp_clk USB1_BUS_REF>, <&zynqmp_clk USB3_DUAL_REF>;
+};
+
+&dwc3_1 {
+ clocks = <&zynqmp_clk USB3_DUAL_REF>;
};
&watchdog0 {
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 92f4190d564d..d7535a77b45e 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
@@ -139,7 +139,7 @@
bus-width = <4>;
};
-&gem3 { /* required by spec */
+&gem3 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gem3_default>;
@@ -166,9 +166,28 @@
};
};
-&pinctrl0 { /* required by spec */
+&pinctrl0 {
status = "okay";
+ pinctrl_gpio0_default: gpio0-default {
+ conf {
+ groups = "gpio0_38_grp";
+ bias-pull-up;
+ power-source = <IO_STANDARD_LVCMOS18>;
+ };
+
+ mux {
+ groups = "gpio0_38_grp";
+ function = "gpio0";
+ };
+
+ conf-tx {
+ pins = "MIO38";
+ bias-disable;
+ output-enable;
+ };
+ };
+
pinctrl_uart1_default: uart1-default {
conf {
groups = "uart1_9_grp";
@@ -185,6 +204,7 @@
conf-tx {
pins = "MIO36";
bias-disable;
+ output-enable;
};
mux {
@@ -207,7 +227,7 @@
};
};
- pinctrl_i2c1_gpio: i2c1-gpio {
+ pinctrl_i2c1_gpio: i2c1-gpio-grp {
conf {
groups = "gpio0_24_grp", "gpio0_25_grp";
slew-rate = <SLEW_RATE_SLOW>;
@@ -236,6 +256,7 @@
conf-bootstrap {
pins = "MIO71", "MIO73", "MIO75";
bias-disable;
+ output-enable;
low-power-disable;
};
@@ -243,6 +264,7 @@
pins = "MIO64", "MIO65", "MIO66",
"MIO67", "MIO68", "MIO69";
bias-disable;
+ output-enable;
low-power-enable;
};
@@ -251,6 +273,7 @@
slew-rate = <SLEW_RATE_SLOW>;
power-source = <IO_STANDARD_LVCMOS18>;
bias-disable;
+ output-enable;
};
mux-mdio {
@@ -281,6 +304,7 @@
pins = "MIO54", "MIO56", "MIO57", "MIO58", "MIO59",
"MIO60", "MIO61", "MIO62", "MIO63";
bias-disable;
+ output-enable;
drive-strength = <4>;
slew-rate = <SLEW_RATE_SLOW>;
};
@@ -319,6 +343,12 @@
};
};
+&gpio {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio0_default>;
+};
+
&uart1 {
status = "okay";
pinctrl-names = "default";
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 f88b71f5b07a..a7b8fffad499 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
@@ -94,6 +94,7 @@
pinctrl-0 = <&pinctrl_usb0_default>;
phy-names = "usb3-phy";
phys = <&psgtr 2 PHY_TYPE_USB3 0 1>;
+ assigned-clock-rates = <250000000>, <20000000>;
};
&dwc3_0 {
@@ -122,7 +123,7 @@
bus-width = <4>;
};
-&gem3 { /* required by spec */
+&gem3 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gem3_default>;
@@ -149,9 +150,28 @@
};
};
-&pinctrl0 { /* required by spec */
+&pinctrl0 {
status = "okay";
+ pinctrl_gpio0_default: gpio0-default {
+ conf {
+ groups = "gpio0_38_grp";
+ bias-pull-up;
+ power-source = <IO_STANDARD_LVCMOS18>;
+ };
+
+ mux {
+ groups = "gpio0_38_grp";
+ function = "gpio0";
+ };
+
+ conf-tx {
+ pins = "MIO38";
+ bias-disable;
+ output-enable;
+ };
+ };
+
pinctrl_uart1_default: uart1-default {
conf {
groups = "uart1_9_grp";
@@ -168,6 +188,7 @@
conf-tx {
pins = "MIO36";
bias-disable;
+ output-enable;
};
mux {
@@ -190,7 +211,7 @@
};
};
- pinctrl_i2c1_gpio: i2c1-gpio {
+ pinctrl_i2c1_gpio: i2c1-gpio-grp {
conf {
groups = "gpio0_24_grp", "gpio0_25_grp";
slew-rate = <SLEW_RATE_SLOW>;
@@ -219,6 +240,7 @@
conf-bootstrap {
pins = "MIO71", "MIO73", "MIO75";
bias-disable;
+ output-enable;
low-power-disable;
};
@@ -226,6 +248,7 @@
pins = "MIO64", "MIO65", "MIO66",
"MIO67", "MIO68", "MIO69";
bias-disable;
+ output-enable;
low-power-enable;
};
@@ -234,6 +257,7 @@
slew-rate = <SLEW_RATE_SLOW>;
power-source = <IO_STANDARD_LVCMOS18>;
bias-disable;
+ output-enable;
};
mux-mdio {
@@ -264,6 +288,7 @@
pins = "MIO54", "MIO56", "MIO57", "MIO58", "MIO59",
"MIO60", "MIO61", "MIO62", "MIO63";
bias-disable;
+ output-enable;
drive-strength = <4>;
slew-rate = <SLEW_RATE_SLOW>;
};
@@ -302,6 +327,12 @@
};
};
+&gpio {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio0_default>;
+};
+
&uart1 {
status = "okay";
pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm015-dc1.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm015-dc1.dts
index 73491626e01e..6aff22d43361 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm015-dc1.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm015-dc1.dts
@@ -148,7 +148,7 @@
};
};
- pinctrl_i2c1_gpio: i2c1-gpio {
+ pinctrl_i2c1_gpio: i2c1-gpio-grp {
mux {
groups = "gpio0_36_grp", "gpio0_37_grp";
function = "gpio0";
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts
index f767708fb50d..1850325e1d6c 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts
@@ -219,7 +219,7 @@
};
};
- pinctrl_i2c0_gpio: i2c0-gpio {
+ pinctrl_i2c0_gpio: i2c0-gpio-grp {
mux {
groups = "gpio0_6_grp", "gpio0_7_grp";
function = "gpio0";
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm019-dc5.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm019-dc5.dts
index b1857e17ab7e..53aa3dca1dca 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm019-dc5.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm019-dc5.dts
@@ -125,7 +125,7 @@
};
};
- pinctrl_i2c0_gpio: i2c0-gpio {
+ pinctrl_i2c0_gpio: i2c0-gpio-grp {
mux {
groups = "gpio0_74_grp", "gpio0_75_grp";
function = "gpio0";
@@ -152,7 +152,7 @@
};
};
- pinctrl_i2c1_gpio: i2c1-gpio {
+ pinctrl_i2c1_gpio: i2c1-gpio-grp {
mux {
groups = "gpio0_76_grp", "gpio0_77_grp";
function = "gpio0";
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts
index 52f998c22538..c5945067cd57 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts
@@ -275,7 +275,7 @@
};
};
- pinctrl_i2c1_gpio: i2c1-gpio {
+ pinctrl_i2c1_gpio: i2c1-gpio-grp {
mux {
groups = "gpio0_4_grp", "gpio0_5_grp";
function = "gpio0";
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts
index 84952c14f021..ad8f23a0ec67 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts
@@ -603,7 +603,7 @@
reg = <0x5d>;
temperature-stability = <50>; /* copy from zc702 */
factory-fout = <156250000>;
- clock-frequency = <148500000>;
+ clock-frequency = <156250000>;
clock-output-names = "si570_mgt";
};
};
@@ -689,7 +689,7 @@
};
};
- pinctrl_i2c0_gpio: i2c0-gpio {
+ pinctrl_i2c0_gpio: i2c0-gpio-grp {
mux {
groups = "gpio0_14_grp", "gpio0_15_grp";
function = "gpio0";
@@ -716,7 +716,7 @@
};
};
- pinctrl_i2c1_gpio: i2c1-gpio {
+ pinctrl_i2c1_gpio: i2c1-gpio-grp {
mux {
groups = "gpio0_16_grp", "gpio0_17_grp";
function = "gpio0";
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revA.dts
index 5084ddcee00f..b1eca1bb6a63 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revA.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revA.dts
@@ -272,7 +272,7 @@
};
};
- pinctrl_i2c1_gpio: i2c1-gpio {
+ pinctrl_i2c1_gpio: i2c1-gpio-grp {
mux {
groups = "gpio0_16_grp", "gpio0_17_grp";
function = "gpio0";
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revC.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revC.dts
index b273bd1d920a..ddc74d963a05 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revC.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revC.dts
@@ -284,7 +284,7 @@
};
};
- pinctrl_i2c1_gpio: i2c1-gpio {
+ pinctrl_i2c1_gpio: i2c1-gpio-grp {
mux {
groups = "gpio0_16_grp", "gpio0_17_grp";
function = "gpio0";
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts
index 50c384aa253e..7beedd730f94 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts
@@ -605,7 +605,7 @@
reg = <0x5d>;
temperature-stability = <50>; /* copy from zc702 */
factory-fout = <156250000>;
- clock-frequency = <148500000>;
+ clock-frequency = <156250000>;
clock-output-names = "si570_mgt";
};
};
@@ -700,7 +700,7 @@
};
};
- pinctrl_i2c0_gpio: i2c0-gpio {
+ pinctrl_i2c0_gpio: i2c0-gpio-grp {
mux {
groups = "gpio0_14_grp", "gpio0_15_grp";
function = "gpio0";
@@ -727,7 +727,7 @@
};
};
- pinctrl_i2c1_gpio: i2c1-gpio {
+ pinctrl_i2c1_gpio: i2c1-gpio-grp {
mux {
groups = "gpio0_16_grp", "gpio0_17_grp";
function = "gpio0";
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts
index 617cb0405a7d..b67ff7ecf3c3 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts
@@ -589,7 +589,7 @@
};
};
- pinctrl_i2c0_gpio: i2c0-gpio {
+ pinctrl_i2c0_gpio: i2c0-gpio-grp {
mux {
groups = "gpio0_14_grp", "gpio0_15_grp";
function = "gpio0";
@@ -616,7 +616,7 @@
};
};
- pinctrl_i2c1_gpio: i2c1-gpio {
+ pinctrl_i2c1_gpio: i2c1-gpio-grp {
mux {
groups = "gpio0_16_grp", "gpio0_17_grp";
function = "gpio0";
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zcu1275-revA.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zcu1275-revA.dts
index c406017b0348..a38c2baeba6c 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-zcu1275-revA.dts
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-zcu1275-revA.dts
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * dts file for Xilinx ZynqMP ZC1275
+ * dts file for Xilinx ZynqMP ZCU1275
*
* (C) Copyright 2017 - 2021, Xilinx, Inc.
*
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
index eaba466804bc..25d20d803230 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
+++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
@@ -24,6 +24,13 @@
#address-cells = <2>;
#size-cells = <2>;
+ options {
+ u-boot {
+ compatible = "u-boot,config";
+ bootscr-address = /bits/ 64 <0x20000000>;
+ };
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
@@ -180,13 +187,18 @@
};
firmware {
+ optee: optee {
+ compatible = "linaro,optee-tz";
+ method = "smc";
+ };
+
zynqmp_firmware: zynqmp-firmware {
compatible = "xlnx,zynqmp-firmware";
#power-domain-cells = <1>;
method = "smc";
bootph-all;
- zynqmp_power: zynqmp-power {
+ zynqmp_power: power-management {
bootph-all;
compatible = "xlnx,zynqmp-power";
interrupt-parent = <&gic>;
@@ -281,6 +293,7 @@
interrupt-parent = <&gic>;
tx-fifo-depth = <0x40>;
rx-fifo-depth = <0x40>;
+ resets = <&zynqmp_reset ZYNQMP_RESET_CAN0>;
power-domains = <&zynqmp_firmware PD_CAN_0>;
};
@@ -293,6 +306,7 @@
interrupt-parent = <&gic>;
tx-fifo-depth = <0x40>;
rx-fifo-depth = <0x40>;
+ resets = <&zynqmp_reset ZYNQMP_RESET_CAN1>;
power-domains = <&zynqmp_firmware PD_CAN_1>;
};
@@ -326,7 +340,7 @@
clock-names = "clk_main", "clk_apb";
#dma-cells = <1>;
xlnx,bus-width = <128>;
- iommus = <&smmu 0x14e8>;
+ /* iommus = <&smmu 0x14e8>; */
power-domains = <&zynqmp_firmware PD_GDMA>;
};
@@ -339,7 +353,7 @@
clock-names = "clk_main", "clk_apb";
#dma-cells = <1>;
xlnx,bus-width = <128>;
- iommus = <&smmu 0x14e9>;
+ /* iommus = <&smmu 0x14e9>; */
power-domains = <&zynqmp_firmware PD_GDMA>;
};
@@ -352,7 +366,7 @@
clock-names = "clk_main", "clk_apb";
#dma-cells = <1>;
xlnx,bus-width = <128>;
- iommus = <&smmu 0x14ea>;
+ /* iommus = <&smmu 0x14ea>; */
power-domains = <&zynqmp_firmware PD_GDMA>;
};
@@ -365,7 +379,7 @@
clock-names = "clk_main", "clk_apb";
#dma-cells = <1>;
xlnx,bus-width = <128>;
- iommus = <&smmu 0x14eb>;
+ /* iommus = <&smmu 0x14eb>; */
power-domains = <&zynqmp_firmware PD_GDMA>;
};
@@ -378,7 +392,7 @@
clock-names = "clk_main", "clk_apb";
#dma-cells = <1>;
xlnx,bus-width = <128>;
- iommus = <&smmu 0x14ec>;
+ /* iommus = <&smmu 0x14ec>; */
power-domains = <&zynqmp_firmware PD_GDMA>;
};
@@ -391,7 +405,7 @@
clock-names = "clk_main", "clk_apb";
#dma-cells = <1>;
xlnx,bus-width = <128>;
- iommus = <&smmu 0x14ed>;
+ /* iommus = <&smmu 0x14ed>; */
power-domains = <&zynqmp_firmware PD_GDMA>;
};
@@ -404,7 +418,7 @@
clock-names = "clk_main", "clk_apb";
#dma-cells = <1>;
xlnx,bus-width = <128>;
- iommus = <&smmu 0x14ee>;
+ /* iommus = <&smmu 0x14ee>; */
power-domains = <&zynqmp_firmware PD_GDMA>;
};
@@ -417,7 +431,7 @@
clock-names = "clk_main", "clk_apb";
#dma-cells = <1>;
xlnx,bus-width = <128>;
- iommus = <&smmu 0x14ef>;
+ /* iommus = <&smmu 0x14ef>; */
power-domains = <&zynqmp_firmware PD_GDMA>;
};
@@ -462,7 +476,7 @@
clock-names = "clk_main", "clk_apb";
#dma-cells = <1>;
xlnx,bus-width = <64>;
- iommus = <&smmu 0x868>;
+ /* iommus = <&smmu 0x868>; */
power-domains = <&zynqmp_firmware PD_ADMA>;
};
@@ -475,7 +489,7 @@
clock-names = "clk_main", "clk_apb";
#dma-cells = <1>;
xlnx,bus-width = <64>;
- iommus = <&smmu 0x869>;
+ /* iommus = <&smmu 0x869>; */
power-domains = <&zynqmp_firmware PD_ADMA>;
};
@@ -488,7 +502,7 @@
clock-names = "clk_main", "clk_apb";
#dma-cells = <1>;
xlnx,bus-width = <64>;
- iommus = <&smmu 0x86a>;
+ /* iommus = <&smmu 0x86a>; */
power-domains = <&zynqmp_firmware PD_ADMA>;
};
@@ -501,7 +515,7 @@
clock-names = "clk_main", "clk_apb";
#dma-cells = <1>;
xlnx,bus-width = <64>;
- iommus = <&smmu 0x86b>;
+ /* iommus = <&smmu 0x86b>; */
power-domains = <&zynqmp_firmware PD_ADMA>;
};
@@ -514,7 +528,7 @@
clock-names = "clk_main", "clk_apb";
#dma-cells = <1>;
xlnx,bus-width = <64>;
- iommus = <&smmu 0x86c>;
+ /* iommus = <&smmu 0x86c>; */
power-domains = <&zynqmp_firmware PD_ADMA>;
};
@@ -527,7 +541,7 @@
clock-names = "clk_main", "clk_apb";
#dma-cells = <1>;
xlnx,bus-width = <64>;
- iommus = <&smmu 0x86d>;
+ /* iommus = <&smmu 0x86d>; */
power-domains = <&zynqmp_firmware PD_ADMA>;
};
@@ -540,7 +554,7 @@
clock-names = "clk_main", "clk_apb";
#dma-cells = <1>;
xlnx,bus-width = <64>;
- iommus = <&smmu 0x86e>;
+ /* iommus = <&smmu 0x86e>; */
power-domains = <&zynqmp_firmware PD_ADMA>;
};
@@ -553,7 +567,7 @@
clock-names = "clk_main", "clk_apb";
#dma-cells = <1>;
xlnx,bus-width = <64>;
- iommus = <&smmu 0x86f>;
+ /* iommus = <&smmu 0x86f>; */
power-domains = <&zynqmp_firmware PD_ADMA>;
};
@@ -573,7 +587,7 @@
interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
- iommus = <&smmu 0x872>;
+ /* iommus = <&smmu 0x872>; */
power-domains = <&zynqmp_firmware PD_NAND>;
};
@@ -585,7 +599,7 @@
<GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x0 0xff0b0000 0x0 0x1000>;
clock-names = "pclk", "hclk", "tx_clk", "rx_clk", "tsu_clk";
- iommus = <&smmu 0x874>;
+ /* iommus = <&smmu 0x874>; */
power-domains = <&zynqmp_firmware PD_ETH_0>;
resets = <&zynqmp_reset ZYNQMP_RESET_GEM0>;
reset-names = "gem0_rst";
@@ -599,7 +613,7 @@
<GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x0 0xff0c0000 0x0 0x1000>;
clock-names = "pclk", "hclk", "tx_clk", "rx_clk", "tsu_clk";
- iommus = <&smmu 0x875>;
+ /* iommus = <&smmu 0x875>; */
power-domains = <&zynqmp_firmware PD_ETH_1>;
resets = <&zynqmp_reset ZYNQMP_RESET_GEM1>;
reset-names = "gem1_rst";
@@ -613,7 +627,7 @@
<GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x0 0xff0d0000 0x0 0x1000>;
clock-names = "pclk", "hclk", "tx_clk", "rx_clk", "tsu_clk";
- iommus = <&smmu 0x876>;
+ /* iommus = <&smmu 0x876>; */
power-domains = <&zynqmp_firmware PD_ETH_2>;
resets = <&zynqmp_reset ZYNQMP_RESET_GEM2>;
reset-names = "gem2_rst";
@@ -627,7 +641,7 @@
<GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x0 0xff0e0000 0x0 0x1000>;
clock-names = "pclk", "hclk", "tx_clk", "rx_clk", "tsu_clk";
- iommus = <&smmu 0x877>;
+ /* iommus = <&smmu 0x877>; */
power-domains = <&zynqmp_firmware PD_ETH_3>;
resets = <&zynqmp_reset ZYNQMP_RESET_GEM3>;
reset-names = "gem3_rst";
@@ -689,7 +703,7 @@
msi-parent = <&pcie>;
reg = <0x0 0xfd0e0000 0x0 0x1000>,
<0x0 0xfd480000 0x0 0x1000>,
- <0x80 0x00000000 0x0 0x1000000>;
+ <0x80 0x00000000 0x0 0x10000000>;
reg-names = "breg", "pcireg", "cfg";
ranges = <0x02000000 0x00000000 0xe0000000 0x00000000 0xe0000000 0x00000000 0x10000000>,/* non-prefetchable memory */
<0x43000000 0x00000006 0x00000000 0x00000006 0x00000000 0x00000002 0x00000000>;/* prefetchable memory */
@@ -699,7 +713,7 @@
<0x0 0x0 0x0 0x2 &pcie_intc 0x2>,
<0x0 0x0 0x0 0x3 &pcie_intc 0x3>,
<0x0 0x0 0x0 0x4 &pcie_intc 0x4>;
- iommus = <&smmu 0x4d0>;
+ /* iommus = <&smmu 0x4d0>; */
power-domains = <&zynqmp_firmware PD_PCIE>;
pcie_intc: legacy-interrupt-controller {
interrupt-controller;
@@ -720,7 +734,7 @@
<0x0 0xc0000000 0x0 0x8000000>;
#address-cells = <1>;
#size-cells = <0>;
- iommus = <&smmu 0x873>;
+ /* iommus = <&smmu 0x873>; */
power-domains = <&zynqmp_firmware PD_QSPI>;
};
@@ -752,8 +766,7 @@
interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
power-domains = <&zynqmp_firmware PD_SATA>;
resets = <&zynqmp_reset ZYNQMP_RESET_SATA>;
- iommus = <&smmu 0x4c0>, <&smmu 0x4c1>,
- <&smmu 0x4c2>, <&smmu 0x4c3>;
+ /* iommus = <&smmu 0x4c0>, <&smmu 0x4c1>, <&smmu 0x4c2>, <&smmu 0x4c3>; */
};
sdhci0: mmc@ff160000 {
@@ -764,7 +777,7 @@
interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x0 0xff160000 0x0 0x1000>;
clock-names = "clk_xin", "clk_ahb";
- iommus = <&smmu 0x870>;
+ /* iommus = <&smmu 0x870>; */
#clock-cells = <1>;
clock-output-names = "clk_out_sd0", "clk_in_sd0";
power-domains = <&zynqmp_firmware PD_SD_0>;
@@ -779,7 +792,7 @@
interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x0 0xff170000 0x0 0x1000>;
clock-names = "clk_xin", "clk_ahb";
- iommus = <&smmu 0x871>;
+ /* iommus = <&smmu 0x871>; */
#clock-cells = <1>;
clock-output-names = "clk_out_sd1", "clk_in_sd1";
power-domains = <&zynqmp_firmware PD_SD_1>;
@@ -912,6 +925,7 @@
status = "disabled";
compatible = "xlnx,zynqmp-dwc3";
reg = <0x0 0xff9d0000 0x0 0x100>;
+ clock-names = "bus_clk", "ref_clk";
power-domains = <&zynqmp_firmware PD_USB_0>;
resets = <&zynqmp_reset ZYNQMP_RESET_USB0_CORERESET>,
<&zynqmp_reset ZYNQMP_RESET_USB0_HIBERRESET>,
@@ -922,14 +936,15 @@
dwc3_0: usb@fe200000 {
compatible = "snps,dwc3";
+ status = "disabled";
reg = <0x0 0xfe200000 0x0 0x40000>;
interrupt-parent = <&gic>;
interrupt-names = "host", "peripheral", "otg";
interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
- clock-names = "bus_early", "ref";
- iommus = <&smmu 0x860>;
+ clock-names = "ref";
+ /* iommus = <&smmu 0x860>; */
snps,quirk-frame-length-adjustment = <0x20>;
snps,resume-hs-terminations;
/* dma-coherent; */
@@ -942,6 +957,7 @@
status = "disabled";
compatible = "xlnx,zynqmp-dwc3";
reg = <0x0 0xff9e0000 0x0 0x100>;
+ clock-names = "bus_clk", "ref_clk";
power-domains = <&zynqmp_firmware PD_USB_1>;
resets = <&zynqmp_reset ZYNQMP_RESET_USB1_CORERESET>,
<&zynqmp_reset ZYNQMP_RESET_USB1_HIBERRESET>,
@@ -951,14 +967,15 @@
dwc3_1: usb@fe300000 {
compatible = "snps,dwc3";
+ status = "disabled";
reg = <0x0 0xfe300000 0x0 0x40000>;
interrupt-parent = <&gic>;
interrupt-names = "host", "peripheral", "otg";
interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
- clock-names = "bus_early", "ref";
- iommus = <&smmu 0x861>;
+ clock-names = "ref";
+ /* iommus = <&smmu 0x861>; */
snps,quirk-frame-length-adjustment = <0x20>;
snps,resume-hs-terminations;
/* dma-coherent; */
@@ -1018,6 +1035,7 @@
interrupt-parent = <&gic>;
clock-names = "axi_clk";
power-domains = <&zynqmp_firmware PD_DP>;
+ /* iommus = <&smmu 0xce4>; */
#dma-cells = <1>;
};
@@ -1032,6 +1050,7 @@
reg-names = "dp", "blend", "av_buf", "aud";
interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
interrupt-parent = <&gic>;
+ /* iommus = <&smmu 0xce3>; */
clock-names = "dp_apb_clk", "dp_aud_clk",
"dp_vtc_pixel_clk_in";
power-domains = <&zynqmp_firmware PD_DP>;
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index e6cf3e5d63c3..2c30d617e180 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -76,7 +76,6 @@ CONFIG_ARCH_VEXPRESS=y
CONFIG_ARCH_VISCONTI=y
CONFIG_ARCH_XGENE=y
CONFIG_ARCH_ZYNQMP=y
-CONFIG_ARM64_VA_BITS_48=y
CONFIG_SCHED_MC=y
CONFIG_SCHED_SMT=y
CONFIG_NUMA=y
@@ -251,6 +250,9 @@ CONFIG_RASPBERRYPI_FIRMWARE=y
CONFIG_INTEL_STRATIX10_SERVICE=y
CONFIG_INTEL_STRATIX10_RSU=m
CONFIG_MTK_ADSP_IPC=m
+CONFIG_GOOGLE_FIRMWARE=y
+CONFIG_GOOGLE_CBMEM=m
+CONFIG_GOOGLE_COREBOOT_TABLE=m
CONFIG_EFI_CAPSULE_LOADER=y
CONFIG_IMX_SCU=y
CONFIG_QCOM_QSEECOM=y
@@ -432,6 +434,7 @@ CONFIG_MOUSE_ELAN_I2C=m
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_ATMEL_MXT=m
CONFIG_TOUCHSCREEN_GOODIX=m
+CONFIG_TOUCHSCREEN_GOODIX_BERLIN_SPI=m
CONFIG_TOUCHSCREEN_ELAN=m
CONFIG_TOUCHSCREEN_EDT_FT5X06=m
CONFIG_INPUT_MISC=y
@@ -620,6 +623,7 @@ CONFIG_PINCTRL_SM8350_LPASS_LPI=m
CONFIG_PINCTRL_SM8450_LPASS_LPI=m
CONFIG_PINCTRL_SC8280XP_LPASS_LPI=m
CONFIG_PINCTRL_SM8550_LPASS_LPI=m
+CONFIG_PINCTRL_SM8650_LPASS_LPI=m
CONFIG_GPIO_ALTERA=m
CONFIG_GPIO_DAVINCI=y
CONFIG_GPIO_DWAPB=y
@@ -632,6 +636,7 @@ CONFIG_GPIO_SYSCON=y
CONFIG_GPIO_UNIPHIER=y
CONFIG_GPIO_VISCONTI=y
CONFIG_GPIO_WCD934X=m
+CONFIG_GPIO_VF610=y
CONFIG_GPIO_XGENE=y
CONFIG_GPIO_XGENE_SB=y
CONFIG_GPIO_MAX732X=y
@@ -752,6 +757,7 @@ CONFIG_REGULATOR_HI6421V530=y
CONFIG_REGULATOR_HI655X=y
CONFIG_REGULATOR_MAX77620=y
CONFIG_REGULATOR_MAX8973=y
+CONFIG_REGULATOR_MAX20411=m
CONFIG_REGULATOR_MP8859=y
CONFIG_REGULATOR_MT6315=m
CONFIG_REGULATOR_MT6357=y
@@ -792,13 +798,16 @@ CONFIG_USB_VIDEO_CLASS=m
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_SDR_PLATFORM_DRIVERS=y
CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_VIDEO_AMPHION_VPU=m
CONFIG_VIDEO_CADENCE_CSI2RX=m
CONFIG_VIDEO_MEDIATEK_JPEG=m
CONFIG_VIDEO_MEDIATEK_VCODEC=m
+CONFIG_VIDEO_WAVE_VPU=m
CONFIG_VIDEO_IMX7_CSI=m
CONFIG_VIDEO_IMX_MIPI_CSIS=m
CONFIG_VIDEO_IMX8_ISI=m
CONFIG_VIDEO_IMX8_ISI_M2M=y
+CONFIG_VIDEO_IMX8_JPEG=m
CONFIG_VIDEO_QCOM_CAMSS=m
CONFIG_VIDEO_QCOM_VENUS=m
CONFIG_VIDEO_RCAR_ISP=m
@@ -861,6 +870,7 @@ CONFIG_DRM_PANEL_RAYDIUM_RM67191=m
CONFIG_DRM_PANEL_SITRONIX_ST7703=m
CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m
CONFIG_DRM_PANEL_VISIONOX_VTDR6130=m
+CONFIG_DRM_FSL_LDB=m
CONFIG_DRM_LONTIUM_LT8912B=m
CONFIG_DRM_LONTIUM_LT9611=m
CONFIG_DRM_LONTIUM_LT9611UXC=m
@@ -992,6 +1002,8 @@ CONFIG_SND_SOC_TLV320AIC32X4_I2C=m
CONFIG_SND_SOC_TLV320AIC3X_I2C=m
CONFIG_SND_SOC_WCD9335=m
CONFIG_SND_SOC_WCD934X=m
+CONFIG_SND_SOC_WCD939X=m
+CONFIG_SND_SOC_WCD939X_SDW=m
CONFIG_SND_SOC_WM8524=m
CONFIG_SND_SOC_WM8904=m
CONFIG_SND_SOC_WM8960=m
@@ -1032,6 +1044,7 @@ CONFIG_USB_CDNS_SUPPORT=m
CONFIG_USB_CDNS3=m
CONFIG_USB_CDNS3_GADGET=y
CONFIG_USB_CDNS3_HOST=y
+CONFIG_USB_CDNS3_IMX=m
CONFIG_USB_MTU3=y
CONFIG_USB_MUSB_HDRC=y
CONFIG_USB_MUSB_SUNXI=y
@@ -1049,6 +1062,7 @@ CONFIG_USB_QCOM_EUD=m
CONFIG_USB_HSIC_USB3503=y
CONFIG_USB_ONBOARD_HUB=m
CONFIG_NOP_USB_XCEIV=y
+CONFIG_USB_MXS_PHY=m
CONFIG_USB_GADGET=y
CONFIG_USB_RENESAS_USBHS_UDC=m
CONFIG_USB_RZV2M_USB3DRD=y
@@ -1079,6 +1093,7 @@ CONFIG_TYPEC_HD3SS3220=m
CONFIG_TYPEC_MUX_FSA4480=m
CONFIG_TYPEC_MUX_GPIO_SBU=m
CONFIG_TYPEC_MUX_NB7VPQ904M=m
+CONFIG_TYPEC_MUX_WCD939X_USBSS=m
CONFIG_TYPEC_DP_ALTMODE=m
CONFIG_MMC=y
CONFIG_MMC_BLOCK_MINORS=32
@@ -1242,7 +1257,11 @@ CONFIG_COMMON_CLK_MT8192_SCP_ADSP=y
CONFIG_COMMON_CLK_MT8192_VDECSYS=y
CONFIG_COMMON_CLK_MT8192_VENCSYS=y
CONFIG_COMMON_CLK_QCOM=y
+CONFIG_CLK_X1E80100_CAMCC=m
+CONFIG_CLK_X1E80100_DISPCC=m
CONFIG_CLK_X1E80100_GCC=y
+CONFIG_CLK_X1E80100_GPUCC=m
+CONFIG_CLK_X1E80100_TCSRCC=y
CONFIG_QCOM_A53PLL=y
CONFIG_QCOM_CLK_APCS_MSM8916=y
CONFIG_QCOM_CLK_APCC_MSM8996=y
@@ -1265,6 +1284,7 @@ CONFIG_MSM_MMCC_8998=m
CONFIG_QCM_GCC_2290=y
CONFIG_QCM_DISPCC_2290=m
CONFIG_QCS_GCC_404=y
+CONFIG_QDU_GCC_1000=y
CONFIG_SC_CAMCC_8280XP=m
CONFIG_SC_DISPCC_8280XP=m
CONFIG_SA_GCC_8775P=y
@@ -1366,6 +1386,7 @@ CONFIG_QCOM_STATS=m
CONFIG_QCOM_WCNSS_CTRL=m
CONFIG_QCOM_APR=m
CONFIG_QCOM_ICC_BWMON=m
+CONFIG_QCOM_PBS=m
CONFIG_ARCH_R8A77995=y
CONFIG_ARCH_R8A77990=y
CONFIG_ARCH_R8A77951=y
@@ -1377,6 +1398,7 @@ CONFIG_ARCH_R8A77980=y
CONFIG_ARCH_R8A77970=y
CONFIG_ARCH_R8A779A0=y
CONFIG_ARCH_R8A779G0=y
+CONFIG_ARCH_R8A779H0=y
CONFIG_ARCH_R8A774C0=y
CONFIG_ARCH_R8A774E1=y
CONFIG_ARCH_R8A774A1=y
@@ -1410,6 +1432,7 @@ CONFIG_EXTCON_USBC_CROS_EC=y
CONFIG_RENESAS_RPCIF=m
CONFIG_IIO=y
CONFIG_EXYNOS_ADC=y
+CONFIG_IMX8QXP_ADC=m
CONFIG_IMX93_ADC=m
CONFIG_MAX9611=m
CONFIG_MEDIATEK_MT6577_AUXADC=m
@@ -1461,6 +1484,7 @@ CONFIG_PHY_SUN4I_USB=y
CONFIG_PHY_CADENCE_TORRENT=m
CONFIG_PHY_CADENCE_DPHY_RX=m
CONFIG_PHY_CADENCE_SIERRA=m
+CONFIG_PHY_CADENCE_SALVO=m
CONFIG_PHY_MIXEL_MIPI_DPHY=m
CONFIG_PHY_FSL_IMX8M_PCIE=y
CONFIG_PHY_HI6220_USB=y
@@ -1490,6 +1514,7 @@ CONFIG_PHY_ROCKCHIP_INNO_USB2=y
CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY=m
CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY=m
CONFIG_PHY_ROCKCHIP_PCIE=m
+CONFIG_PHY_ROCKCHIP_SAMSUNG_HDPTX=m
CONFIG_PHY_ROCKCHIP_SNPS_PCIE3=y
CONFIG_PHY_ROCKCHIP_TYPEC=y
CONFIG_PHY_SAMSUNG_UFS=y
@@ -1550,8 +1575,9 @@ CONFIG_INTERCONNECT_QCOM=y
CONFIG_INTERCONNECT_QCOM_MSM8916=m
CONFIG_INTERCONNECT_QCOM_MSM8996=m
CONFIG_INTERCONNECT_QCOM_OSM_L3=m
-CONFIG_INTERCONNECT_QCOM_QCM2290=m
+CONFIG_INTERCONNECT_QCOM_QCM2290=y
CONFIG_INTERCONNECT_QCOM_QCS404=m
+CONFIG_INTERCONNECT_QCOM_QDU1000=y
CONFIG_INTERCONNECT_QCOM_SA8775P=y
CONFIG_INTERCONNECT_QCOM_SC7180=y
CONFIG_INTERCONNECT_QCOM_SC7280=y
@@ -1560,7 +1586,7 @@ CONFIG_INTERCONNECT_QCOM_SC8280XP=y
CONFIG_INTERCONNECT_QCOM_SDM845=y
CONFIG_INTERCONNECT_QCOM_SDX75=y
CONFIG_INTERCONNECT_QCOM_SM8150=m
-CONFIG_INTERCONNECT_QCOM_SM8250=m
+CONFIG_INTERCONNECT_QCOM_SM8250=y
CONFIG_INTERCONNECT_QCOM_SM8350=m
CONFIG_INTERCONNECT_QCOM_SM8450=y
CONFIG_INTERCONNECT_QCOM_SM8550=y
@@ -1571,8 +1597,7 @@ CONFIG_RZ_MTU3_CNT=m
CONFIG_HTE=y
CONFIG_HTE_TEGRA194=y
CONFIG_HTE_TEGRA194_TEST=m
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_BTRFS_FS=m
CONFIG_BTRFS_FS_POSIX_ACL=y
@@ -1590,6 +1615,7 @@ CONFIG_CONFIGFS_FS=y
CONFIG_EFIVAR_FS=y
CONFIG_UBIFS_FS=m
CONFIG_SQUASHFS=y
+CONFIG_PSTORE_RAM=m
CONFIG_NFS_FS=y
CONFIG_NFS_V4=y
CONFIG_NFS_V4_1=y
diff --git a/arch/arm64/configs/virt.config b/arch/arm64/configs/virt.config
index c47c36f8f67b..2d1d2ce7ae2a 100644
--- a/arch/arm64/configs/virt.config
+++ b/arch/arm64/configs/virt.config
@@ -14,6 +14,7 @@
# CONFIG_ARCH_BERLIN is not set
# CONFIG_ARCH_BRCMSTB is not set
# CONFIG_ARCH_EXYNOS is not set
+# CONFIG_ARCH_SPARX5 is not set
# CONFIG_ARCH_K3 is not set
# CONFIG_ARCH_LAYERSCAPE is not set
# CONFIG_ARCH_LG1K is not set
@@ -23,14 +24,17 @@
# CONFIG_ARCH_MESON is not set
# CONFIG_ARCH_MVEBU is not set
# CONFIG_ARCH_NXP is not set
+# CONFIG_ARCH_MA35 is not set
# CONFIG_ARCH_MXC is not set
# CONFIG_ARCH_NPCM is not set
# CONFIG_ARCH_QCOM is not set
+# CONFIG_ARCH_REALTEK is not set
# CONFIG_ARCH_RENESAS is not set
# CONFIG_ARCH_ROCKCHIP is not set
# CONFIG_ARCH_S32 is not set
# CONFIG_ARCH_SEATTLE is not set
# CONFIG_ARCH_INTEL_SOCFPGA is not set
+# CONFIG_ARCH_STM32 is not set
# CONFIG_ARCH_SYNQUACER is not set
# CONFIG_ARCH_TEGRA is not set
# CONFIG_ARCH_TESLA_FSD is not set
diff --git a/arch/arm64/crypto/Kconfig b/arch/arm64/crypto/Kconfig
index eb7b423ba463..e7d9bd8e4709 100644
--- a/arch/arm64/crypto/Kconfig
+++ b/arch/arm64/crypto/Kconfig
@@ -268,6 +268,7 @@ config CRYPTO_AES_ARM64_CE_CCM
depends on ARM64 && KERNEL_MODE_NEON
select CRYPTO_ALGAPI
select CRYPTO_AES_ARM64_CE
+ select CRYPTO_AES_ARM64_CE_BLK
select CRYPTO_AEAD
select CRYPTO_LIB_AES
help
diff --git a/arch/arm64/crypto/aes-ce-ccm-core.S b/arch/arm64/crypto/aes-ce-ccm-core.S
index b03f7f71f893..f2624238fd95 100644
--- a/arch/arm64/crypto/aes-ce-ccm-core.S
+++ b/arch/arm64/crypto/aes-ce-ccm-core.S
@@ -1,8 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * aesce-ccm-core.S - AES-CCM transform for ARMv8 with Crypto Extensions
+ * aes-ce-ccm-core.S - AES-CCM transform for ARMv8 with Crypto Extensions
*
- * Copyright (C) 2013 - 2017 Linaro Ltd <ard.biesheuvel@linaro.org>
+ * Copyright (C) 2013 - 2017 Linaro Ltd.
+ * Copyright (C) 2024 Google LLC
+ *
+ * Author: Ard Biesheuvel <ardb@kernel.org>
*/
#include <linux/linkage.h>
@@ -11,211 +14,129 @@
.text
.arch armv8-a+crypto
- /*
- * u32 ce_aes_ccm_auth_data(u8 mac[], u8 const in[], u32 abytes,
- * u32 macp, u8 const rk[], u32 rounds);
- */
-SYM_FUNC_START(ce_aes_ccm_auth_data)
- ld1 {v0.16b}, [x0] /* load mac */
- cbz w3, 1f
- sub w3, w3, #16
- eor v1.16b, v1.16b, v1.16b
-0: ldrb w7, [x1], #1 /* get 1 byte of input */
- subs w2, w2, #1
- add w3, w3, #1
- ins v1.b[0], w7
- ext v1.16b, v1.16b, v1.16b, #1 /* rotate in the input bytes */
- beq 8f /* out of input? */
- cbnz w3, 0b
- eor v0.16b, v0.16b, v1.16b
-1: ld1 {v3.4s}, [x4] /* load first round key */
- prfm pldl1strm, [x1]
- cmp w5, #12 /* which key size? */
- add x6, x4, #16
- sub w7, w5, #2 /* modified # of rounds */
- bmi 2f
- bne 5f
- mov v5.16b, v3.16b
- b 4f
-2: mov v4.16b, v3.16b
- ld1 {v5.4s}, [x6], #16 /* load 2nd round key */
-3: aese v0.16b, v4.16b
- aesmc v0.16b, v0.16b
-4: ld1 {v3.4s}, [x6], #16 /* load next round key */
- aese v0.16b, v5.16b
- aesmc v0.16b, v0.16b
-5: ld1 {v4.4s}, [x6], #16 /* load next round key */
- subs w7, w7, #3
- aese v0.16b, v3.16b
- aesmc v0.16b, v0.16b
- ld1 {v5.4s}, [x6], #16 /* load next round key */
- bpl 3b
- aese v0.16b, v4.16b
- subs w2, w2, #16 /* last data? */
- eor v0.16b, v0.16b, v5.16b /* final round */
- bmi 6f
- ld1 {v1.16b}, [x1], #16 /* load next input block */
- eor v0.16b, v0.16b, v1.16b /* xor with mac */
- bne 1b
-6: st1 {v0.16b}, [x0] /* store mac */
- beq 10f
- adds w2, w2, #16
- beq 10f
- mov w3, w2
-7: ldrb w7, [x1], #1
- umov w6, v0.b[0]
- eor w6, w6, w7
- strb w6, [x0], #1
- subs w2, w2, #1
- beq 10f
- ext v0.16b, v0.16b, v0.16b, #1 /* rotate out the mac bytes */
- b 7b
-8: cbz w3, 91f
- mov w7, w3
- add w3, w3, #16
-9: ext v1.16b, v1.16b, v1.16b, #1
- adds w7, w7, #1
- bne 9b
-91: eor v0.16b, v0.16b, v1.16b
- st1 {v0.16b}, [x0]
-10: mov w0, w3
- ret
-SYM_FUNC_END(ce_aes_ccm_auth_data)
+ .macro load_round_keys, rk, nr, tmp
+ sub w\tmp, \nr, #10
+ add \tmp, \rk, w\tmp, sxtw #4
+ ld1 {v10.4s-v13.4s}, [\rk]
+ ld1 {v14.4s-v17.4s}, [\tmp], #64
+ ld1 {v18.4s-v21.4s}, [\tmp], #64
+ ld1 {v3.4s-v5.4s}, [\tmp]
+ .endm
- /*
- * void ce_aes_ccm_final(u8 mac[], u8 const ctr[], u8 const rk[],
- * u32 rounds);
- */
-SYM_FUNC_START(ce_aes_ccm_final)
- ld1 {v3.4s}, [x2], #16 /* load first round key */
- ld1 {v0.16b}, [x0] /* load mac */
- cmp w3, #12 /* which key size? */
- sub w3, w3, #2 /* modified # of rounds */
- ld1 {v1.16b}, [x1] /* load 1st ctriv */
- bmi 0f
- bne 3f
- mov v5.16b, v3.16b
- b 2f
-0: mov v4.16b, v3.16b
-1: ld1 {v5.4s}, [x2], #16 /* load next round key */
- aese v0.16b, v4.16b
- aesmc v0.16b, v0.16b
- aese v1.16b, v4.16b
- aesmc v1.16b, v1.16b
-2: ld1 {v3.4s}, [x2], #16 /* load next round key */
- aese v0.16b, v5.16b
- aesmc v0.16b, v0.16b
- aese v1.16b, v5.16b
- aesmc v1.16b, v1.16b
-3: ld1 {v4.4s}, [x2], #16 /* load next round key */
- subs w3, w3, #3
- aese v0.16b, v3.16b
- aesmc v0.16b, v0.16b
- aese v1.16b, v3.16b
- aesmc v1.16b, v1.16b
- bpl 1b
- aese v0.16b, v4.16b
- aese v1.16b, v4.16b
- /* final round key cancels out */
- eor v0.16b, v0.16b, v1.16b /* en-/decrypt the mac */
- st1 {v0.16b}, [x0] /* store result */
- ret
-SYM_FUNC_END(ce_aes_ccm_final)
+ .macro dround, va, vb, vk
+ aese \va\().16b, \vk\().16b
+ aesmc \va\().16b, \va\().16b
+ aese \vb\().16b, \vk\().16b
+ aesmc \vb\().16b, \vb\().16b
+ .endm
+
+ .macro aes_encrypt, va, vb, nr
+ tbz \nr, #2, .L\@
+ dround \va, \vb, v10
+ dround \va, \vb, v11
+ tbz \nr, #1, .L\@
+ dround \va, \vb, v12
+ dround \va, \vb, v13
+.L\@: .irp v, v14, v15, v16, v17, v18, v19, v20, v21, v3
+ dround \va, \vb, \v
+ .endr
+ aese \va\().16b, v4.16b
+ aese \vb\().16b, v4.16b
+ .endm
.macro aes_ccm_do_crypt,enc
- cbz x2, 5f
- ldr x8, [x6, #8] /* load lower ctr */
+ load_round_keys x3, w4, x10
+
ld1 {v0.16b}, [x5] /* load mac */
+ cbz x2, ce_aes_ccm_final
+ ldr x8, [x6, #8] /* load lower ctr */
CPU_LE( rev x8, x8 ) /* keep swabbed ctr in reg */
0: /* outer loop */
ld1 {v1.8b}, [x6] /* load upper ctr */
prfm pldl1strm, [x1]
add x8, x8, #1
rev x9, x8
- cmp w4, #12 /* which key size? */
- sub w7, w4, #2 /* get modified # of rounds */
ins v1.d[1], x9 /* no carry in lower ctr */
- ld1 {v3.4s}, [x3] /* load first round key */
- add x10, x3, #16
- bmi 1f
- bne 4f
- mov v5.16b, v3.16b
- b 3f
-1: mov v4.16b, v3.16b
- ld1 {v5.4s}, [x10], #16 /* load 2nd round key */
-2: /* inner loop: 3 rounds, 2x interleaved */
- aese v0.16b, v4.16b
- aesmc v0.16b, v0.16b
- aese v1.16b, v4.16b
- aesmc v1.16b, v1.16b
-3: ld1 {v3.4s}, [x10], #16 /* load next round key */
- aese v0.16b, v5.16b
- aesmc v0.16b, v0.16b
- aese v1.16b, v5.16b
- aesmc v1.16b, v1.16b
-4: ld1 {v4.4s}, [x10], #16 /* load next round key */
- subs w7, w7, #3
- aese v0.16b, v3.16b
- aesmc v0.16b, v0.16b
- aese v1.16b, v3.16b
- aesmc v1.16b, v1.16b
- ld1 {v5.4s}, [x10], #16 /* load next round key */
- bpl 2b
- aese v0.16b, v4.16b
- aese v1.16b, v4.16b
+
+ aes_encrypt v0, v1, w4
+
subs w2, w2, #16
- bmi 6f /* partial block? */
+ bmi ce_aes_ccm_crypt_tail
ld1 {v2.16b}, [x1], #16 /* load next input block */
.if \enc == 1
eor v2.16b, v2.16b, v5.16b /* final round enc+mac */
- eor v1.16b, v1.16b, v2.16b /* xor with crypted ctr */
+ eor v6.16b, v1.16b, v2.16b /* xor with crypted ctr */
.else
eor v2.16b, v2.16b, v1.16b /* xor with crypted ctr */
- eor v1.16b, v2.16b, v5.16b /* final round enc */
+ eor v6.16b, v2.16b, v5.16b /* final round enc */
.endif
eor v0.16b, v0.16b, v2.16b /* xor mac with pt ^ rk[last] */
- st1 {v1.16b}, [x0], #16 /* write output block */
+ st1 {v6.16b}, [x0], #16 /* write output block */
bne 0b
CPU_LE( rev x8, x8 )
- st1 {v0.16b}, [x5] /* store mac */
str x8, [x6, #8] /* store lsb end of ctr (BE) */
-5: ret
-
-6: eor v0.16b, v0.16b, v5.16b /* final round mac */
- eor v1.16b, v1.16b, v5.16b /* final round enc */
+ cbnz x7, ce_aes_ccm_final
st1 {v0.16b}, [x5] /* store mac */
- add w2, w2, #16 /* process partial tail block */
-7: ldrb w9, [x1], #1 /* get 1 byte of input */
- umov w6, v1.b[0] /* get top crypted ctr byte */
- umov w7, v0.b[0] /* get top mac byte */
- .if \enc == 1
- eor w7, w7, w9
- eor w9, w9, w6
- .else
- eor w9, w9, w6
- eor w7, w7, w9
- .endif
- strb w9, [x0], #1 /* store out byte */
- strb w7, [x5], #1 /* store mac byte */
- subs w2, w2, #1
- beq 5b
- ext v0.16b, v0.16b, v0.16b, #1 /* shift out mac byte */
- ext v1.16b, v1.16b, v1.16b, #1 /* shift out ctr byte */
- b 7b
+ ret
.endm
+SYM_FUNC_START_LOCAL(ce_aes_ccm_crypt_tail)
+ eor v0.16b, v0.16b, v5.16b /* final round mac */
+ eor v1.16b, v1.16b, v5.16b /* final round enc */
+
+ add x1, x1, w2, sxtw /* rewind the input pointer (w2 < 0) */
+ add x0, x0, w2, sxtw /* rewind the output pointer */
+
+ adr_l x8, .Lpermute /* load permute vectors */
+ add x9, x8, w2, sxtw
+ sub x8, x8, w2, sxtw
+ ld1 {v7.16b-v8.16b}, [x9]
+ ld1 {v9.16b}, [x8]
+
+ ld1 {v2.16b}, [x1] /* load a full block of input */
+ tbl v1.16b, {v1.16b}, v7.16b /* move keystream to end of register */
+ eor v7.16b, v2.16b, v1.16b /* encrypt partial input block */
+ bif v2.16b, v7.16b, v22.16b /* select plaintext */
+ tbx v7.16b, {v6.16b}, v8.16b /* insert output from previous iteration */
+ tbl v2.16b, {v2.16b}, v9.16b /* copy plaintext to start of v2 */
+ eor v0.16b, v0.16b, v2.16b /* fold plaintext into mac */
+
+ st1 {v7.16b}, [x0] /* store output block */
+ cbz x7, 0f
+
+SYM_INNER_LABEL(ce_aes_ccm_final, SYM_L_LOCAL)
+ ld1 {v1.16b}, [x7] /* load 1st ctriv */
+
+ aes_encrypt v0, v1, w4
+
+ /* final round key cancels out */
+ eor v0.16b, v0.16b, v1.16b /* en-/decrypt the mac */
+0: st1 {v0.16b}, [x5] /* store result */
+ ret
+SYM_FUNC_END(ce_aes_ccm_crypt_tail)
+
/*
* void ce_aes_ccm_encrypt(u8 out[], u8 const in[], u32 cbytes,
* u8 const rk[], u32 rounds, u8 mac[],
- * u8 ctr[]);
+ * u8 ctr[], u8 const final_iv[]);
* void ce_aes_ccm_decrypt(u8 out[], u8 const in[], u32 cbytes,
* u8 const rk[], u32 rounds, u8 mac[],
- * u8 ctr[]);
+ * u8 ctr[], u8 const final_iv[]);
*/
SYM_FUNC_START(ce_aes_ccm_encrypt)
+ movi v22.16b, #255
aes_ccm_do_crypt 1
SYM_FUNC_END(ce_aes_ccm_encrypt)
SYM_FUNC_START(ce_aes_ccm_decrypt)
+ movi v22.16b, #0
aes_ccm_do_crypt 0
SYM_FUNC_END(ce_aes_ccm_decrypt)
+
+ .section ".rodata", "a"
+ .align 6
+ .fill 15, 1, 0xff
+.Lpermute:
+ .byte 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7
+ .byte 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf
+ .fill 15, 1, 0xff
diff --git a/arch/arm64/crypto/aes-ce-ccm-glue.c b/arch/arm64/crypto/aes-ce-ccm-glue.c
index 25cd3808ecbe..ce9b28e3c7d6 100644
--- a/arch/arm64/crypto/aes-ce-ccm-glue.c
+++ b/arch/arm64/crypto/aes-ce-ccm-glue.c
@@ -1,8 +1,11 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * aes-ccm-glue.c - AES-CCM transform for ARMv8 with Crypto Extensions
+ * aes-ce-ccm-glue.c - AES-CCM transform for ARMv8 with Crypto Extensions
*
- * Copyright (C) 2013 - 2017 Linaro Ltd <ard.biesheuvel@linaro.org>
+ * Copyright (C) 2013 - 2017 Linaro Ltd.
+ * Copyright (C) 2024 Google LLC
+ *
+ * Author: Ard Biesheuvel <ardb@kernel.org>
*/
#include <asm/neon.h>
@@ -15,6 +18,8 @@
#include "aes-ce-setkey.h"
+MODULE_IMPORT_NS(CRYPTO_INTERNAL);
+
static int num_rounds(struct crypto_aes_ctx *ctx)
{
/*
@@ -27,19 +32,17 @@ static int num_rounds(struct crypto_aes_ctx *ctx)
return 6 + ctx->key_length / 4;
}
-asmlinkage u32 ce_aes_ccm_auth_data(u8 mac[], u8 const in[], u32 abytes,
- u32 macp, u32 const rk[], u32 rounds);
+asmlinkage u32 ce_aes_mac_update(u8 const in[], u32 const rk[], int rounds,
+ int blocks, u8 dg[], int enc_before,
+ int enc_after);
asmlinkage void ce_aes_ccm_encrypt(u8 out[], u8 const in[], u32 cbytes,
u32 const rk[], u32 rounds, u8 mac[],
- u8 ctr[]);
+ u8 ctr[], u8 const final_iv[]);
asmlinkage void ce_aes_ccm_decrypt(u8 out[], u8 const in[], u32 cbytes,
u32 const rk[], u32 rounds, u8 mac[],
- u8 ctr[]);
-
-asmlinkage void ce_aes_ccm_final(u8 mac[], u8 const ctr[], u32 const rk[],
- u32 rounds);
+ u8 ctr[], u8 const final_iv[]);
static int ccm_setkey(struct crypto_aead *tfm, const u8 *in_key,
unsigned int key_len)
@@ -94,6 +97,41 @@ static int ccm_init_mac(struct aead_request *req, u8 maciv[], u32 msglen)
return 0;
}
+static u32 ce_aes_ccm_auth_data(u8 mac[], u8 const in[], u32 abytes,
+ u32 macp, u32 const rk[], u32 rounds)
+{
+ int enc_after = (macp + abytes) % AES_BLOCK_SIZE;
+
+ do {
+ u32 blocks = abytes / AES_BLOCK_SIZE;
+
+ if (macp == AES_BLOCK_SIZE || (!macp && blocks > 0)) {
+ u32 rem = ce_aes_mac_update(in, rk, rounds, blocks, mac,
+ macp, enc_after);
+ u32 adv = (blocks - rem) * AES_BLOCK_SIZE;
+
+ macp = enc_after ? 0 : AES_BLOCK_SIZE;
+ in += adv;
+ abytes -= adv;
+
+ if (unlikely(rem)) {
+ kernel_neon_end();
+ kernel_neon_begin();
+ macp = 0;
+ }
+ } else {
+ u32 l = min(AES_BLOCK_SIZE - macp, abytes);
+
+ crypto_xor(&mac[macp], in, l);
+ in += l;
+ macp += l;
+ abytes -= l;
+ }
+ } while (abytes > 0);
+
+ return macp;
+}
+
static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[])
{
struct crypto_aead *aead = crypto_aead_reqtfm(req);
@@ -101,7 +139,7 @@ static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[])
struct __packed { __be16 l; __be32 h; u16 len; } ltag;
struct scatter_walk walk;
u32 len = req->assoclen;
- u32 macp = 0;
+ u32 macp = AES_BLOCK_SIZE;
/* prepend the AAD with a length tag */
if (len < 0xff00) {
@@ -125,16 +163,11 @@ static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[])
scatterwalk_start(&walk, sg_next(walk.sg));
n = scatterwalk_clamp(&walk, len);
}
- n = min_t(u32, n, SZ_4K); /* yield NEON at least every 4k */
p = scatterwalk_map(&walk);
macp = ce_aes_ccm_auth_data(mac, p, n, macp, ctx->key_enc,
num_rounds(ctx));
- if (len / SZ_4K > (len - n) / SZ_4K) {
- kernel_neon_end();
- kernel_neon_begin();
- }
len -= n;
scatterwalk_unmap(p);
@@ -149,7 +182,7 @@ static int ccm_encrypt(struct aead_request *req)
struct crypto_aes_ctx *ctx = crypto_aead_ctx(aead);
struct skcipher_walk walk;
u8 __aligned(8) mac[AES_BLOCK_SIZE];
- u8 buf[AES_BLOCK_SIZE];
+ u8 orig_iv[AES_BLOCK_SIZE];
u32 len = req->cryptlen;
int err;
@@ -158,42 +191,55 @@ static int ccm_encrypt(struct aead_request *req)
return err;
/* preserve the original iv for the final round */
- memcpy(buf, req->iv, AES_BLOCK_SIZE);
+ memcpy(orig_iv, req->iv, AES_BLOCK_SIZE);
err = skcipher_walk_aead_encrypt(&walk, req, false);
+ if (unlikely(err))
+ return err;
kernel_neon_begin();
if (req->assoclen)
ccm_calculate_auth_mac(req, mac);
- while (walk.nbytes) {
+ do {
u32 tail = walk.nbytes % AES_BLOCK_SIZE;
- bool final = walk.nbytes == walk.total;
+ const u8 *src = walk.src.virt.addr;
+ u8 *dst = walk.dst.virt.addr;
+ u8 buf[AES_BLOCK_SIZE];
+ u8 *final_iv = NULL;
- if (final)
+ if (walk.nbytes == walk.total) {
tail = 0;
+ final_iv = orig_iv;
+ }
- ce_aes_ccm_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
- walk.nbytes - tail, ctx->key_enc,
- num_rounds(ctx), mac, walk.iv);
+ if (unlikely(walk.nbytes < AES_BLOCK_SIZE))
+ src = dst = memcpy(&buf[sizeof(buf) - walk.nbytes],
+ src, walk.nbytes);
- if (!final)
- kernel_neon_end();
- err = skcipher_walk_done(&walk, tail);
- if (!final)
- kernel_neon_begin();
- }
+ ce_aes_ccm_encrypt(dst, src, walk.nbytes - tail,
+ ctx->key_enc, num_rounds(ctx),
+ mac, walk.iv, final_iv);
+
+ if (unlikely(walk.nbytes < AES_BLOCK_SIZE))
+ memcpy(walk.dst.virt.addr, dst, walk.nbytes);
- ce_aes_ccm_final(mac, buf, ctx->key_enc, num_rounds(ctx));
+ if (walk.nbytes) {
+ err = skcipher_walk_done(&walk, tail);
+ }
+ } while (walk.nbytes);
kernel_neon_end();
+ if (unlikely(err))
+ return err;
+
/* copy authtag to end of dst */
scatterwalk_map_and_copy(mac, req->dst, req->assoclen + req->cryptlen,
crypto_aead_authsize(aead), 1);
- return err;
+ return 0;
}
static int ccm_decrypt(struct aead_request *req)
@@ -203,7 +249,7 @@ static int ccm_decrypt(struct aead_request *req)
unsigned int authsize = crypto_aead_authsize(aead);
struct skcipher_walk walk;
u8 __aligned(8) mac[AES_BLOCK_SIZE];
- u8 buf[AES_BLOCK_SIZE];
+ u8 orig_iv[AES_BLOCK_SIZE];
u32 len = req->cryptlen - authsize;
int err;
@@ -212,34 +258,44 @@ static int ccm_decrypt(struct aead_request *req)
return err;
/* preserve the original iv for the final round */
- memcpy(buf, req->iv, AES_BLOCK_SIZE);
+ memcpy(orig_iv, req->iv, AES_BLOCK_SIZE);
err = skcipher_walk_aead_decrypt(&walk, req, false);
+ if (unlikely(err))
+ return err;
kernel_neon_begin();
if (req->assoclen)
ccm_calculate_auth_mac(req, mac);
- while (walk.nbytes) {
+ do {
u32 tail = walk.nbytes % AES_BLOCK_SIZE;
- bool final = walk.nbytes == walk.total;
+ const u8 *src = walk.src.virt.addr;
+ u8 *dst = walk.dst.virt.addr;
+ u8 buf[AES_BLOCK_SIZE];
+ u8 *final_iv = NULL;
- if (final)
+ if (walk.nbytes == walk.total) {
tail = 0;
+ final_iv = orig_iv;
+ }
- ce_aes_ccm_decrypt(walk.dst.virt.addr, walk.src.virt.addr,
- walk.nbytes - tail, ctx->key_enc,
- num_rounds(ctx), mac, walk.iv);
+ if (unlikely(walk.nbytes < AES_BLOCK_SIZE))
+ src = dst = memcpy(&buf[sizeof(buf) - walk.nbytes],
+ src, walk.nbytes);
- if (!final)
- kernel_neon_end();
- err = skcipher_walk_done(&walk, tail);
- if (!final)
- kernel_neon_begin();
- }
+ ce_aes_ccm_decrypt(dst, src, walk.nbytes - tail,
+ ctx->key_enc, num_rounds(ctx),
+ mac, walk.iv, final_iv);
+
+ if (unlikely(walk.nbytes < AES_BLOCK_SIZE))
+ memcpy(walk.dst.virt.addr, dst, walk.nbytes);
- ce_aes_ccm_final(mac, buf, ctx->key_enc, num_rounds(ctx));
+ if (walk.nbytes) {
+ err = skcipher_walk_done(&walk, tail);
+ }
+ } while (walk.nbytes);
kernel_neon_end();
@@ -247,11 +303,11 @@ static int ccm_decrypt(struct aead_request *req)
return err;
/* compare calculated auth tag with the stored one */
- scatterwalk_map_and_copy(buf, req->src,
+ scatterwalk_map_and_copy(orig_iv, req->src,
req->assoclen + req->cryptlen - authsize,
authsize, 0);
- if (crypto_memneq(mac, buf, authsize))
+ if (crypto_memneq(mac, orig_iv, authsize))
return -EBADMSG;
return 0;
}
@@ -290,6 +346,6 @@ module_init(aes_mod_init);
module_exit(aes_mod_exit);
MODULE_DESCRIPTION("Synchronous AES in CCM mode using ARMv8 Crypto Extensions");
-MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
+MODULE_AUTHOR("Ard Biesheuvel <ardb@kernel.org>");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS_CRYPTO("ccm(aes)");
diff --git a/arch/arm64/crypto/aes-glue.c b/arch/arm64/crypto/aes-glue.c
index 162787c7aa86..a147e847a5a1 100644
--- a/arch/arm64/crypto/aes-glue.c
+++ b/arch/arm64/crypto/aes-glue.c
@@ -1048,6 +1048,7 @@ unregister_ciphers:
#ifdef USE_V8_CRYPTO_EXTENSIONS
module_cpu_feature_match(AES, aes_init);
+EXPORT_SYMBOL_NS(ce_aes_mac_update, CRYPTO_INTERNAL);
#else
module_init(aes_init);
EXPORT_SYMBOL(neon_aes_ecb_encrypt);
diff --git a/arch/arm64/hyperv/hv_core.c b/arch/arm64/hyperv/hv_core.c
index b54c34793701..f1ebc025e1df 100644
--- a/arch/arm64/hyperv/hv_core.c
+++ b/arch/arm64/hyperv/hv_core.c
@@ -160,22 +160,22 @@ void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die)
return;
panic_reported = true;
- guest_id = hv_get_vpreg(HV_REGISTER_GUEST_OSID);
+ guest_id = hv_get_vpreg(HV_REGISTER_GUEST_OS_ID);
/*
* Hyper-V provides the ability to store only 5 values.
* Pick the passed in error value, the guest_id, the PC,
* and the SP.
*/
- hv_set_vpreg(HV_REGISTER_CRASH_P0, err);
- hv_set_vpreg(HV_REGISTER_CRASH_P1, guest_id);
- hv_set_vpreg(HV_REGISTER_CRASH_P2, regs->pc);
- hv_set_vpreg(HV_REGISTER_CRASH_P3, regs->sp);
- hv_set_vpreg(HV_REGISTER_CRASH_P4, 0);
+ hv_set_vpreg(HV_REGISTER_GUEST_CRASH_P0, err);
+ hv_set_vpreg(HV_REGISTER_GUEST_CRASH_P1, guest_id);
+ hv_set_vpreg(HV_REGISTER_GUEST_CRASH_P2, regs->pc);
+ hv_set_vpreg(HV_REGISTER_GUEST_CRASH_P3, regs->sp);
+ hv_set_vpreg(HV_REGISTER_GUEST_CRASH_P4, 0);
/*
* Let Hyper-V know there is crash data available
*/
- hv_set_vpreg(HV_REGISTER_CRASH_CTL, HV_CRASH_CTL_CRASH_NOTIFY);
+ hv_set_vpreg(HV_REGISTER_GUEST_CRASH_CTL, HV_CRASH_CTL_CRASH_NOTIFY);
}
EXPORT_SYMBOL_GPL(hyperv_report_panic);
diff --git a/arch/arm64/hyperv/mshyperv.c b/arch/arm64/hyperv/mshyperv.c
index f1b8a04ee9f2..b1a4de4eee29 100644
--- a/arch/arm64/hyperv/mshyperv.c
+++ b/arch/arm64/hyperv/mshyperv.c
@@ -19,10 +19,17 @@
static bool hyperv_initialized;
+int hv_get_hypervisor_version(union hv_hypervisor_version_info *info)
+{
+ hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION,
+ (struct hv_get_vp_registers_output *)info);
+
+ return 0;
+}
+
static int __init hyperv_init(void)
{
struct hv_get_vp_registers_output result;
- u32 a, b, c, d;
u64 guest_id;
int ret;
@@ -39,7 +46,7 @@ static int __init hyperv_init(void)
/* Setup the guest ID */
guest_id = hv_generate_guest_id(LINUX_VERSION_CODE);
- hv_set_vpreg(HV_REGISTER_GUEST_OSID, guest_id);
+ hv_set_vpreg(HV_REGISTER_GUEST_OS_ID, guest_id);
/* Get the features and hints from Hyper-V */
hv_get_vpreg_128(HV_REGISTER_FEATURES, &result);
@@ -54,15 +61,6 @@ static int __init hyperv_init(void)
ms_hyperv.features, ms_hyperv.priv_high, ms_hyperv.hints,
ms_hyperv.misc_features);
- /* Get information about the Hyper-V host version */
- hv_get_vpreg_128(HV_REGISTER_HYPERVISOR_VERSION, &result);
- a = result.as32.a;
- b = result.as32.b;
- c = result.as32.c;
- d = result.as32.d;
- pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n",
- b >> 16, b & 0xFFFF, a, d & 0xFFFFFF, c, d >> 24);
-
ret = hv_common_init();
if (ret)
return ret;
@@ -74,6 +72,8 @@ static int __init hyperv_init(void)
return ret;
}
+ ms_hyperv_late_init();
+
hyperv_initialized = true;
return 0;
}
diff --git a/arch/arm64/include/asm/archrandom.h b/arch/arm64/include/asm/archrandom.h
index ecdb3cfcd0f8..8babfbe31f95 100644
--- a/arch/arm64/include/asm/archrandom.h
+++ b/arch/arm64/include/asm/archrandom.h
@@ -129,6 +129,4 @@ static inline bool __init __early_cpu_has_rndr(void)
return (ftr >> ID_AA64ISAR0_EL1_RNDR_SHIFT) & 0xf;
}
-u64 kaslr_early_init(void *fdt);
-
#endif /* _ASM_ARCHRANDOM_H */
diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index 513787e43329..ab8b396428da 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -38,10 +38,6 @@
msr daifset, #0xf
.endm
- .macro enable_daif
- msr daifclr, #0xf
- .endm
-
/*
* Save/restore interrupts.
*/
@@ -346,20 +342,6 @@ alternative_cb_end
.endm
/*
- * idmap_get_t0sz - get the T0SZ value needed to cover the ID map
- *
- * Calculate the maximum allowed value for TCR_EL1.T0SZ so that the
- * entire ID map region can be mapped. As T0SZ == (64 - #bits used),
- * this number conveniently equals the number of leading zeroes in
- * the physical address of _end.
- */
- .macro idmap_get_t0sz, reg
- adrp \reg, _end
- orr \reg, \reg, #(1 << VA_BITS_MIN) - 1
- clz \reg, \reg
- .endm
-
-/*
* tcr_compute_pa_size - set TCR.(I)PS to the highest supported
* ID_AA64MMFR0_EL1.PARange value
*
@@ -590,18 +572,27 @@ alternative_endif
.endm
/*
- * Offset ttbr1 to allow for 48-bit kernel VAs set with 52-bit PTRS_PER_PGD.
+ * If the kernel is built for 52-bit virtual addressing but the hardware only
+ * supports 48 bits, we cannot program the pgdir address into TTBR1 directly,
+ * but we have to add an offset so that the TTBR1 address corresponds with the
+ * pgdir entry that covers the lowest 48-bit addressable VA.
+ *
+ * Note that this trick is only used for LVA/64k pages - LPA2/4k pages uses an
+ * additional paging level, and on LPA2/16k pages, we would end up with a root
+ * level table with only 2 entries, which is suboptimal in terms of TLB
+ * utilization, so there we fall back to 47 bits of translation if LPA2 is not
+ * supported.
+ *
* orr is used as it can cover the immediate value (and is idempotent).
- * In future this may be nop'ed out when dealing with 52-bit kernel VAs.
* ttbr: Value of ttbr to set, modified.
*/
.macro offset_ttbr1, ttbr, tmp
-#ifdef CONFIG_ARM64_VA_BITS_52
- mrs_s \tmp, SYS_ID_AA64MMFR2_EL1
- and \tmp, \tmp, #(0xf << ID_AA64MMFR2_EL1_VARange_SHIFT)
- cbnz \tmp, .Lskipoffs_\@
- orr \ttbr, \ttbr, #TTBR1_BADDR_4852_OFFSET
-.Lskipoffs_\@ :
+#if defined(CONFIG_ARM64_VA_BITS_52) && !defined(CONFIG_ARM64_LPA2)
+ mrs \tmp, tcr_el1
+ and \tmp, \tmp, #TCR_T1SZ_MASK
+ cmp \tmp, #TCR_T1SZ(VA_BITS_MIN)
+ orr \tmp, \ttbr, #TTBR1_BADDR_4852_OFFSET
+ csel \ttbr, \tmp, \ttbr, eq
#endif
.endm
@@ -623,25 +614,13 @@ alternative_endif
.macro phys_to_pte, pte, phys
#ifdef CONFIG_ARM64_PA_BITS_52
- /*
- * We assume \phys is 64K aligned and this is guaranteed by only
- * supporting this configuration with 64K pages.
- */
- orr \pte, \phys, \phys, lsr #36
- and \pte, \pte, #PTE_ADDR_MASK
+ orr \pte, \phys, \phys, lsr #PTE_ADDR_HIGH_SHIFT
+ and \pte, \pte, #PHYS_TO_PTE_ADDR_MASK
#else
mov \pte, \phys
#endif
.endm
- .macro pte_to_phys, phys, pte
- and \phys, \pte, #PTE_ADDR_MASK
-#ifdef CONFIG_ARM64_PA_BITS_52
- orr \phys, \phys, \phys, lsl #PTE_ADDR_HIGH_SHIFT
- and \phys, \phys, GENMASK_ULL(PHYS_MASK_SHIFT - 1, PAGE_SHIFT)
-#endif
- .endm
-
/*
* tcr_clear_errata_bits - Clear TCR bits that trigger an errata on this CPU.
*/
diff --git a/arch/arm64/include/asm/brk-imm.h b/arch/arm64/include/asm/brk-imm.h
index 1abdcd508a11..beb42c62b6ac 100644
--- a/arch/arm64/include/asm/brk-imm.h
+++ b/arch/arm64/include/asm/brk-imm.h
@@ -11,6 +11,7 @@
* 0x004: for installing kprobes
* 0x005: for installing uprobes
* 0x006: for kprobe software single-step
+ * 0x007: for kretprobe return
* Allowed values for kgdb are 0x400 - 0x7ff
* 0x100: for triggering a fault on purpose (reserved)
* 0x400: for dynamic BRK instruction
@@ -23,6 +24,7 @@
#define KPROBES_BRK_IMM 0x004
#define UPROBES_BRK_IMM 0x005
#define KPROBES_BRK_SS_IMM 0x006
+#define KRETPROBES_BRK_IMM 0x007
#define FAULT_BRK_IMM 0x100
#define KGDB_DYN_DBG_BRK_IMM 0x400
#define KGDB_COMPILED_DBG_BRK_IMM 0x401
diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h
index b1e43f56ee46..9b73fd0cd721 100644
--- a/arch/arm64/include/asm/cpu.h
+++ b/arch/arm64/include/asm/cpu.h
@@ -52,14 +52,18 @@ struct cpuinfo_arm64 {
u64 reg_id_aa64isar0;
u64 reg_id_aa64isar1;
u64 reg_id_aa64isar2;
+ u64 reg_id_aa64isar3;
u64 reg_id_aa64mmfr0;
u64 reg_id_aa64mmfr1;
u64 reg_id_aa64mmfr2;
u64 reg_id_aa64mmfr3;
+ u64 reg_id_aa64mmfr4;
u64 reg_id_aa64pfr0;
u64 reg_id_aa64pfr1;
+ u64 reg_id_aa64pfr2;
u64 reg_id_aa64zfr0;
u64 reg_id_aa64smfr0;
+ u64 reg_id_aa64fpfr0;
struct cpuinfo_32bit aarch32;
};
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index bd8d4ca81a48..8b904a757bd3 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -17,6 +17,7 @@
#define ARM64_SW_FEATURE_OVERRIDE_NOKASLR 0
#define ARM64_SW_FEATURE_OVERRIDE_HVHE 4
+#define ARM64_SW_FEATURE_OVERRIDE_RODATA_OFF 8
#ifndef __ASSEMBLY__
@@ -363,6 +364,7 @@ struct arm64_cpu_capabilities {
u8 field_pos;
u8 field_width;
u8 min_field_value;
+ u8 max_field_value;
u8 hwcap_type;
bool sign;
unsigned long hwcap;
@@ -768,6 +770,11 @@ static __always_inline bool system_supports_tpidr2(void)
return system_supports_sme();
}
+static __always_inline bool system_supports_fpmr(void)
+{
+ return alternative_has_cap_unlikely(ARM64_HAS_FPMR);
+}
+
static __always_inline bool system_supports_cnp(void)
{
return alternative_has_cap_unlikely(ARM64_HAS_CNP);
@@ -905,7 +912,9 @@ static inline unsigned int get_vmid_bits(u64 mmfr1)
s64 arm64_ftr_safe_value(const struct arm64_ftr_bits *ftrp, s64 new, s64 cur);
struct arm64_ftr_reg *get_arm64_ftr_reg(u32 sys_id);
+extern struct arm64_ftr_override id_aa64mmfr0_override;
extern struct arm64_ftr_override id_aa64mmfr1_override;
+extern struct arm64_ftr_override id_aa64mmfr2_override;
extern struct arm64_ftr_override id_aa64pfr0_override;
extern struct arm64_ftr_override id_aa64pfr1_override;
extern struct arm64_ftr_override id_aa64zfr0_override;
@@ -915,9 +924,114 @@ extern struct arm64_ftr_override id_aa64isar2_override;
extern struct arm64_ftr_override arm64_sw_feature_override;
+static inline
+u64 arm64_apply_feature_override(u64 val, int feat, int width,
+ const struct arm64_ftr_override *override)
+{
+ u64 oval = override->val;
+
+ /*
+ * When it encounters an invalid override (e.g., an override that
+ * cannot be honoured due to a missing CPU feature), the early idreg
+ * override code will set the mask to 0x0 and the value to non-zero for
+ * the field in question. In order to determine whether the override is
+ * valid or not for the field we are interested in, we first need to
+ * disregard bits belonging to other fields.
+ */
+ oval &= GENMASK_ULL(feat + width - 1, feat);
+
+ /*
+ * The override is valid if all value bits are accounted for in the
+ * mask. If so, replace the masked bits with the override value.
+ */
+ if (oval == (oval & override->mask)) {
+ val &= ~override->mask;
+ val |= oval;
+ }
+
+ /* Extract the field from the updated value */
+ return cpuid_feature_extract_unsigned_field(val, feat);
+}
+
+static inline bool arm64_test_sw_feature_override(int feat)
+{
+ /*
+ * Software features are pseudo CPU features that have no underlying
+ * CPUID system register value to apply the override to.
+ */
+ return arm64_apply_feature_override(0, feat, 4,
+ &arm64_sw_feature_override);
+}
+
+static inline bool kaslr_disabled_cmdline(void)
+{
+ return arm64_test_sw_feature_override(ARM64_SW_FEATURE_OVERRIDE_NOKASLR);
+}
+
u32 get_kvm_ipa_limit(void);
void dump_cpu_features(void);
+static inline bool cpu_has_bti(void)
+{
+ if (!IS_ENABLED(CONFIG_ARM64_BTI))
+ return false;
+
+ return arm64_apply_feature_override(read_cpuid(ID_AA64PFR1_EL1),
+ ID_AA64PFR1_EL1_BT_SHIFT, 4,
+ &id_aa64pfr1_override);
+}
+
+static inline bool cpu_has_pac(void)
+{
+ u64 isar1, isar2;
+
+ if (!IS_ENABLED(CONFIG_ARM64_PTR_AUTH))
+ return false;
+
+ isar1 = read_cpuid(ID_AA64ISAR1_EL1);
+ isar2 = read_cpuid(ID_AA64ISAR2_EL1);
+
+ if (arm64_apply_feature_override(isar1, ID_AA64ISAR1_EL1_APA_SHIFT, 4,
+ &id_aa64isar1_override))
+ return true;
+
+ if (arm64_apply_feature_override(isar1, ID_AA64ISAR1_EL1_API_SHIFT, 4,
+ &id_aa64isar1_override))
+ return true;
+
+ return arm64_apply_feature_override(isar2, ID_AA64ISAR2_EL1_APA3_SHIFT, 4,
+ &id_aa64isar2_override);
+}
+
+static inline bool cpu_has_lva(void)
+{
+ u64 mmfr2;
+
+ mmfr2 = read_sysreg_s(SYS_ID_AA64MMFR2_EL1);
+ mmfr2 &= ~id_aa64mmfr2_override.mask;
+ mmfr2 |= id_aa64mmfr2_override.val;
+ return cpuid_feature_extract_unsigned_field(mmfr2,
+ ID_AA64MMFR2_EL1_VARange_SHIFT);
+}
+
+static inline bool cpu_has_lpa2(void)
+{
+#ifdef CONFIG_ARM64_LPA2
+ u64 mmfr0;
+ int feat;
+
+ mmfr0 = read_sysreg(id_aa64mmfr0_el1);
+ mmfr0 &= ~id_aa64mmfr0_override.mask;
+ mmfr0 |= id_aa64mmfr0_override.val;
+ feat = cpuid_feature_extract_signed_field(mmfr0,
+ ID_AA64MMFR0_EL1_TGRAN_SHIFT);
+
+ return feat >= ID_AA64MMFR0_EL1_TGRAN_LPA2;
+#else
+ return false;
+#endif
+}
+
#endif /* __ASSEMBLY__ */
#endif
diff --git a/arch/arm64/include/asm/crash_core.h b/arch/arm64/include/asm/crash_reserve.h
index 9f5c8d339f44..4afe027a4e7b 100644
--- a/arch/arm64/include/asm/crash_core.h
+++ b/arch/arm64/include/asm/crash_reserve.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-#ifndef _ARM64_CRASH_CORE_H
-#define _ARM64_CRASH_CORE_H
+#ifndef _ARM64_CRASH_RESERVE_H
+#define _ARM64_CRASH_RESERVE_H
/* Current arm64 boot protocol requires 2MB alignment */
#define CRASH_ALIGN SZ_2M
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 97932fbf973d..3f93f4eef953 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -201,16 +201,16 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
#define COMPAT_ELF_PLATFORM ("v8l")
#endif
-#ifdef CONFIG_COMPAT
-
-/* PIE load location for compat arm. Must match ARM ELF_ET_DYN_BASE. */
-#define COMPAT_ELF_ET_DYN_BASE 0x000400000UL
-
/* AArch32 registers. */
#define COMPAT_ELF_NGREG 18
typedef unsigned int compat_elf_greg_t;
typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG];
+#ifdef CONFIG_COMPAT
+
+/* PIE load location for compat arm. Must match ARM ELF_ET_DYN_BASE. */
+#define COMPAT_ELF_ET_DYN_BASE 0x000400000UL
+
/* AArch32 EABI. */
#define EF_ARM_EABI_MASK 0xff000000
int compat_elf_check_arch(const struct elf32_hdr *);
diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index 353fe08546cf..81606bf7d5ac 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -117,15 +117,9 @@
#define ESR_ELx_FSC_ACCESS (0x08)
#define ESR_ELx_FSC_FAULT (0x04)
#define ESR_ELx_FSC_PERM (0x0C)
-#define ESR_ELx_FSC_SEA_TTW0 (0x14)
-#define ESR_ELx_FSC_SEA_TTW1 (0x15)
-#define ESR_ELx_FSC_SEA_TTW2 (0x16)
-#define ESR_ELx_FSC_SEA_TTW3 (0x17)
+#define ESR_ELx_FSC_SEA_TTW(n) (0x14 + (n))
#define ESR_ELx_FSC_SECC (0x18)
-#define ESR_ELx_FSC_SECC_TTW0 (0x1c)
-#define ESR_ELx_FSC_SECC_TTW1 (0x1d)
-#define ESR_ELx_FSC_SECC_TTW2 (0x1e)
-#define ESR_ELx_FSC_SECC_TTW3 (0x1f)
+#define ESR_ELx_FSC_SECC_TTW(n) (0x1c + (n))
/* ISS field definitions for Data Aborts */
#define ESR_ELx_ISV_SHIFT (24)
@@ -394,6 +388,9 @@ static inline bool esr_is_data_abort(unsigned long esr)
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;
}
diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h
index ad688e157c9b..f296662590c7 100644
--- a/arch/arm64/include/asm/exception.h
+++ b/arch/arm64/include/asm/exception.h
@@ -74,7 +74,7 @@ void do_el0_fpac(struct pt_regs *regs, unsigned long esr);
void do_el1_fpac(struct pt_regs *regs, unsigned long esr);
void do_el0_mops(struct pt_regs *regs, unsigned long esr);
void do_serror(struct pt_regs *regs, unsigned long esr);
-void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags);
+void do_signal(struct pt_regs *regs);
void __noreturn panic_bad_stack(struct pt_regs *regs, unsigned long esr, unsigned long far);
#endif /* __ASM_EXCEPTION_H */
diff --git a/arch/arm64/include/asm/fixmap.h b/arch/arm64/include/asm/fixmap.h
index 58c294a96676..87e307804b99 100644
--- a/arch/arm64/include/asm/fixmap.h
+++ b/arch/arm64/include/asm/fixmap.h
@@ -87,6 +87,7 @@ enum fixed_addresses {
FIX_PTE,
FIX_PMD,
FIX_PUD,
+ FIX_P4D,
FIX_PGD,
__end_of_fixed_addresses
@@ -100,7 +101,6 @@ enum fixed_addresses {
#define FIXMAP_PAGE_IO __pgprot(PROT_DEVICE_nGnRE)
void __init early_fixmap_init(void);
-void __init fixmap_copy(pgd_t *pgdir);
#define __early_set_fixmap __set_fixmap
diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index b67b89c54e1c..bc69ac368d73 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -21,7 +21,6 @@
#include <linux/stddef.h>
#include <linux/types.h>
-#ifdef CONFIG_COMPAT
/* Masks for extracting the FPSR and FPCR from the FPSCR */
#define VFP_FPSCR_STAT_MASK 0xf800009f
#define VFP_FPSCR_CTRL_MASK 0x07f79f00
@@ -30,7 +29,6 @@
* control/status register.
*/
#define VFP_STATE_SIZE ((32 * 8) + 4)
-#endif
static inline unsigned long cpacr_save_enable_kernel_sve(void)
{
@@ -89,6 +87,7 @@ struct cpu_fp_state {
void *sve_state;
void *sme_state;
u64 *svcr;
+ u64 *fpmr;
unsigned int sve_vl;
unsigned int sme_vl;
enum fp_type *fp_type;
@@ -154,6 +153,7 @@ extern void cpu_enable_sve(const struct arm64_cpu_capabilities *__unused);
extern void cpu_enable_sme(const struct arm64_cpu_capabilities *__unused);
extern void cpu_enable_sme2(const struct arm64_cpu_capabilities *__unused);
extern void cpu_enable_fa64(const struct arm64_cpu_capabilities *__unused);
+extern void cpu_enable_fpmr(const struct arm64_cpu_capabilities *__unused);
extern u64 read_smcr_features(void);
diff --git a/arch/arm64/include/asm/hw_breakpoint.h b/arch/arm64/include/asm/hw_breakpoint.h
index 84055329cd8b..bd81cf17744a 100644
--- a/arch/arm64/include/asm/hw_breakpoint.h
+++ b/arch/arm64/include/asm/hw_breakpoint.h
@@ -59,7 +59,6 @@ static inline void decode_ctrl_reg(u32 reg,
/* Watchpoints */
#define ARM_BREAKPOINT_LOAD 1
#define ARM_BREAKPOINT_STORE 2
-#define AARCH64_ESR_ACCESS_MASK (1 << 6)
/* Lengths */
#define ARM_BREAKPOINT_LEN_1 0x1
diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h
index cd71e09ea14d..4edd3b61df11 100644
--- a/arch/arm64/include/asm/hwcap.h
+++ b/arch/arm64/include/asm/hwcap.h
@@ -142,6 +142,21 @@
#define KERNEL_HWCAP_SVE_B16B16 __khwcap2_feature(SVE_B16B16)
#define KERNEL_HWCAP_LRCPC3 __khwcap2_feature(LRCPC3)
#define KERNEL_HWCAP_LSE128 __khwcap2_feature(LSE128)
+#define KERNEL_HWCAP_FPMR __khwcap2_feature(FPMR)
+#define KERNEL_HWCAP_LUT __khwcap2_feature(LUT)
+#define KERNEL_HWCAP_FAMINMAX __khwcap2_feature(FAMINMAX)
+#define KERNEL_HWCAP_F8CVT __khwcap2_feature(F8CVT)
+#define KERNEL_HWCAP_F8FMA __khwcap2_feature(F8FMA)
+#define KERNEL_HWCAP_F8DP4 __khwcap2_feature(F8DP4)
+#define KERNEL_HWCAP_F8DP2 __khwcap2_feature(F8DP2)
+#define KERNEL_HWCAP_F8E4M3 __khwcap2_feature(F8E4M3)
+#define KERNEL_HWCAP_F8E5M2 __khwcap2_feature(F8E5M2)
+#define KERNEL_HWCAP_SME_LUTV2 __khwcap2_feature(SME_LUTV2)
+#define KERNEL_HWCAP_SME_F8F16 __khwcap2_feature(SME_F8F16)
+#define KERNEL_HWCAP_SME_F8F32 __khwcap2_feature(SME_F8F32)
+#define KERNEL_HWCAP_SME_SF8FMA __khwcap2_feature(SME_SF8FMA)
+#define KERNEL_HWCAP_SME_SF8DP4 __khwcap2_feature(SME_SF8DP4)
+#define KERNEL_HWCAP_SME_SF8DP2 __khwcap2_feature(SME_SF8DP2)
/*
* This yields a mask that user programs can use to figure out what
diff --git a/arch/arm64/include/asm/hyperv-tlfs.h b/arch/arm64/include/asm/hyperv-tlfs.h
index bc6c7ac934a1..bc30aadedfe9 100644
--- a/arch/arm64/include/asm/hyperv-tlfs.h
+++ b/arch/arm64/include/asm/hyperv-tlfs.h
@@ -22,14 +22,6 @@
*/
/*
- * These Hyper-V registers provide information equivalent to the CPUID
- * instruction on x86/x64.
- */
-#define HV_REGISTER_HYPERVISOR_VERSION 0x00000100 /*CPUID 0x40000002 */
-#define HV_REGISTER_FEATURES 0x00000200 /*CPUID 0x40000003 */
-#define HV_REGISTER_ENLIGHTENMENTS 0x00000201 /*CPUID 0x40000004 */
-
-/*
* Group C Features. See the asm-generic version of hyperv-tlfs.h
* for a description of Feature Groups.
*/
@@ -41,28 +33,29 @@
#define HV_STIMER_DIRECT_MODE_AVAILABLE BIT(13)
/*
- * Synthetic register definitions equivalent to MSRs on x86/x64
+ * To support arch-generic code calling hv_set/get_register:
+ * - On x86, HV_MSR_ indicates an MSR accessed via rdmsrl/wrmsrl
+ * - On ARM, HV_MSR_ indicates a VP register accessed via hypercall
*/
-#define HV_REGISTER_CRASH_P0 0x00000210
-#define HV_REGISTER_CRASH_P1 0x00000211
-#define HV_REGISTER_CRASH_P2 0x00000212
-#define HV_REGISTER_CRASH_P3 0x00000213
-#define HV_REGISTER_CRASH_P4 0x00000214
-#define HV_REGISTER_CRASH_CTL 0x00000215
+#define HV_MSR_CRASH_P0 (HV_REGISTER_GUEST_CRASH_P0)
+#define HV_MSR_CRASH_P1 (HV_REGISTER_GUEST_CRASH_P1)
+#define HV_MSR_CRASH_P2 (HV_REGISTER_GUEST_CRASH_P2)
+#define HV_MSR_CRASH_P3 (HV_REGISTER_GUEST_CRASH_P3)
+#define HV_MSR_CRASH_P4 (HV_REGISTER_GUEST_CRASH_P4)
+#define HV_MSR_CRASH_CTL (HV_REGISTER_GUEST_CRASH_CTL)
-#define HV_REGISTER_GUEST_OSID 0x00090002
-#define HV_REGISTER_VP_INDEX 0x00090003
-#define HV_REGISTER_TIME_REF_COUNT 0x00090004
-#define HV_REGISTER_REFERENCE_TSC 0x00090017
+#define HV_MSR_VP_INDEX (HV_REGISTER_VP_INDEX)
+#define HV_MSR_TIME_REF_COUNT (HV_REGISTER_TIME_REF_COUNT)
+#define HV_MSR_REFERENCE_TSC (HV_REGISTER_REFERENCE_TSC)
-#define HV_REGISTER_SINT0 0x000A0000
-#define HV_REGISTER_SCONTROL 0x000A0010
-#define HV_REGISTER_SIEFP 0x000A0012
-#define HV_REGISTER_SIMP 0x000A0013
-#define HV_REGISTER_EOM 0x000A0014
+#define HV_MSR_SINT0 (HV_REGISTER_SINT0)
+#define HV_MSR_SCONTROL (HV_REGISTER_SCONTROL)
+#define HV_MSR_SIEFP (HV_REGISTER_SIEFP)
+#define HV_MSR_SIMP (HV_REGISTER_SIMP)
+#define HV_MSR_EOM (HV_REGISTER_EOM)
-#define HV_REGISTER_STIMER0_CONFIG 0x000B0000
-#define HV_REGISTER_STIMER0_COUNT 0x000B0001
+#define HV_MSR_STIMER0_CONFIG (HV_REGISTER_STIMER0_CONFIG)
+#define HV_MSR_STIMER0_COUNT (HV_REGISTER_STIMER0_COUNT)
union hv_msi_entry {
u64 as_uint64[2];
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 3b694511b98f..8d825522c55c 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -24,25 +24,29 @@
#define __raw_writeb __raw_writeb
static __always_inline void __raw_writeb(u8 val, volatile void __iomem *addr)
{
- asm volatile("strb %w0, [%1]" : : "rZ" (val), "r" (addr));
+ volatile u8 __iomem *ptr = addr;
+ asm volatile("strb %w0, %1" : : "rZ" (val), "Qo" (*ptr));
}
#define __raw_writew __raw_writew
static __always_inline void __raw_writew(u16 val, volatile void __iomem *addr)
{
- asm volatile("strh %w0, [%1]" : : "rZ" (val), "r" (addr));
+ volatile u16 __iomem *ptr = addr;
+ asm volatile("strh %w0, %1" : : "rZ" (val), "Qo" (*ptr));
}
#define __raw_writel __raw_writel
static __always_inline void __raw_writel(u32 val, volatile void __iomem *addr)
{
- asm volatile("str %w0, [%1]" : : "rZ" (val), "r" (addr));
+ volatile u32 __iomem *ptr = addr;
+ asm volatile("str %w0, %1" : : "rZ" (val), "Qo" (*ptr));
}
#define __raw_writeq __raw_writeq
static __always_inline void __raw_writeq(u64 val, volatile void __iomem *addr)
{
- asm volatile("str %x0, [%1]" : : "rZ" (val), "r" (addr));
+ volatile u64 __iomem *ptr = addr;
+ asm volatile("str %x0, %1" : : "rZ" (val), "Qo" (*ptr));
}
#define __raw_readb __raw_readb
diff --git a/arch/arm64/include/asm/kasan.h b/arch/arm64/include/asm/kasan.h
index 7eefc525a9df..e1b57c13f8a4 100644
--- a/arch/arm64/include/asm/kasan.h
+++ b/arch/arm64/include/asm/kasan.h
@@ -17,11 +17,9 @@
asmlinkage void kasan_early_init(void);
void kasan_init(void);
-void kasan_copy_shadow(pgd_t *pgdir);
#else
static inline void kasan_init(void) { }
-static inline void kasan_copy_shadow(pgd_t *pgdir) { }
#endif
#endif
diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h
index 83ddb14b95a5..bf05a77873a4 100644
--- a/arch/arm64/include/asm/kernel-pgtable.h
+++ b/arch/arm64/include/asm/kernel-pgtable.h
@@ -13,28 +13,27 @@
#include <asm/sparsemem.h>
/*
- * The linear mapping and the start of memory are both 2M aligned (per
- * the arm64 booting.txt requirements). Hence we can use section mapping
- * with 4K (section size = 2M) but not with 16K (section size = 32M) or
- * 64K (section size = 512M).
+ * The physical and virtual addresses of the start of the kernel image are
+ * equal modulo 2 MiB (per the arm64 booting.txt requirements). Hence we can
+ * use section mapping with 4K (section size = 2M) but not with 16K (section
+ * size = 32M) or 64K (section size = 512M).
*/
-
-/*
- * The idmap and swapper page tables need some space reserved in the kernel
- * image. Both require pgd, pud (4 levels only) and pmd tables to (section)
- * map the kernel. With the 64K page configuration, swapper and idmap need to
- * map to pte level. The swapper also maps the FDT (see __create_page_tables
- * for more information). Note that the number of ID map translation levels
- * could be increased on the fly if system RAM is out of reach for the default
- * VA range, so pages required to map highest possible PA are reserved in all
- * cases.
- */
-#ifdef CONFIG_ARM64_4K_PAGES
-#define SWAPPER_PGTABLE_LEVELS (CONFIG_PGTABLE_LEVELS - 1)
+#if defined(PMD_SIZE) && PMD_SIZE <= MIN_KIMG_ALIGN
+#define SWAPPER_BLOCK_SHIFT PMD_SHIFT
+#define SWAPPER_SKIP_LEVEL 1
#else
-#define SWAPPER_PGTABLE_LEVELS (CONFIG_PGTABLE_LEVELS)
+#define SWAPPER_BLOCK_SHIFT PAGE_SHIFT
+#define SWAPPER_SKIP_LEVEL 0
#endif
+#define SWAPPER_BLOCK_SIZE (UL(1) << SWAPPER_BLOCK_SHIFT)
+#define SWAPPER_TABLE_SHIFT (SWAPPER_BLOCK_SHIFT + PAGE_SHIFT - 3)
+#define SWAPPER_PGTABLE_LEVELS (CONFIG_PGTABLE_LEVELS - SWAPPER_SKIP_LEVEL)
+#define INIT_IDMAP_PGTABLE_LEVELS (IDMAP_LEVELS - SWAPPER_SKIP_LEVEL)
+
+#define IDMAP_VA_BITS 48
+#define IDMAP_LEVELS ARM64_HW_PGTABLE_LEVELS(IDMAP_VA_BITS)
+#define IDMAP_ROOT_LEVEL (4 - IDMAP_LEVELS)
/*
* A relocatable kernel may execute from an address that differs from the one at
@@ -50,57 +49,39 @@
#define EARLY_ENTRIES(vstart, vend, shift, add) \
(SPAN_NR_ENTRIES(vstart, vend, shift) + (add))
-#define EARLY_PGDS(vstart, vend, add) (EARLY_ENTRIES(vstart, vend, PGDIR_SHIFT, add))
-
-#if SWAPPER_PGTABLE_LEVELS > 3
-#define EARLY_PUDS(vstart, vend, add) (EARLY_ENTRIES(vstart, vend, PUD_SHIFT, add))
-#else
-#define EARLY_PUDS(vstart, vend, add) (0)
-#endif
+#define EARLY_LEVEL(lvl, lvls, vstart, vend, add) \
+ (lvls > lvl ? EARLY_ENTRIES(vstart, vend, SWAPPER_BLOCK_SHIFT + lvl * (PAGE_SHIFT - 3), add) : 0)
-#if SWAPPER_PGTABLE_LEVELS > 2
-#define EARLY_PMDS(vstart, vend, add) (EARLY_ENTRIES(vstart, vend, SWAPPER_TABLE_SHIFT, add))
-#else
-#define EARLY_PMDS(vstart, vend, add) (0)
-#endif
+#define EARLY_PAGES(lvls, vstart, vend, add) (1 /* PGDIR page */ \
+ + EARLY_LEVEL(3, (lvls), (vstart), (vend), add) /* each entry needs a next level page table */ \
+ + EARLY_LEVEL(2, (lvls), (vstart), (vend), add) /* each entry needs a next level page table */ \
+ + EARLY_LEVEL(1, (lvls), (vstart), (vend), add))/* each entry needs a next level page table */
+#define INIT_DIR_SIZE (PAGE_SIZE * (EARLY_PAGES(SWAPPER_PGTABLE_LEVELS, KIMAGE_VADDR, _end, EXTRA_PAGE) \
+ + EARLY_SEGMENT_EXTRA_PAGES))
-#define EARLY_PAGES(vstart, vend, add) ( 1 /* PGDIR page */ \
- + EARLY_PGDS((vstart), (vend), add) /* each PGDIR needs a next level page table */ \
- + EARLY_PUDS((vstart), (vend), add) /* each PUD needs a next level page table */ \
- + EARLY_PMDS((vstart), (vend), add)) /* each PMD needs a next level page table */
-#define INIT_DIR_SIZE (PAGE_SIZE * EARLY_PAGES(KIMAGE_VADDR, _end, EXTRA_PAGE))
+#define INIT_IDMAP_DIR_PAGES (EARLY_PAGES(INIT_IDMAP_PGTABLE_LEVELS, KIMAGE_VADDR, _end, 1))
+#define INIT_IDMAP_DIR_SIZE ((INIT_IDMAP_DIR_PAGES + EARLY_IDMAP_EXTRA_PAGES) * PAGE_SIZE)
-/* the initial ID map may need two extra pages if it needs to be extended */
-#if VA_BITS < 48
-#define INIT_IDMAP_DIR_SIZE ((INIT_IDMAP_DIR_PAGES + 2) * PAGE_SIZE)
-#else
-#define INIT_IDMAP_DIR_SIZE (INIT_IDMAP_DIR_PAGES * PAGE_SIZE)
-#endif
-#define INIT_IDMAP_DIR_PAGES EARLY_PAGES(KIMAGE_VADDR, _end + MAX_FDT_SIZE + SWAPPER_BLOCK_SIZE, 1)
+#define INIT_IDMAP_FDT_PAGES (EARLY_PAGES(INIT_IDMAP_PGTABLE_LEVELS, 0UL, UL(MAX_FDT_SIZE), 1) - 1)
+#define INIT_IDMAP_FDT_SIZE ((INIT_IDMAP_FDT_PAGES + EARLY_IDMAP_EXTRA_FDT_PAGES) * PAGE_SIZE)
-/* Initial memory map size */
-#ifdef CONFIG_ARM64_4K_PAGES
-#define SWAPPER_BLOCK_SHIFT PMD_SHIFT
-#define SWAPPER_BLOCK_SIZE PMD_SIZE
-#define SWAPPER_TABLE_SHIFT PUD_SHIFT
-#else
-#define SWAPPER_BLOCK_SHIFT PAGE_SHIFT
-#define SWAPPER_BLOCK_SIZE PAGE_SIZE
-#define SWAPPER_TABLE_SHIFT PMD_SHIFT
-#endif
+/* The number of segments in the kernel image (text, rodata, inittext, initdata, data+bss) */
+#define KERNEL_SEGMENT_COUNT 5
+#if SWAPPER_BLOCK_SIZE > SEGMENT_ALIGN
+#define EARLY_SEGMENT_EXTRA_PAGES (KERNEL_SEGMENT_COUNT + 1)
/*
- * Initial memory map attributes.
+ * The initial ID map consists of the kernel image, mapped as two separate
+ * segments, and may appear misaligned wrt the swapper block size. This means
+ * we need 3 additional pages. The DT could straddle a swapper block boundary,
+ * so it may need 2.
*/
-#define SWAPPER_PTE_FLAGS (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED | PTE_UXN)
-#define SWAPPER_PMD_FLAGS (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S | PTE_UXN)
-
-#ifdef CONFIG_ARM64_4K_PAGES
-#define SWAPPER_RW_MMUFLAGS (PMD_ATTRINDX(MT_NORMAL) | SWAPPER_PMD_FLAGS | PTE_WRITE)
-#define SWAPPER_RX_MMUFLAGS (SWAPPER_RW_MMUFLAGS | PMD_SECT_RDONLY)
+#define EARLY_IDMAP_EXTRA_PAGES 3
+#define EARLY_IDMAP_EXTRA_FDT_PAGES 2
#else
-#define SWAPPER_RW_MMUFLAGS (PTE_ATTRINDX(MT_NORMAL) | SWAPPER_PTE_FLAGS | PTE_WRITE)
-#define SWAPPER_RX_MMUFLAGS (SWAPPER_RW_MMUFLAGS | PTE_RDONLY)
+#define EARLY_SEGMENT_EXTRA_PAGES 0
+#define EARLY_IDMAP_EXTRA_PAGES 0
+#define EARLY_IDMAP_EXTRA_FDT_PAGES 0
#endif
#endif /* __ASM_KERNEL_PGTABLE_H */
diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
index 9ac9572a3bbe..4d9cc7a76d9c 100644
--- a/arch/arm64/include/asm/kexec.h
+++ b/arch/arm64/include/asm/kexec.h
@@ -80,7 +80,7 @@ static inline void crash_setup_regs(struct pt_regs *newregs,
}
}
-#if defined(CONFIG_KEXEC_CORE) && defined(CONFIG_HIBERNATION)
+#if defined(CONFIG_CRASH_DUMP) && defined(CONFIG_HIBERNATION)
extern bool crash_is_nosave(unsigned long pfn);
extern void crash_prepare_suspend(void);
extern void crash_post_resume(void);
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 3c6f8ba1e479..e01bb5ca13b7 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -102,10 +102,8 @@
#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 | \
- (cpus_have_final_cap(ARM64_HAS_MOPS) ? (HCRX_EL2_MSCEn | HCRX_EL2_MCE2) : 0))
-#define HCRX_HOST_FLAGS (HCRX_EL2_MSCEn | HCRX_EL2_TCR2En)
+#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 */
#define TCR_EL2_DS (1UL << 32)
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index b804fe832184..975af30af31f 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -209,7 +209,8 @@ static inline bool vcpu_is_el2(const struct kvm_vcpu *vcpu)
static inline bool __vcpu_el2_e2h_is_set(const struct kvm_cpu_context *ctxt)
{
- return ctxt_sys_reg(ctxt, HCR_EL2) & HCR_E2H;
+ return (!cpus_have_final_cap(ARM64_HAS_HCR_NV1) ||
+ (ctxt_sys_reg(ctxt, HCR_EL2) & HCR_E2H));
}
static inline bool vcpu_el2_e2h_is_set(const struct kvm_vcpu *vcpu)
@@ -425,15 +426,9 @@ static __always_inline bool kvm_vcpu_abt_issea(const struct kvm_vcpu *vcpu)
{
switch (kvm_vcpu_trap_get_fault(vcpu)) {
case ESR_ELx_FSC_EXTABT:
- case ESR_ELx_FSC_SEA_TTW0:
- case ESR_ELx_FSC_SEA_TTW1:
- case ESR_ELx_FSC_SEA_TTW2:
- case ESR_ELx_FSC_SEA_TTW3:
+ case ESR_ELx_FSC_SEA_TTW(-1) ... ESR_ELx_FSC_SEA_TTW(3):
case ESR_ELx_FSC_SECC:
- case ESR_ELx_FSC_SECC_TTW0:
- case ESR_ELx_FSC_SECC_TTW1:
- case ESR_ELx_FSC_SECC_TTW2:
- case ESR_ELx_FSC_SECC_TTW3:
+ case ESR_ELx_FSC_SECC_TTW(-1) ... ESR_ELx_FSC_SECC_TTW(3):
return true;
default:
return false;
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 21c57b812569..9e8a496fb284 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -238,9 +238,32 @@ static inline u16 kvm_mpidr_index(struct kvm_mpidr_data *data, u64 mpidr)
return index;
}
+struct kvm_sysreg_masks;
+
+enum fgt_group_id {
+ __NO_FGT_GROUP__,
+ HFGxTR_GROUP,
+ HDFGRTR_GROUP,
+ HDFGWTR_GROUP = HDFGRTR_GROUP,
+ HFGITR_GROUP,
+ HAFGRTR_GROUP,
+
+ /* Must be last */
+ __NR_FGT_GROUP_IDS__
+};
+
struct kvm_arch {
struct kvm_s2_mmu mmu;
+ /*
+ * Fine-Grained UNDEF, mimicking the FGT layout defined by the
+ * architecture. We track them globally, as we present the
+ * same feature-set to all vcpus.
+ *
+ * Index 0 is currently spare.
+ */
+ u64 fgu[__NR_FGT_GROUP_IDS__];
+
/* Interrupt controller */
struct vgic_dist vgic;
@@ -274,6 +297,8 @@ struct kvm_arch {
#define KVM_ARCH_FLAG_TIMER_PPIS_IMMUTABLE 6
/* Initial ID reg values loaded */
#define KVM_ARCH_FLAG_ID_REGS_INITIALIZED 7
+ /* Fine-Grained UNDEF initialised */
+#define KVM_ARCH_FLAG_FGU_INITIALIZED 8
unsigned long flags;
/* VM-wide vCPU feature set */
@@ -294,6 +319,9 @@ struct kvm_arch {
/* PMCR_EL0.N value for the guest */
u8 pmcr_n;
+ /* Iterator for idreg debugfs */
+ u8 idreg_debugfs_iter;
+
/* Hypercall features firmware registers' descriptor */
struct kvm_smccc_features smccc_feat;
struct maple_tree smccc_filter;
@@ -312,6 +340,9 @@ struct kvm_arch {
#define KVM_ARM_ID_REG_NUM (IDREG_IDX(sys_reg(3, 0, 0, 7, 7)) + 1)
u64 id_regs[KVM_ARM_ID_REG_NUM];
+ /* Masks for VNCR-baked sysregs */
+ struct kvm_sysreg_masks *sysreg_masks;
+
/*
* For an untrusted host VM, 'pkvm.handle' is used to lookup
* the associated pKVM instance in the hypervisor.
@@ -474,6 +505,13 @@ enum vcpu_sysreg {
NR_SYS_REGS /* Nothing after this line! */
};
+struct kvm_sysreg_masks {
+ struct {
+ u64 res0;
+ u64 res1;
+ } mask[NR_SYS_REGS - __VNCR_START__];
+};
+
struct kvm_cpu_context {
struct user_pt_regs regs; /* sp = sp_el0 */
@@ -543,12 +581,14 @@ struct kvm_vcpu_arch {
enum fp_type fp_type;
unsigned int sve_max_vl;
u64 svcr;
+ u64 fpmr;
/* Stage 2 paging state used by the hardware on next switch */
struct kvm_s2_mmu *hw_mmu;
/* Values of trap registers for the guest. */
u64 hcr_el2;
+ u64 hcrx_el2;
u64 mdcr_el2;
u64 cptr_el2;
@@ -868,7 +908,15 @@ static inline u64 *__ctxt_sys_reg(const struct kvm_cpu_context *ctxt, int r)
#define ctxt_sys_reg(c,r) (*__ctxt_sys_reg(c,r))
-#define __vcpu_sys_reg(v,r) (ctxt_sys_reg(&(v)->arch.ctxt, (r)))
+u64 kvm_vcpu_sanitise_vncr_reg(const struct kvm_vcpu *, enum vcpu_sysreg);
+#define __vcpu_sys_reg(v,r) \
+ (*({ \
+ const struct kvm_cpu_context *ctxt = &(v)->arch.ctxt; \
+ u64 *__r = __ctxt_sys_reg(ctxt, (r)); \
+ if (vcpu_has_nv((v)) && (r) >= __VNCR_START__) \
+ *__r = kvm_vcpu_sanitise_vncr_reg((v), (r)); \
+ __r; \
+ }))
u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg);
void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg);
@@ -1055,14 +1103,20 @@ int kvm_handle_cp15_64(struct kvm_vcpu *vcpu);
int kvm_handle_sys_reg(struct kvm_vcpu *vcpu);
int kvm_handle_cp10_id(struct kvm_vcpu *vcpu);
+void kvm_sys_regs_create_debugfs(struct kvm *kvm);
void kvm_reset_sys_regs(struct kvm_vcpu *vcpu);
int __init kvm_sys_reg_table_init(void);
+struct sys_reg_desc;
+int __init populate_sysreg_config(const struct sys_reg_desc *sr,
+ unsigned int idx);
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 *);
+
/* MMIO helpers */
void kvm_mmio_write_buf(void *buf, unsigned int len, unsigned long data);
unsigned long kvm_mmio_read_buf(const void *buf, unsigned int len);
@@ -1233,4 +1287,48 @@ 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);
+#define __expand_field_sign_unsigned(id, fld, val) \
+ ((u64)SYS_FIELD_VALUE(id, fld, val))
+
+#define __expand_field_sign_signed(id, fld, val) \
+ ({ \
+ u64 __val = SYS_FIELD_VALUE(id, fld, val); \
+ sign_extend64(__val, id##_##fld##_WIDTH - 1); \
+ })
+
+#define expand_field_sign(id, fld, val) \
+ (id##_##fld##_SIGNED ? \
+ __expand_field_sign_signed(id, fld, val) : \
+ __expand_field_sign_unsigned(id, fld, val))
+
+#define get_idreg_field_unsigned(kvm, id, fld) \
+ ({ \
+ u64 __val = IDREG((kvm), SYS_##id); \
+ FIELD_GET(id##_##fld##_MASK, __val); \
+ })
+
+#define get_idreg_field_signed(kvm, id, fld) \
+ ({ \
+ u64 __val = get_idreg_field_unsigned(kvm, id, fld); \
+ sign_extend64(__val, id##_##fld##_WIDTH - 1); \
+ })
+
+#define get_idreg_field_enum(kvm, id, fld) \
+ get_idreg_field_unsigned(kvm, id, fld)
+
+#define get_idreg_field(kvm, id, fld) \
+ (id##_##fld##_SIGNED ? \
+ get_idreg_field_signed(kvm, id, fld) : \
+ get_idreg_field_unsigned(kvm, id, fld))
+
+#define kvm_has_feat(kvm, id, fld, limit) \
+ (get_idreg_field((kvm), id, fld) >= expand_field_sign(id, fld, limit))
+
+#define kvm_has_feat_enum(kvm, id, fld, val) \
+ (get_idreg_field_unsigned((kvm), id, fld) == __expand_field_sign_unsigned(id, fld, val))
+
+#define kvm_has_feat_range(kvm, id, fld, min, max) \
+ (get_idreg_field((kvm), id, fld) >= expand_field_sign(id, fld, min) && \
+ get_idreg_field((kvm), id, fld) <= expand_field_sign(id, fld, max))
+
#endif /* __ARM64_KVM_HOST_H__ */
diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
index 145ce73fc16c..3e2a1ac0c9bb 100644
--- a/arch/arm64/include/asm/kvm_hyp.h
+++ b/arch/arm64/include/asm/kvm_hyp.h
@@ -70,7 +70,7 @@ DECLARE_PER_CPU(struct kvm_nvhe_init_params, kvm_init_params);
/*
* Without an __arch_swab32(), we fall back to ___constant_swab32(), but the
* static inline can allow the compiler to out-of-line this. KVM always wants
- * the macro version as its always inlined.
+ * the macro version as it's always inlined.
*/
#define __kvm_swab32(x) ___constant_swab32(x)
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index e3e793d0ec30..d5e48d870461 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -54,27 +54,6 @@
#include <asm/alternative.h>
/*
- * Convert a kernel VA into a HYP VA.
- * reg: VA to be converted.
- *
- * The actual code generation takes place in kvm_update_va_mask, and
- * the instructions below are only there to reserve the space and
- * perform the register allocation (kvm_update_va_mask uses the
- * specific registers encoded in the instructions).
- */
-.macro kern_hyp_va reg
-#ifndef __KVM_VHE_HYPERVISOR__
-alternative_cb ARM64_ALWAYS_SYSTEM, kvm_update_va_mask
- and \reg, \reg, #1 /* mask with va_mask */
- ror \reg, \reg, #1 /* rotate to the first tag bit */
- add \reg, \reg, #0 /* insert the low 12 bits of the tag */
- add \reg, \reg, #0, lsl 12 /* insert the top 12 bits of the tag */
- ror \reg, \reg, #63 /* rotate back */
-alternative_cb_end
-#endif
-.endm
-
-/*
* Convert a hypervisor VA to a PA
* reg: hypervisor address to be converted in place
* tmp: temporary register
@@ -127,14 +106,29 @@ void kvm_apply_hyp_relocations(void);
#define __hyp_pa(x) (((phys_addr_t)(x)) + hyp_physvirt_offset)
+/*
+ * Convert a kernel VA into a HYP VA.
+ *
+ * Can be called from hyp or non-hyp context.
+ *
+ * The actual code generation takes place in kvm_update_va_mask(), and
+ * the instructions below are only there to reserve the space and
+ * perform the register allocation (kvm_update_va_mask() uses the
+ * specific registers encoded in the instructions).
+ */
static __always_inline unsigned long __kern_hyp_va(unsigned long v)
{
+/*
+ * This #ifndef is an optimisation for when this is called from VHE hyp
+ * context. When called from a VHE non-hyp context, kvm_update_va_mask() will
+ * replace the instructions with `nop`s.
+ */
#ifndef __KVM_VHE_HYPERVISOR__
- asm volatile(ALTERNATIVE_CB("and %0, %0, #1\n"
- "ror %0, %0, #1\n"
- "add %0, %0, #0\n"
- "add %0, %0, #0, lsl 12\n"
- "ror %0, %0, #63\n",
+ asm volatile(ALTERNATIVE_CB("and %0, %0, #1\n" /* mask with va_mask */
+ "ror %0, %0, #1\n" /* rotate to the first tag bit */
+ "add %0, %0, #0\n" /* insert the low 12 bits of the tag */
+ "add %0, %0, #0, lsl 12\n" /* insert the top 12 bits of the tag */
+ "ror %0, %0, #63\n", /* rotate back */
ARM64_ALWAYS_SYSTEM,
kvm_update_va_mask)
: "+r" (v));
diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
index 4882905357f4..c77d795556e1 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -60,7 +60,6 @@ static inline u64 translate_ttbr0_el2_to_ttbr0_el1(u64 ttbr0)
return ttbr0 & ~GENMASK_ULL(63, 48);
}
-extern bool __check_nv_sr_forward(struct kvm_vcpu *vcpu);
int kvm_init_nv_sysregs(struct kvm *kvm);
diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h
index cfdf40f734b1..19278dfe7978 100644
--- a/arch/arm64/include/asm/kvm_pgtable.h
+++ b/arch/arm64/include/asm/kvm_pgtable.h
@@ -197,6 +197,7 @@ enum kvm_pgtable_stage2_flags {
* @KVM_PGTABLE_PROT_W: Write permission.
* @KVM_PGTABLE_PROT_R: Read permission.
* @KVM_PGTABLE_PROT_DEVICE: Device attributes.
+ * @KVM_PGTABLE_PROT_NORMAL_NC: Normal noncacheable attributes.
* @KVM_PGTABLE_PROT_SW0: Software bit 0.
* @KVM_PGTABLE_PROT_SW1: Software bit 1.
* @KVM_PGTABLE_PROT_SW2: Software bit 2.
@@ -208,6 +209,7 @@ enum kvm_pgtable_prot {
KVM_PGTABLE_PROT_R = BIT(2),
KVM_PGTABLE_PROT_DEVICE = BIT(3),
+ KVM_PGTABLE_PROT_NORMAL_NC = BIT(4),
KVM_PGTABLE_PROT_SW0 = BIT(55),
KVM_PGTABLE_PROT_SW1 = BIT(56),
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index d82305ab420f..54fb014eba05 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -30,8 +30,8 @@
* keep a constant PAGE_OFFSET and "fallback" to using the higher end
* of the VMEMMAP where 52-bit support is not available in hardware.
*/
-#define VMEMMAP_SHIFT (PAGE_SHIFT - STRUCT_PAGE_MAX_SHIFT)
-#define VMEMMAP_SIZE ((_PAGE_END(VA_BITS_MIN) - PAGE_OFFSET) >> VMEMMAP_SHIFT)
+#define VMEMMAP_RANGE (_PAGE_END(VA_BITS_MIN) - PAGE_OFFSET)
+#define VMEMMAP_SIZE ((VMEMMAP_RANGE >> PAGE_SHIFT) * sizeof(struct page))
/*
* PAGE_OFFSET - the virtual address of the start of the linear map, at the
@@ -47,14 +47,18 @@
#define MODULES_END (MODULES_VADDR + MODULES_VSIZE)
#define MODULES_VADDR (_PAGE_END(VA_BITS_MIN))
#define MODULES_VSIZE (SZ_2G)
-#define VMEMMAP_START (-(UL(1) << (VA_BITS - VMEMMAP_SHIFT)))
-#define VMEMMAP_END (VMEMMAP_START + VMEMMAP_SIZE)
-#define PCI_IO_END (VMEMMAP_START - SZ_8M)
-#define PCI_IO_START (PCI_IO_END - PCI_IO_SIZE)
-#define FIXADDR_TOP (VMEMMAP_START - SZ_32M)
+#define VMEMMAP_START (VMEMMAP_END - VMEMMAP_SIZE)
+#define VMEMMAP_END (-UL(SZ_1G))
+#define PCI_IO_START (VMEMMAP_END + SZ_8M)
+#define PCI_IO_END (PCI_IO_START + PCI_IO_SIZE)
+#define FIXADDR_TOP (-UL(SZ_8M))
#if VA_BITS > 48
+#ifdef CONFIG_ARM64_16K_PAGES
+#define VA_BITS_MIN (47)
+#else
#define VA_BITS_MIN (48)
+#endif
#else
#define VA_BITS_MIN (VA_BITS)
#endif
@@ -173,6 +177,7 @@
* Memory types for Stage-2 translation
*/
#define MT_S2_NORMAL 0xf
+#define MT_S2_NORMAL_NC 0x5
#define MT_S2_DEVICE_nGnRE 0x1
/*
@@ -180,6 +185,7 @@
* Stage-2 enforces Normal-WB and Device-nGnRE
*/
#define MT_S2_FWB_NORMAL 6
+#define MT_S2_FWB_NORMAL_NC 5
#define MT_S2_FWB_DEVICE_nGnRE 1
#ifdef CONFIG_ARM64_4K_PAGES
@@ -209,9 +215,20 @@
#include <asm/boot.h>
#include <asm/bug.h>
#include <asm/sections.h>
+#include <asm/sysreg.h>
+
+static inline u64 __pure read_tcr(void)
+{
+ u64 tcr;
+
+ // read_sysreg() uses asm volatile, so avoid it here
+ asm("mrs %0, tcr_el1" : "=r"(tcr));
+ return tcr;
+}
#if VA_BITS > 48
-extern u64 vabits_actual;
+// For reasons of #include hell, we can't use TCR_T1SZ_OFFSET/TCR_T1SZ_MASK here
+#define vabits_actual (64 - ((read_tcr() >> 16) & 63))
#else
#define vabits_actual ((u64)VA_BITS)
#endif
diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
index 2fcf51231d6e..65977c7783c5 100644
--- a/arch/arm64/include/asm/mmu.h
+++ b/arch/arm64/include/asm/mmu.h
@@ -71,10 +71,46 @@ extern void create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys,
pgprot_t prot, bool page_mappings_only);
extern void *fixmap_remap_fdt(phys_addr_t dt_phys, int *size, pgprot_t prot);
extern void mark_linear_text_alias_ro(void);
-extern bool kaslr_requires_kpti(void);
+
+/*
+ * This check is triggered during the early boot before the cpufeature
+ * is initialised. Checking the status on the local CPU allows the boot
+ * CPU to detect the need for non-global mappings and thus avoiding a
+ * pagetable re-write after all the CPUs are booted. This check will be
+ * anyway run on individual CPUs, allowing us to get the consistent
+ * state once the SMP CPUs are up and thus make the switch to non-global
+ * mappings if required.
+ */
+static inline bool kaslr_requires_kpti(void)
+{
+ /*
+ * E0PD does a similar job to KPTI so can be used instead
+ * where available.
+ */
+ if (IS_ENABLED(CONFIG_ARM64_E0PD)) {
+ u64 mmfr2 = read_sysreg_s(SYS_ID_AA64MMFR2_EL1);
+ if (cpuid_feature_extract_unsigned_field(mmfr2,
+ ID_AA64MMFR2_EL1_E0PD_SHIFT))
+ return false;
+ }
+
+ /*
+ * Systems affected by Cavium erratum 24756 are incompatible
+ * with KPTI.
+ */
+ if (IS_ENABLED(CONFIG_CAVIUM_ERRATUM_27456)) {
+ extern const struct midr_range cavium_erratum_27456_cpus[];
+
+ if (is_midr_in_range_list(read_cpuid_id(),
+ cavium_erratum_27456_cpus))
+ return false;
+ }
+
+ return true;
+}
#define INIT_MM_CONTEXT(name) \
- .pgd = init_pg_dir,
+ .pgd = swapper_pg_dir,
#endif /* !__ASSEMBLY__ */
#endif
diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h
index 9ce4200508b1..c768d16b81a4 100644
--- a/arch/arm64/include/asm/mmu_context.h
+++ b/arch/arm64/include/asm/mmu_context.h
@@ -61,11 +61,9 @@ static inline void cpu_switch_mm(pgd_t *pgd, struct mm_struct *mm)
}
/*
- * TCR.T0SZ value to use when the ID map is active. Usually equals
- * TCR_T0SZ(VA_BITS), unless system RAM is positioned very high in
- * physical memory, in which case it will be smaller.
+ * TCR.T0SZ value to use when the ID map is active.
*/
-extern int idmap_t0sz;
+#define idmap_t0sz TCR_T0SZ(IDMAP_VA_BITS)
/*
* Ensure TCR.T0SZ is set to the provided value.
@@ -110,18 +108,13 @@ static inline void cpu_uninstall_idmap(void)
cpu_switch_mm(mm->pgd, mm);
}
-static inline void __cpu_install_idmap(pgd_t *idmap)
+static inline void cpu_install_idmap(void)
{
cpu_set_reserved_ttbr0();
local_flush_tlb_all();
cpu_set_idmap_tcr_t0sz();
- cpu_switch_mm(lm_alias(idmap), &init_mm);
-}
-
-static inline void cpu_install_idmap(void)
-{
- __cpu_install_idmap(idmap_pg_dir);
+ cpu_switch_mm(lm_alias(idmap_pg_dir), &init_mm);
}
/*
@@ -148,51 +141,21 @@ static inline void cpu_install_ttbr0(phys_addr_t ttbr0, unsigned long t0sz)
isb();
}
-/*
- * Atomically replaces the active TTBR1_EL1 PGD with a new VA-compatible PGD,
- * avoiding the possibility of conflicting TLB entries being allocated.
- */
-static inline void __cpu_replace_ttbr1(pgd_t *pgdp, pgd_t *idmap, bool cnp)
-{
- typedef void (ttbr_replace_func)(phys_addr_t);
- extern ttbr_replace_func idmap_cpu_replace_ttbr1;
- ttbr_replace_func *replace_phys;
- unsigned long daif;
-
- /* phys_to_ttbr() zeros lower 2 bits of ttbr with 52-bit PA */
- phys_addr_t ttbr1 = phys_to_ttbr(virt_to_phys(pgdp));
-
- if (cnp)
- ttbr1 |= TTBR_CNP_BIT;
-
- replace_phys = (void *)__pa_symbol(idmap_cpu_replace_ttbr1);
-
- __cpu_install_idmap(idmap);
-
- /*
- * We really don't want to take *any* exceptions while TTBR1 is
- * in the process of being replaced so mask everything.
- */
- daif = local_daif_save();
- replace_phys(ttbr1);
- local_daif_restore(daif);
-
- cpu_uninstall_idmap();
-}
+void __cpu_replace_ttbr1(pgd_t *pgdp, bool cnp);
static inline void cpu_enable_swapper_cnp(void)
{
- __cpu_replace_ttbr1(lm_alias(swapper_pg_dir), idmap_pg_dir, true);
+ __cpu_replace_ttbr1(lm_alias(swapper_pg_dir), true);
}
-static inline void cpu_replace_ttbr1(pgd_t *pgdp, pgd_t *idmap)
+static inline void cpu_replace_ttbr1(pgd_t *pgdp)
{
/*
* Only for early TTBR1 replacement before cpucaps are finalized and
* before we've decided whether to use CNP.
*/
WARN_ON(system_capabilities_finalized());
- __cpu_replace_ttbr1(pgdp, idmap, false);
+ __cpu_replace_ttbr1(pgdp, false);
}
/*
diff --git a/arch/arm64/include/asm/mshyperv.h b/arch/arm64/include/asm/mshyperv.h
index 20070a847304..a975e1a689dd 100644
--- a/arch/arm64/include/asm/mshyperv.h
+++ b/arch/arm64/include/asm/mshyperv.h
@@ -31,12 +31,12 @@ void hv_set_vpreg(u32 reg, u64 value);
u64 hv_get_vpreg(u32 reg);
void hv_get_vpreg_128(u32 reg, struct hv_get_vp_registers_output *result);
-static inline void hv_set_register(unsigned int reg, u64 value)
+static inline void hv_set_msr(unsigned int reg, u64 value)
{
hv_set_vpreg(reg, value);
}
-static inline u64 hv_get_register(unsigned int reg)
+static inline u64 hv_get_msr(unsigned int reg)
{
return hv_get_vpreg(reg);
}
diff --git a/arch/arm64/include/asm/page-def.h b/arch/arm64/include/asm/page-def.h
index 2403f7b4cdbf..792e9fe881dc 100644
--- a/arch/arm64/include/asm/page-def.h
+++ b/arch/arm64/include/asm/page-def.h
@@ -11,7 +11,7 @@
#include <linux/const.h>
/* PAGE_SHIFT determines the page size */
-#define PAGE_SHIFT CONFIG_ARM64_PAGE_SHIFT
+#define PAGE_SHIFT CONFIG_PAGE_SHIFT
#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
diff --git a/arch/arm64/include/asm/patching.h b/arch/arm64/include/asm/patching.h
index 68908b82b168..587bdb91ab7a 100644
--- a/arch/arm64/include/asm/patching.h
+++ b/arch/arm64/include/asm/patching.h
@@ -8,6 +8,8 @@ int aarch64_insn_read(void *addr, u32 *insnp);
int aarch64_insn_write(void *addr, u32 insn);
int aarch64_insn_write_literal_u64(void *addr, u64 val);
+void *aarch64_insn_set(void *dst, u32 insn, size_t len);
+void *aarch64_insn_copy(void *dst, void *src, size_t len);
int aarch64_insn_patch_text_nosync(void *addr, u32 insn);
int aarch64_insn_patch_text(void *addrs[], u32 insns[], int cnt);
diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
index 237224484d0f..8ff5f2a2579e 100644
--- a/arch/arm64/include/asm/pgalloc.h
+++ b/arch/arm64/include/asm/pgalloc.h
@@ -14,6 +14,7 @@
#include <asm/tlbflush.h>
#define __HAVE_ARCH_PGD_FREE
+#define __HAVE_ARCH_PUD_FREE
#include <asm-generic/pgalloc.h>
#define PGD_SIZE (PTRS_PER_PGD * sizeof(pgd_t))
@@ -43,7 +44,8 @@ static inline void __pud_populate(pud_t *pudp, phys_addr_t pmdp, pudval_t prot)
static inline void __p4d_populate(p4d_t *p4dp, phys_addr_t pudp, p4dval_t prot)
{
- set_p4d(p4dp, __p4d(__phys_to_p4d_val(pudp) | prot));
+ if (pgtable_l4_enabled())
+ set_p4d(p4dp, __p4d(__phys_to_p4d_val(pudp) | prot));
}
static inline void p4d_populate(struct mm_struct *mm, p4d_t *p4dp, pud_t *pudp)
@@ -53,6 +55,13 @@ static inline void p4d_populate(struct mm_struct *mm, p4d_t *p4dp, pud_t *pudp)
p4dval |= (mm == &init_mm) ? P4D_TABLE_UXN : P4D_TABLE_PXN;
__p4d_populate(p4dp, __pa(pudp), p4dval);
}
+
+static inline void pud_free(struct mm_struct *mm, pud_t *pud)
+{
+ if (!pgtable_l4_enabled())
+ return;
+ __pud_free(mm, pud);
+}
#else
static inline void __p4d_populate(p4d_t *p4dp, phys_addr_t pudp, p4dval_t prot)
{
@@ -60,6 +69,47 @@ static inline void __p4d_populate(p4d_t *p4dp, phys_addr_t pudp, p4dval_t prot)
}
#endif /* CONFIG_PGTABLE_LEVELS > 3 */
+#if CONFIG_PGTABLE_LEVELS > 4
+
+static inline void __pgd_populate(pgd_t *pgdp, phys_addr_t p4dp, pgdval_t prot)
+{
+ if (pgtable_l5_enabled())
+ set_pgd(pgdp, __pgd(__phys_to_pgd_val(p4dp) | prot));
+}
+
+static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgdp, p4d_t *p4dp)
+{
+ pgdval_t pgdval = PGD_TYPE_TABLE;
+
+ pgdval |= (mm == &init_mm) ? PGD_TABLE_UXN : PGD_TABLE_PXN;
+ __pgd_populate(pgdp, __pa(p4dp), pgdval);
+}
+
+static inline p4d_t *p4d_alloc_one(struct mm_struct *mm, unsigned long addr)
+{
+ gfp_t gfp = GFP_PGTABLE_USER;
+
+ if (mm == &init_mm)
+ gfp = GFP_PGTABLE_KERNEL;
+ return (p4d_t *)get_zeroed_page(gfp);
+}
+
+static inline void p4d_free(struct mm_struct *mm, p4d_t *p4d)
+{
+ if (!pgtable_l5_enabled())
+ return;
+ BUG_ON((unsigned long)p4d & (PAGE_SIZE-1));
+ free_page((unsigned long)p4d);
+}
+
+#define __p4d_free_tlb(tlb, p4d, addr) p4d_free((tlb)->mm, p4d)
+#else
+static inline void __pgd_populate(pgd_t *pgdp, phys_addr_t p4dp, pgdval_t prot)
+{
+ BUILD_BUG();
+}
+#endif /* CONFIG_PGTABLE_LEVELS > 4 */
+
extern pgd_t *pgd_alloc(struct mm_struct *mm);
extern void pgd_free(struct mm_struct *mm, pgd_t *pgdp);
diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index e4944d517c99..ef207a0d4f0d 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -26,10 +26,10 @@
#define ARM64_HW_PGTABLE_LEVELS(va_bits) (((va_bits) - 4) / (PAGE_SHIFT - 3))
/*
- * Size mapped by an entry at level n ( 0 <= n <= 3)
+ * Size mapped by an entry at level n ( -1 <= n <= 3)
* We map (PAGE_SHIFT - 3) at all translation levels and PAGE_SHIFT bits
* in the final page. The maximum number of translation levels supported by
- * the architecture is 4. Hence, starting at level n, we have further
+ * the architecture is 5. Hence, starting at level n, we have further
* ((4 - n) - 1) levels of translation excluding the offset within the page.
* So, the total number of bits mapped by an entry at level n is :
*
@@ -62,9 +62,16 @@
#define PTRS_PER_PUD (1 << (PAGE_SHIFT - 3))
#endif
+#if CONFIG_PGTABLE_LEVELS > 4
+#define P4D_SHIFT ARM64_HW_PGTABLE_LEVEL_SHIFT(0)
+#define P4D_SIZE (_AC(1, UL) << P4D_SHIFT)
+#define P4D_MASK (~(P4D_SIZE-1))
+#define PTRS_PER_P4D (1 << (PAGE_SHIFT - 3))
+#endif
+
/*
* PGDIR_SHIFT determines the size a top-level page table entry can map
- * (depending on the configuration, this level can be 0, 1 or 2).
+ * (depending on the configuration, this level can be -1, 0, 1 or 2).
*/
#define PGDIR_SHIFT ARM64_HW_PGTABLE_LEVEL_SHIFT(4 - CONFIG_PGTABLE_LEVELS)
#define PGDIR_SIZE (_AC(1, UL) << PGDIR_SHIFT)
@@ -87,6 +94,15 @@
/*
* Hardware page table definitions.
*
+ * Level -1 descriptor (PGD).
+ */
+#define PGD_TYPE_TABLE (_AT(pgdval_t, 3) << 0)
+#define PGD_TABLE_BIT (_AT(pgdval_t, 1) << 1)
+#define PGD_TYPE_MASK (_AT(pgdval_t, 3) << 0)
+#define PGD_TABLE_PXN (_AT(pgdval_t, 1) << 59)
+#define PGD_TABLE_UXN (_AT(pgdval_t, 1) << 60)
+
+/*
* Level 0 descriptor (P4D).
*/
#define P4D_TYPE_TABLE (_AT(p4dval_t, 3) << 0)
@@ -155,13 +171,17 @@
#define PTE_PXN (_AT(pteval_t, 1) << 53) /* Privileged XN */
#define PTE_UXN (_AT(pteval_t, 1) << 54) /* User XN */
-#define PTE_ADDR_LOW (((_AT(pteval_t, 1) << (48 - PAGE_SHIFT)) - 1) << PAGE_SHIFT)
+#define PTE_ADDR_LOW (((_AT(pteval_t, 1) << (50 - PAGE_SHIFT)) - 1) << PAGE_SHIFT)
#ifdef CONFIG_ARM64_PA_BITS_52
+#ifdef CONFIG_ARM64_64K_PAGES
#define PTE_ADDR_HIGH (_AT(pteval_t, 0xf) << 12)
-#define PTE_ADDR_MASK (PTE_ADDR_LOW | PTE_ADDR_HIGH)
#define PTE_ADDR_HIGH_SHIFT 36
+#define PHYS_TO_PTE_ADDR_MASK (PTE_ADDR_LOW | PTE_ADDR_HIGH)
#else
-#define PTE_ADDR_MASK PTE_ADDR_LOW
+#define PTE_ADDR_HIGH (_AT(pteval_t, 0x3) << 8)
+#define PTE_ADDR_HIGH_SHIFT 42
+#define PHYS_TO_PTE_ADDR_MASK GENMASK_ULL(49, 8)
+#endif
#endif
/*
@@ -284,6 +304,7 @@
#define TCR_E0PD1 (UL(1) << 56)
#define TCR_TCMA0 (UL(1) << 57)
#define TCR_TCMA1 (UL(1) << 58)
+#define TCR_DS (UL(1) << 59)
/*
* TTBR.
diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
index 483dbfa39c4c..dd9ee67d1d87 100644
--- a/arch/arm64/include/asm/pgtable-prot.h
+++ b/arch/arm64/include/asm/pgtable-prot.h
@@ -30,8 +30,8 @@
#define _PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED)
#define _PROT_SECT_DEFAULT (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S)
-#define PROT_DEFAULT (_PROT_DEFAULT | PTE_MAYBE_NG)
-#define PROT_SECT_DEFAULT (_PROT_SECT_DEFAULT | PMD_MAYBE_NG)
+#define PROT_DEFAULT (PTE_TYPE_PAGE | PTE_MAYBE_NG | PTE_MAYBE_SHARED | PTE_AF)
+#define PROT_SECT_DEFAULT (PMD_TYPE_SECT | PMD_MAYBE_NG | PMD_MAYBE_SHARED | PMD_SECT_AF)
#define PROT_DEVICE_nGnRnE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRnE))
#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRE))
@@ -57,10 +57,6 @@
#define _PAGE_READONLY_EXEC (_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN)
#define _PAGE_EXECONLY (_PAGE_DEFAULT | PTE_RDONLY | PTE_NG | PTE_PXN)
-#ifdef __ASSEMBLY__
-#define PTE_MAYBE_NG 0
-#endif
-
#ifndef __ASSEMBLY__
#include <asm/cpufeature.h>
@@ -71,7 +67,19 @@ extern bool arm64_use_ng_mappings;
#define PTE_MAYBE_NG (arm64_use_ng_mappings ? PTE_NG : 0)
#define PMD_MAYBE_NG (arm64_use_ng_mappings ? PMD_SECT_NG : 0)
+#ifndef CONFIG_ARM64_LPA2
#define lpa2_is_enabled() false
+#define PTE_MAYBE_SHARED PTE_SHARED
+#define PMD_MAYBE_SHARED PMD_SECT_S
+#else
+static inline bool __pure lpa2_is_enabled(void)
+{
+ return read_tcr() & TCR_DS;
+}
+
+#define PTE_MAYBE_SHARED (lpa2_is_enabled() ? 0 : PTE_SHARED)
+#define PMD_MAYBE_SHARED (lpa2_is_enabled() ? 0 : PMD_SECT_S)
+#endif
/*
* If we have userspace only BTI we don't want to mark kernel pages
diff --git a/arch/arm64/include/asm/pgtable-types.h b/arch/arm64/include/asm/pgtable-types.h
index b8f158ae2527..6d6d4065b0cb 100644
--- a/arch/arm64/include/asm/pgtable-types.h
+++ b/arch/arm64/include/asm/pgtable-types.h
@@ -36,6 +36,12 @@ typedef struct { pudval_t pud; } pud_t;
#define __pud(x) ((pud_t) { (x) } )
#endif
+#if CONFIG_PGTABLE_LEVELS > 4
+typedef struct { p4dval_t p4d; } p4d_t;
+#define p4d_val(x) ((x).p4d)
+#define __p4d(x) ((p4d_t) { (x) } )
+#endif
+
typedef struct { pgdval_t pgd; } pgd_t;
#define pgd_val(x) ((x).pgd)
#define __pgd(x) ((pgd_t) { (x) } )
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 79ce70fbb751..afdd56d26ad7 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -18,11 +18,15 @@
* VMALLOC range.
*
* VMALLOC_START: beginning of the kernel vmalloc space
- * VMALLOC_END: extends to the available space below vmemmap, PCI I/O space
- * and fixed mappings
+ * VMALLOC_END: extends to the available space below vmemmap
*/
#define VMALLOC_START (MODULES_END)
-#define VMALLOC_END (VMEMMAP_START - SZ_256M)
+#if VA_BITS == VA_BITS_MIN
+#define VMALLOC_END (VMEMMAP_START - SZ_8M)
+#else
+#define VMEMMAP_UNUSED_NPAGES ((_PAGE_OFFSET(vabits_actual) - PAGE_OFFSET) >> PAGE_SHIFT)
+#define VMALLOC_END (VMEMMAP_START + VMEMMAP_UNUSED_NPAGES * sizeof(struct page) - SZ_8M)
+#endif
#define vmemmap ((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT))
@@ -76,15 +80,16 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
#ifdef CONFIG_ARM64_PA_BITS_52
static inline phys_addr_t __pte_to_phys(pte_t pte)
{
+ pte_val(pte) &= ~PTE_MAYBE_SHARED;
return (pte_val(pte) & PTE_ADDR_LOW) |
((pte_val(pte) & PTE_ADDR_HIGH) << PTE_ADDR_HIGH_SHIFT);
}
static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
{
- return (phys | (phys >> PTE_ADDR_HIGH_SHIFT)) & PTE_ADDR_MASK;
+ return (phys | (phys >> PTE_ADDR_HIGH_SHIFT)) & PHYS_TO_PTE_ADDR_MASK;
}
#else
-#define __pte_to_phys(pte) (pte_val(pte) & PTE_ADDR_MASK)
+#define __pte_to_phys(pte) (pte_val(pte) & PTE_ADDR_LOW)
#define __phys_to_pte_val(phys) (phys)
#endif
@@ -93,7 +98,8 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
__pte(__phys_to_pte_val((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot))
#define pte_none(pte) (!pte_val(pte))
-#define pte_clear(mm,addr,ptep) set_pte(ptep, __pte(0))
+#define __pte_clear(mm, addr, ptep) \
+ __set_pte(ptep, __pte(0))
#define pte_page(pte) (pfn_to_page(pte_pfn(pte)))
/*
@@ -133,11 +139,15 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
#define pte_valid_not_user(pte) \
((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_UXN)) == (PTE_VALID | PTE_UXN))
/*
+ * Returns true if the pte is valid and has the contiguous bit set.
+ */
+#define pte_valid_cont(pte) (pte_valid(pte) && pte_cont(pte))
+/*
* Could the pte be present in the TLB? We must check mm_tlb_flush_pending
* so that we don't erroneously return false for pages that have been
* remapped as PROT_NONE but are yet to be flushed from the TLB.
* Note that we can't make any assumptions based on the state of the access
- * flag, since ptep_clear_flush_young() elides a DSB when invalidating the
+ * flag, since __ptep_clear_flush_young() elides a DSB when invalidating the
* TLB.
*/
#define pte_accessible(mm, pte) \
@@ -261,7 +271,7 @@ 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)
+static inline void __set_pte(pte_t *ptep, pte_t pte)
{
WRITE_ONCE(*ptep, pte);
@@ -275,6 +285,11 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
}
}
+static inline pte_t __ptep_get(pte_t *ptep)
+{
+ return READ_ONCE(*ptep);
+}
+
extern void __sync_icache_dcache(pte_t pteval);
bool pgattr_change_is_safe(u64 old, u64 new);
@@ -302,7 +317,7 @@ static inline void __check_safe_pte_update(struct mm_struct *mm, pte_t *ptep,
if (!IS_ENABLED(CONFIG_DEBUG_VM))
return;
- old_pte = READ_ONCE(*ptep);
+ old_pte = __ptep_get(ptep);
if (!pte_valid(old_pte) || !pte_valid(pte))
return;
@@ -311,7 +326,7 @@ static inline void __check_safe_pte_update(struct mm_struct *mm, pte_t *ptep,
/*
* Check for potential race with hardware updates of the pte
- * (ptep_set_access_flags safely changes valid ptes without going
+ * (__ptep_set_access_flags safely changes valid ptes without going
* through an invalid entry).
*/
VM_WARN_ONCE(!pte_young(pte),
@@ -341,23 +356,38 @@ static inline void __sync_cache_and_tags(pte_t pte, unsigned int nr_pages)
mte_sync_tags(pte, nr_pages);
}
-static inline void set_ptes(struct mm_struct *mm,
- unsigned long __always_unused addr,
- pte_t *ptep, pte_t pte, unsigned int nr)
+/*
+ * Select all bits except the pfn
+ */
+static inline pgprot_t pte_pgprot(pte_t pte)
+{
+ unsigned long pfn = pte_pfn(pte);
+
+ return __pgprot(pte_val(pfn_pte(pfn, __pgprot(0))) ^ pte_val(pte));
+}
+
+#define pte_advance_pfn pte_advance_pfn
+static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
+{
+ return pfn_pte(pte_pfn(pte) + nr, pte_pgprot(pte));
+}
+
+static inline void __set_ptes(struct mm_struct *mm,
+ unsigned long __always_unused addr,
+ pte_t *ptep, pte_t pte, unsigned int nr)
{
page_table_check_ptes_set(mm, ptep, pte, nr);
__sync_cache_and_tags(pte, nr);
for (;;) {
__check_safe_pte_update(mm, ptep, pte);
- set_pte(ptep, pte);
+ __set_pte(ptep, pte);
if (--nr == 0)
break;
ptep++;
- pte_val(pte) += PAGE_SIZE;
+ pte = pte_advance_pfn(pte, 1);
}
}
-#define set_ptes set_ptes
/*
* Huge pte definitions.
@@ -433,16 +463,6 @@ static inline pte_t pte_swp_clear_exclusive(pte_t pte)
return clear_pte_bit(pte, __pgprot(PTE_SWP_EXCLUSIVE));
}
-/*
- * Select all bits except the pfn
- */
-static inline pgprot_t pte_pgprot(pte_t pte)
-{
- unsigned long pfn = pte_pfn(pte);
-
- return __pgprot(pte_val(pfn_pte(pfn, __pgprot(0))) ^ pte_val(pte));
-}
-
#ifdef CONFIG_NUMA_BALANCING
/*
* See the comment in include/linux/pgtable.h
@@ -534,7 +554,7 @@ static inline void __set_pte_at(struct mm_struct *mm,
{
__sync_cache_and_tags(pte, nr);
__check_safe_pte_update(mm, ptep, pte);
- set_pte(ptep, pte);
+ __set_pte(ptep, pte);
}
static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
@@ -616,12 +636,12 @@ static inline bool pud_table(pud_t pud) { return true; }
PUD_TYPE_TABLE)
#endif
-extern pgd_t init_pg_dir[PTRS_PER_PGD];
+extern pgd_t init_pg_dir[];
extern pgd_t init_pg_end[];
-extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
-extern pgd_t idmap_pg_dir[PTRS_PER_PGD];
-extern pgd_t tramp_pg_dir[PTRS_PER_PGD];
-extern pgd_t reserved_pg_dir[PTRS_PER_PGD];
+extern pgd_t swapper_pg_dir[];
+extern pgd_t idmap_pg_dir[];
+extern pgd_t tramp_pg_dir[];
+extern pgd_t reserved_pg_dir[];
extern void set_swapper_pgd(pgd_t *pgdp, pgd_t pgd);
@@ -694,14 +714,14 @@ static inline unsigned long pmd_page_vaddr(pmd_t pmd)
#define pud_user(pud) pte_user(pud_pte(pud))
#define pud_user_exec(pud) pte_user_exec(pud_pte(pud))
+static inline bool pgtable_l4_enabled(void);
+
static inline void set_pud(pud_t *pudp, pud_t pud)
{
-#ifdef __PAGETABLE_PUD_FOLDED
- if (in_swapper_pgdir(pudp)) {
+ if (!pgtable_l4_enabled() && in_swapper_pgdir(pudp)) {
set_swapper_pgd((pgd_t *)pudp, __pgd(pud_val(pud)));
return;
}
-#endif /* __PAGETABLE_PUD_FOLDED */
WRITE_ONCE(*pudp, pud);
@@ -754,12 +774,27 @@ static inline pmd_t *pud_pgtable(pud_t pud)
#if CONFIG_PGTABLE_LEVELS > 3
+static __always_inline bool pgtable_l4_enabled(void)
+{
+ if (CONFIG_PGTABLE_LEVELS > 4 || !IS_ENABLED(CONFIG_ARM64_LPA2))
+ return true;
+ if (!alternative_has_cap_likely(ARM64_ALWAYS_BOOT))
+ return vabits_actual == VA_BITS;
+ return alternative_has_cap_unlikely(ARM64_HAS_VA52);
+}
+
+static inline bool mm_pud_folded(const struct mm_struct *mm)
+{
+ return !pgtable_l4_enabled();
+}
+#define mm_pud_folded mm_pud_folded
+
#define pud_ERROR(e) \
pr_err("%s:%d: bad pud %016llx.\n", __FILE__, __LINE__, pud_val(e))
-#define p4d_none(p4d) (!p4d_val(p4d))
-#define p4d_bad(p4d) (!(p4d_val(p4d) & 2))
-#define p4d_present(p4d) (p4d_val(p4d))
+#define p4d_none(p4d) (pgtable_l4_enabled() && !p4d_val(p4d))
+#define p4d_bad(p4d) (pgtable_l4_enabled() && !(p4d_val(p4d) & 2))
+#define p4d_present(p4d) (!p4d_none(p4d))
static inline void set_p4d(p4d_t *p4dp, p4d_t p4d)
{
@@ -775,7 +810,8 @@ static inline void set_p4d(p4d_t *p4dp, p4d_t p4d)
static inline void p4d_clear(p4d_t *p4dp)
{
- set_p4d(p4dp, __p4d(0));
+ if (pgtable_l4_enabled())
+ set_p4d(p4dp, __p4d(0));
}
static inline phys_addr_t p4d_page_paddr(p4d_t p4d)
@@ -783,27 +819,75 @@ static inline phys_addr_t p4d_page_paddr(p4d_t p4d)
return __p4d_to_phys(p4d);
}
+#define pud_index(addr) (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))
+
+static inline pud_t *p4d_to_folded_pud(p4d_t *p4dp, unsigned long addr)
+{
+ return (pud_t *)PTR_ALIGN_DOWN(p4dp, PAGE_SIZE) + pud_index(addr);
+}
+
static inline pud_t *p4d_pgtable(p4d_t p4d)
{
return (pud_t *)__va(p4d_page_paddr(p4d));
}
-/* Find an entry in the first-level page table. */
-#define pud_offset_phys(dir, addr) (p4d_page_paddr(READ_ONCE(*(dir))) + pud_index(addr) * sizeof(pud_t))
+static inline phys_addr_t pud_offset_phys(p4d_t *p4dp, unsigned long addr)
+{
+ BUG_ON(!pgtable_l4_enabled());
-#define pud_set_fixmap(addr) ((pud_t *)set_fixmap_offset(FIX_PUD, addr))
-#define pud_set_fixmap_offset(p4d, addr) pud_set_fixmap(pud_offset_phys(p4d, addr))
-#define pud_clear_fixmap() clear_fixmap(FIX_PUD)
+ return p4d_page_paddr(READ_ONCE(*p4dp)) + pud_index(addr) * sizeof(pud_t);
+}
-#define p4d_page(p4d) pfn_to_page(__phys_to_pfn(__p4d_to_phys(p4d)))
+static inline
+pud_t *pud_offset_lockless(p4d_t *p4dp, p4d_t p4d, unsigned long addr)
+{
+ if (!pgtable_l4_enabled())
+ return p4d_to_folded_pud(p4dp, addr);
+ return (pud_t *)__va(p4d_page_paddr(p4d)) + pud_index(addr);
+}
+#define pud_offset_lockless pud_offset_lockless
+
+static inline pud_t *pud_offset(p4d_t *p4dp, unsigned long addr)
+{
+ return pud_offset_lockless(p4dp, READ_ONCE(*p4dp), addr);
+}
+#define pud_offset pud_offset
+
+static inline pud_t *pud_set_fixmap(unsigned long addr)
+{
+ if (!pgtable_l4_enabled())
+ return NULL;
+ return (pud_t *)set_fixmap_offset(FIX_PUD, addr);
+}
+
+static inline pud_t *pud_set_fixmap_offset(p4d_t *p4dp, unsigned long addr)
+{
+ if (!pgtable_l4_enabled())
+ return p4d_to_folded_pud(p4dp, addr);
+ return pud_set_fixmap(pud_offset_phys(p4dp, addr));
+}
+
+static inline void pud_clear_fixmap(void)
+{
+ if (pgtable_l4_enabled())
+ clear_fixmap(FIX_PUD);
+}
/* use ONLY for statically allocated translation tables */
-#define pud_offset_kimg(dir,addr) ((pud_t *)__phys_to_kimg(pud_offset_phys((dir), (addr))))
+static inline pud_t *pud_offset_kimg(p4d_t *p4dp, u64 addr)
+{
+ if (!pgtable_l4_enabled())
+ return p4d_to_folded_pud(p4dp, addr);
+ return (pud_t *)__phys_to_kimg(pud_offset_phys(p4dp, addr));
+}
+
+#define p4d_page(p4d) pfn_to_page(__phys_to_pfn(__p4d_to_phys(p4d)))
#else
+static inline bool pgtable_l4_enabled(void) { return false; }
+
#define p4d_page_paddr(p4d) ({ BUILD_BUG(); 0;})
-#define pgd_page_paddr(pgd) ({ BUILD_BUG(); 0;})
/* Match pud_offset folding in <asm/generic/pgtable-nopud.h> */
#define pud_set_fixmap(addr) NULL
@@ -814,6 +898,122 @@ static inline pud_t *p4d_pgtable(p4d_t p4d)
#endif /* CONFIG_PGTABLE_LEVELS > 3 */
+#if CONFIG_PGTABLE_LEVELS > 4
+
+static __always_inline bool pgtable_l5_enabled(void)
+{
+ if (!alternative_has_cap_likely(ARM64_ALWAYS_BOOT))
+ return vabits_actual == VA_BITS;
+ return alternative_has_cap_unlikely(ARM64_HAS_VA52);
+}
+
+static inline bool mm_p4d_folded(const struct mm_struct *mm)
+{
+ return !pgtable_l5_enabled();
+}
+#define mm_p4d_folded mm_p4d_folded
+
+#define p4d_ERROR(e) \
+ pr_err("%s:%d: bad p4d %016llx.\n", __FILE__, __LINE__, p4d_val(e))
+
+#define pgd_none(pgd) (pgtable_l5_enabled() && !pgd_val(pgd))
+#define pgd_bad(pgd) (pgtable_l5_enabled() && !(pgd_val(pgd) & 2))
+#define pgd_present(pgd) (!pgd_none(pgd))
+
+static inline void set_pgd(pgd_t *pgdp, pgd_t pgd)
+{
+ if (in_swapper_pgdir(pgdp)) {
+ set_swapper_pgd(pgdp, __pgd(pgd_val(pgd)));
+ return;
+ }
+
+ WRITE_ONCE(*pgdp, pgd);
+ dsb(ishst);
+ isb();
+}
+
+static inline void pgd_clear(pgd_t *pgdp)
+{
+ if (pgtable_l5_enabled())
+ set_pgd(pgdp, __pgd(0));
+}
+
+static inline phys_addr_t pgd_page_paddr(pgd_t pgd)
+{
+ return __pgd_to_phys(pgd);
+}
+
+#define p4d_index(addr) (((addr) >> P4D_SHIFT) & (PTRS_PER_P4D - 1))
+
+static inline p4d_t *pgd_to_folded_p4d(pgd_t *pgdp, unsigned long addr)
+{
+ return (p4d_t *)PTR_ALIGN_DOWN(pgdp, PAGE_SIZE) + p4d_index(addr);
+}
+
+static inline phys_addr_t p4d_offset_phys(pgd_t *pgdp, unsigned long addr)
+{
+ BUG_ON(!pgtable_l5_enabled());
+
+ return pgd_page_paddr(READ_ONCE(*pgdp)) + p4d_index(addr) * sizeof(p4d_t);
+}
+
+static inline
+p4d_t *p4d_offset_lockless(pgd_t *pgdp, pgd_t pgd, unsigned long addr)
+{
+ if (!pgtable_l5_enabled())
+ return pgd_to_folded_p4d(pgdp, addr);
+ return (p4d_t *)__va(pgd_page_paddr(pgd)) + p4d_index(addr);
+}
+#define p4d_offset_lockless p4d_offset_lockless
+
+static inline p4d_t *p4d_offset(pgd_t *pgdp, unsigned long addr)
+{
+ return p4d_offset_lockless(pgdp, READ_ONCE(*pgdp), addr);
+}
+
+static inline p4d_t *p4d_set_fixmap(unsigned long addr)
+{
+ if (!pgtable_l5_enabled())
+ return NULL;
+ return (p4d_t *)set_fixmap_offset(FIX_P4D, addr);
+}
+
+static inline p4d_t *p4d_set_fixmap_offset(pgd_t *pgdp, unsigned long addr)
+{
+ if (!pgtable_l5_enabled())
+ return pgd_to_folded_p4d(pgdp, addr);
+ return p4d_set_fixmap(p4d_offset_phys(pgdp, addr));
+}
+
+static inline void p4d_clear_fixmap(void)
+{
+ if (pgtable_l5_enabled())
+ clear_fixmap(FIX_P4D);
+}
+
+/* use ONLY for statically allocated translation tables */
+static inline p4d_t *p4d_offset_kimg(pgd_t *pgdp, u64 addr)
+{
+ if (!pgtable_l5_enabled())
+ return pgd_to_folded_p4d(pgdp, addr);
+ return (p4d_t *)__phys_to_kimg(p4d_offset_phys(pgdp, addr));
+}
+
+#define pgd_page(pgd) pfn_to_page(__phys_to_pfn(__pgd_to_phys(pgd)))
+
+#else
+
+static inline bool pgtable_l5_enabled(void) { return false; }
+
+/* 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)
+#define p4d_clear_fixmap()
+
+#define p4d_offset_kimg(dir,addr) ((p4d_t *)dir)
+
+#endif /* CONFIG_PGTABLE_LEVELS > 4 */
+
#define pgd_ERROR(e) \
pr_err("%s:%d: bad pgd %016llx.\n", __FILE__, __LINE__, pgd_val(e))
@@ -848,8 +1048,7 @@ static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
return pte_pmd(pte_modify(pmd_pte(pmd), newprot));
}
-#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
-extern int ptep_set_access_flags(struct vm_area_struct *vma,
+extern int __ptep_set_access_flags(struct vm_area_struct *vma,
unsigned long address, pte_t *ptep,
pte_t entry, int dirty);
@@ -859,7 +1058,8 @@ static inline int pmdp_set_access_flags(struct vm_area_struct *vma,
unsigned long address, pmd_t *pmdp,
pmd_t entry, int dirty)
{
- return ptep_set_access_flags(vma, address, (pte_t *)pmdp, pmd_pte(entry), dirty);
+ return __ptep_set_access_flags(vma, address, (pte_t *)pmdp,
+ pmd_pte(entry), dirty);
}
static inline int pud_devmap(pud_t pud)
@@ -893,12 +1093,13 @@ static inline bool pud_user_accessible_page(pud_t pud)
/*
* Atomic pte/pmd modifications.
*/
-#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
-static inline int __ptep_test_and_clear_young(pte_t *ptep)
+static inline int __ptep_test_and_clear_young(struct vm_area_struct *vma,
+ unsigned long address,
+ pte_t *ptep)
{
pte_t old_pte, pte;
- pte = READ_ONCE(*ptep);
+ pte = __ptep_get(ptep);
do {
old_pte = pte;
pte = pte_mkold(pte);
@@ -909,18 +1110,10 @@ static inline int __ptep_test_and_clear_young(pte_t *ptep)
return pte_young(pte);
}
-static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
- unsigned long address,
- pte_t *ptep)
-{
- return __ptep_test_and_clear_young(ptep);
-}
-
-#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
-static inline int ptep_clear_flush_young(struct vm_area_struct *vma,
+static inline int __ptep_clear_flush_young(struct vm_area_struct *vma,
unsigned long address, pte_t *ptep)
{
- int young = ptep_test_and_clear_young(vma, address, ptep);
+ int young = __ptep_test_and_clear_young(vma, address, ptep);
if (young) {
/*
@@ -943,12 +1136,11 @@ static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma,
unsigned long address,
pmd_t *pmdp)
{
- return ptep_test_and_clear_young(vma, address, (pte_t *)pmdp);
+ return __ptep_test_and_clear_young(vma, address, (pte_t *)pmdp);
}
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
-#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
-static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
+static inline pte_t __ptep_get_and_clear(struct mm_struct *mm,
unsigned long address, pte_t *ptep)
{
pte_t pte = __pte(xchg_relaxed(&pte_val(*ptep), 0));
@@ -958,6 +1150,37 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
return pte;
}
+static inline void __clear_full_ptes(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, unsigned int nr, int full)
+{
+ for (;;) {
+ __ptep_get_and_clear(mm, addr, ptep);
+ if (--nr == 0)
+ break;
+ ptep++;
+ addr += PAGE_SIZE;
+ }
+}
+
+static inline pte_t __get_and_clear_full_ptes(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep,
+ unsigned int nr, int full)
+{
+ pte_t pte, tmp_pte;
+
+ pte = __ptep_get_and_clear(mm, addr, ptep);
+ while (--nr) {
+ ptep++;
+ addr += PAGE_SIZE;
+ tmp_pte = __ptep_get_and_clear(mm, addr, ptep);
+ if (pte_dirty(tmp_pte))
+ pte = pte_mkdirty(pte);
+ if (pte_young(tmp_pte))
+ pte = pte_mkyoung(pte);
+ }
+ return pte;
+}
+
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
#define __HAVE_ARCH_PMDP_HUGE_GET_AND_CLEAR
static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
@@ -971,16 +1194,12 @@ static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
}
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
-/*
- * ptep_set_wrprotect - mark read-only while trasferring potential hardware
- * dirty status (PTE_DBM && !PTE_RDONLY) to the software PTE_DIRTY bit.
- */
-#define __HAVE_ARCH_PTEP_SET_WRPROTECT
-static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long address, pte_t *ptep)
+static inline void ___ptep_set_wrprotect(struct mm_struct *mm,
+ unsigned long address, pte_t *ptep,
+ pte_t pte)
{
- pte_t old_pte, pte;
+ pte_t old_pte;
- pte = READ_ONCE(*ptep);
do {
old_pte = pte;
pte = pte_wrprotect(pte);
@@ -989,12 +1208,31 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres
} while (pte_val(pte) != pte_val(old_pte));
}
+/*
+ * __ptep_set_wrprotect - mark read-only while trasferring potential hardware
+ * dirty status (PTE_DBM && !PTE_RDONLY) to the software PTE_DIRTY bit.
+ */
+static inline void __ptep_set_wrprotect(struct mm_struct *mm,
+ unsigned long address, pte_t *ptep)
+{
+ ___ptep_set_wrprotect(mm, address, ptep, __ptep_get(ptep));
+}
+
+static inline void __wrprotect_ptes(struct mm_struct *mm, unsigned long address,
+ pte_t *ptep, unsigned int nr)
+{
+ unsigned int i;
+
+ for (i = 0; i < nr; i++, address += PAGE_SIZE, ptep++)
+ __ptep_set_wrprotect(mm, address, ptep);
+}
+
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
#define __HAVE_ARCH_PMDP_SET_WRPROTECT
static inline void pmdp_set_wrprotect(struct mm_struct *mm,
unsigned long address, pmd_t *pmdp)
{
- ptep_set_wrprotect(mm, address, (pte_t *)pmdp);
+ __ptep_set_wrprotect(mm, address, (pte_t *)pmdp);
}
#define pmdp_establish pmdp_establish
@@ -1072,7 +1310,7 @@ static inline void arch_swap_restore(swp_entry_t entry, struct folio *folio)
#endif /* CONFIG_ARM64_MTE */
/*
- * On AArch64, the cache coherency is handled via the set_pte_at() function.
+ * On AArch64, the cache coherency is handled via the __set_ptes() function.
*/
static inline void update_mmu_cache_range(struct vm_fault *vmf,
struct vm_area_struct *vma, unsigned long addr, pte_t *ptep,
@@ -1124,6 +1362,282 @@ extern pte_t ptep_modify_prot_start(struct vm_area_struct *vma,
extern void ptep_modify_prot_commit(struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep,
pte_t old_pte, pte_t new_pte);
+
+#ifdef CONFIG_ARM64_CONTPTE
+
+/*
+ * The contpte APIs are used to transparently manage the contiguous bit in ptes
+ * where it is possible and makes sense to do so. The PTE_CONT bit is considered
+ * a private implementation detail of the public ptep API (see below).
+ */
+extern void __contpte_try_fold(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pte);
+extern void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pte);
+extern pte_t contpte_ptep_get(pte_t *ptep, pte_t orig_pte);
+extern pte_t contpte_ptep_get_lockless(pte_t *orig_ptep);
+extern void contpte_set_ptes(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pte, unsigned int nr);
+extern void contpte_clear_full_ptes(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, unsigned int nr, int full);
+extern pte_t contpte_get_and_clear_full_ptes(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep,
+ unsigned int nr, int full);
+extern int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep);
+extern int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep);
+extern void contpte_wrprotect_ptes(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, unsigned int nr);
+extern int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep,
+ pte_t entry, int dirty);
+
+static __always_inline void contpte_try_fold(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep, pte_t pte)
+{
+ /*
+ * Only bother trying if both the virtual and physical addresses are
+ * aligned and correspond to the last entry in a contig range. The core
+ * code mostly modifies ranges from low to high, so this is the likely
+ * the last modification in the contig range, so a good time to fold.
+ * We can't fold special mappings, because there is no associated folio.
+ */
+
+ const unsigned long contmask = CONT_PTES - 1;
+ bool valign = ((addr >> PAGE_SHIFT) & contmask) == contmask;
+
+ if (unlikely(valign)) {
+ bool palign = (pte_pfn(pte) & contmask) == contmask;
+
+ if (unlikely(palign &&
+ pte_valid(pte) && !pte_cont(pte) && !pte_special(pte)))
+ __contpte_try_fold(mm, addr, ptep, pte);
+ }
+}
+
+static __always_inline void contpte_try_unfold(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep, pte_t pte)
+{
+ if (unlikely(pte_valid_cont(pte)))
+ __contpte_try_unfold(mm, addr, ptep, pte);
+}
+
+#define pte_batch_hint pte_batch_hint
+static inline unsigned int pte_batch_hint(pte_t *ptep, pte_t pte)
+{
+ if (!pte_valid_cont(pte))
+ return 1;
+
+ return CONT_PTES - (((unsigned long)ptep >> 3) & (CONT_PTES - 1));
+}
+
+/*
+ * The below functions constitute the public API that arm64 presents to the
+ * core-mm to manipulate PTE entries within their page tables (or at least this
+ * is the subset of the API that arm64 needs to implement). These public
+ * versions will automatically and transparently apply the contiguous bit where
+ * it makes sense to do so. Therefore any users that are contig-aware (e.g.
+ * hugetlb, kernel mapper) should NOT use these APIs, but instead use the
+ * private versions, which are prefixed with double underscore. All of these
+ * APIs except for ptep_get_lockless() are expected to be called with the PTL
+ * held. Although the contiguous bit is considered private to the
+ * implementation, it is deliberately allowed to leak through the getters (e.g.
+ * ptep_get()), back to core code. This is required so that pte_leaf_size() can
+ * provide an accurate size for perf_get_pgtable_size(). But this leakage means
+ * its possible a pte will be passed to a setter with the contiguous bit set, so
+ * we explicitly clear the contiguous bit in those cases to prevent accidentally
+ * setting it in the pgtable.
+ */
+
+#define ptep_get ptep_get
+static inline pte_t ptep_get(pte_t *ptep)
+{
+ pte_t pte = __ptep_get(ptep);
+
+ if (likely(!pte_valid_cont(pte)))
+ return pte;
+
+ return contpte_ptep_get(ptep, pte);
+}
+
+#define ptep_get_lockless ptep_get_lockless
+static inline pte_t ptep_get_lockless(pte_t *ptep)
+{
+ pte_t pte = __ptep_get(ptep);
+
+ if (likely(!pte_valid_cont(pte)))
+ return pte;
+
+ return contpte_ptep_get_lockless(ptep);
+}
+
+static inline void set_pte(pte_t *ptep, pte_t pte)
+{
+ /*
+ * We don't have the mm or vaddr so cannot unfold contig entries (since
+ * it requires tlb maintenance). set_pte() is not used in core code, so
+ * this should never even be called. Regardless do our best to service
+ * any call and emit a warning if there is any attempt to set a pte on
+ * top of an existing contig range.
+ */
+ pte_t orig_pte = __ptep_get(ptep);
+
+ WARN_ON_ONCE(pte_valid_cont(orig_pte));
+ __set_pte(ptep, pte_mknoncont(pte));
+}
+
+#define set_ptes set_ptes
+static __always_inline void set_ptes(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pte, unsigned int nr)
+{
+ pte = pte_mknoncont(pte);
+
+ if (likely(nr == 1)) {
+ contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
+ __set_ptes(mm, addr, ptep, pte, 1);
+ contpte_try_fold(mm, addr, ptep, pte);
+ } else {
+ contpte_set_ptes(mm, addr, ptep, pte, nr);
+ }
+}
+
+static inline void pte_clear(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
+{
+ contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
+ __pte_clear(mm, addr, ptep);
+}
+
+#define clear_full_ptes clear_full_ptes
+static inline void clear_full_ptes(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, unsigned int nr, int full)
+{
+ if (likely(nr == 1)) {
+ contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
+ __clear_full_ptes(mm, addr, ptep, nr, full);
+ } else {
+ contpte_clear_full_ptes(mm, addr, ptep, nr, full);
+ }
+}
+
+#define get_and_clear_full_ptes get_and_clear_full_ptes
+static inline pte_t get_and_clear_full_ptes(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep,
+ unsigned int nr, int full)
+{
+ pte_t pte;
+
+ if (likely(nr == 1)) {
+ contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
+ pte = __get_and_clear_full_ptes(mm, addr, ptep, nr, full);
+ } else {
+ pte = contpte_get_and_clear_full_ptes(mm, addr, ptep, nr, full);
+ }
+
+ return pte;
+}
+
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
+{
+ contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
+ return __ptep_get_and_clear(mm, addr, ptep);
+}
+
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
+static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep)
+{
+ pte_t orig_pte = __ptep_get(ptep);
+
+ if (likely(!pte_valid_cont(orig_pte)))
+ return __ptep_test_and_clear_young(vma, addr, ptep);
+
+ return contpte_ptep_test_and_clear_young(vma, addr, ptep);
+}
+
+#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
+static inline int ptep_clear_flush_young(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep)
+{
+ pte_t orig_pte = __ptep_get(ptep);
+
+ if (likely(!pte_valid_cont(orig_pte)))
+ return __ptep_clear_flush_young(vma, addr, ptep);
+
+ return contpte_ptep_clear_flush_young(vma, addr, ptep);
+}
+
+#define wrprotect_ptes wrprotect_ptes
+static __always_inline void wrprotect_ptes(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep, unsigned int nr)
+{
+ if (likely(nr == 1)) {
+ /*
+ * Optimization: wrprotect_ptes() can only be called for present
+ * ptes so we only need to check contig bit as condition for
+ * unfold, and we can remove the contig bit from the pte we read
+ * to avoid re-reading. This speeds up fork() which is sensitive
+ * for order-0 folios. Equivalent to contpte_try_unfold().
+ */
+ pte_t orig_pte = __ptep_get(ptep);
+
+ if (unlikely(pte_cont(orig_pte))) {
+ __contpte_try_unfold(mm, addr, ptep, orig_pte);
+ orig_pte = pte_mknoncont(orig_pte);
+ }
+ ___ptep_set_wrprotect(mm, addr, ptep, orig_pte);
+ } else {
+ contpte_wrprotect_ptes(mm, addr, ptep, nr);
+ }
+}
+
+#define __HAVE_ARCH_PTEP_SET_WRPROTECT
+static inline void ptep_set_wrprotect(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
+{
+ wrprotect_ptes(mm, addr, ptep, 1);
+}
+
+#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
+static inline int ptep_set_access_flags(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep,
+ pte_t entry, int dirty)
+{
+ pte_t orig_pte = __ptep_get(ptep);
+
+ entry = pte_mknoncont(entry);
+
+ if (likely(!pte_valid_cont(orig_pte)))
+ return __ptep_set_access_flags(vma, addr, ptep, entry, dirty);
+
+ return contpte_ptep_set_access_flags(vma, addr, ptep, entry, dirty);
+}
+
+#else /* CONFIG_ARM64_CONTPTE */
+
+#define ptep_get __ptep_get
+#define set_pte __set_pte
+#define set_ptes __set_ptes
+#define pte_clear __pte_clear
+#define clear_full_ptes __clear_full_ptes
+#define get_and_clear_full_ptes __get_and_clear_full_ptes
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+#define ptep_get_and_clear __ptep_get_and_clear
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
+#define ptep_test_and_clear_young __ptep_test_and_clear_young
+#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
+#define ptep_clear_flush_young __ptep_clear_flush_young
+#define __HAVE_ARCH_PTEP_SET_WRPROTECT
+#define ptep_set_wrprotect __ptep_set_wrprotect
+#define wrprotect_ptes __wrprotect_ptes
+#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
+#define ptep_set_access_flags __ptep_set_access_flags
+
+#endif /* CONFIG_ARM64_CONTPTE */
+
#endif /* !__ASSEMBLY__ */
#endif /* __ASM_PGTABLE_H */
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 5b0a04810b23..f77371232d8c 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -155,6 +155,8 @@ struct thread_struct {
struct {
unsigned long tp_value; /* TLS register */
unsigned long tp2_value;
+ u64 fpmr;
+ unsigned long pad;
struct user_fpsimd_state fpsimd_state;
} uw;
@@ -253,6 +255,8 @@ static inline void arch_thread_struct_whitelist(unsigned long *offset,
BUILD_BUG_ON(sizeof_field(struct thread_struct, uw) !=
sizeof_field(struct thread_struct, uw.tp_value) +
sizeof_field(struct thread_struct, uw.tp2_value) +
+ sizeof_field(struct thread_struct, uw.fpmr) +
+ sizeof_field(struct thread_struct, uw.pad) +
sizeof_field(struct thread_struct, uw.fpsimd_state));
*offset = offsetof(struct thread_struct, uw);
diff --git a/arch/arm64/include/asm/ptdump.h b/arch/arm64/include/asm/ptdump.h
index 581caac525b0..5b1701c76d1c 100644
--- a/arch/arm64/include/asm/ptdump.h
+++ b/arch/arm64/include/asm/ptdump.h
@@ -29,13 +29,6 @@ void __init ptdump_debugfs_register(struct ptdump_info *info, const char *name);
static inline void ptdump_debugfs_register(struct ptdump_info *info,
const char *name) { }
#endif
-void ptdump_check_wx(void);
#endif /* CONFIG_PTDUMP_CORE */
-#ifdef CONFIG_DEBUG_WX
-#define debug_checkwx() ptdump_check_wx()
-#else
-#define debug_checkwx() do { } while (0)
-#endif
-
#endif /* __ASM_PTDUMP_H */
diff --git a/arch/arm64/include/asm/scs.h b/arch/arm64/include/asm/scs.h
index 3fdae5fe3142..2e010ea76be2 100644
--- a/arch/arm64/include/asm/scs.h
+++ b/arch/arm64/include/asm/scs.h
@@ -33,37 +33,11 @@
#include <asm/cpufeature.h>
#ifdef CONFIG_UNWIND_PATCH_PAC_INTO_SCS
-static inline bool should_patch_pac_into_scs(void)
-{
- u64 reg;
-
- /*
- * We only enable the shadow call stack dynamically if we are running
- * on a system that does not implement PAC or BTI. PAC and SCS provide
- * roughly the same level of protection, and BTI relies on the PACIASP
- * instructions serving as landing pads, preventing us from patching
- * those instructions into something else.
- */
- reg = read_sysreg_s(SYS_ID_AA64ISAR1_EL1);
- if (SYS_FIELD_GET(ID_AA64ISAR1_EL1, APA, reg) |
- SYS_FIELD_GET(ID_AA64ISAR1_EL1, API, reg))
- return false;
-
- reg = read_sysreg_s(SYS_ID_AA64ISAR2_EL1);
- if (SYS_FIELD_GET(ID_AA64ISAR2_EL1, APA3, reg))
- return false;
-
- if (IS_ENABLED(CONFIG_ARM64_BTI_KERNEL)) {
- reg = read_sysreg_s(SYS_ID_AA64PFR1_EL1);
- if (reg & (0xf << ID_AA64PFR1_EL1_BT_SHIFT))
- return false;
- }
- return true;
-}
-
static inline void dynamic_scs_init(void)
{
- if (should_patch_pac_into_scs()) {
+ extern bool __pi_dynamic_scs_is_enabled;
+
+ if (__pi_dynamic_scs_is_enabled) {
pr_info("Enabling dynamic shadow call stack\n");
static_branch_enable(&dynamic_scs_enabled);
}
@@ -72,8 +46,8 @@ static inline void dynamic_scs_init(void)
static inline void dynamic_scs_init(void) {}
#endif
-int scs_patch(const u8 eh_frame[], int size);
-asmlinkage void scs_patch_vmlinux(void);
+int __pi_scs_patch(const u8 eh_frame[], int size);
+asmlinkage void __pi_scs_patch_vmlinux(void);
#endif /* __ASSEMBLY __ */
diff --git a/arch/arm64/include/asm/setup.h b/arch/arm64/include/asm/setup.h
index 2e4d7da74fb8..ba269a7a3201 100644
--- a/arch/arm64/include/asm/setup.h
+++ b/arch/arm64/include/asm/setup.h
@@ -7,9 +7,6 @@
#include <uapi/asm/setup.h>
-void *get_early_fdt_ptr(void);
-void early_fdt_map(u64 dt_phys);
-
/*
* These two variables are used in the head.S file.
*/
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index c3b19b376c86..9e8999592f3a 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -1181,6 +1181,8 @@
par; \
})
+#define SYS_FIELD_VALUE(reg, field, val) reg##_##field##_##val
+
#define SYS_FIELD_GET(reg, field, val) \
FIELD_GET(reg##_##field##_MASK, val)
@@ -1188,7 +1190,8 @@
FIELD_PREP(reg##_##field##_MASK, val)
#define SYS_FIELD_PREP_ENUM(reg, field, val) \
- FIELD_PREP(reg##_##field##_MASK, reg##_##field##_##val)
+ FIELD_PREP(reg##_##field##_MASK, \
+ SYS_FIELD_VALUE(reg, field, val))
#endif
diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
index 0150deb332af..a947c6e784ed 100644
--- a/arch/arm64/include/asm/tlb.h
+++ b/arch/arm64/include/asm/tlb.h
@@ -103,6 +103,9 @@ static inline void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pudp,
{
struct ptdesc *ptdesc = virt_to_ptdesc(pudp);
+ if (!pgtable_l4_enabled())
+ return;
+
pagetable_pud_dtor(ptdesc);
tlb_remove_ptdesc(tlb, ptdesc);
}
diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
index 1deb5d789c2e..3b0e8248e1a4 100644
--- a/arch/arm64/include/asm/tlbflush.h
+++ b/arch/arm64/include/asm/tlbflush.h
@@ -422,7 +422,7 @@ do { \
#define __flush_s2_tlb_range_op(op, start, pages, stride, tlb_level) \
__flush_tlb_range_op(op, start, pages, stride, 0, tlb_level, false, kvm_lpa2_is_enabled());
-static inline void __flush_tlb_range(struct vm_area_struct *vma,
+static inline void __flush_tlb_range_nosync(struct vm_area_struct *vma,
unsigned long start, unsigned long end,
unsigned long stride, bool last_level,
int tlb_level)
@@ -456,10 +456,19 @@ static inline void __flush_tlb_range(struct vm_area_struct *vma,
__flush_tlb_range_op(vae1is, start, pages, stride, asid,
tlb_level, true, lpa2_is_enabled());
- dsb(ish);
mmu_notifier_arch_invalidate_secondary_tlbs(vma->vm_mm, start, end);
}
+static inline void __flush_tlb_range(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end,
+ unsigned long stride, bool last_level,
+ int tlb_level)
+{
+ __flush_tlb_range_nosync(vma, start, end, stride,
+ last_level, tlb_level);
+ dsb(ish);
+}
+
static inline void flush_tlb_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
{
diff --git a/arch/arm64/include/asm/word-at-a-time.h b/arch/arm64/include/asm/word-at-a-time.h
index f3b151ed0d7a..14251abee23c 100644
--- a/arch/arm64/include/asm/word-at-a-time.h
+++ b/arch/arm64/include/asm/word-at-a-time.h
@@ -9,7 +9,8 @@
#ifndef __AARCH64EB__
-#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/wordpart.h>
struct word_at_a_time {
const unsigned long one_bits, high_bits;
diff --git a/arch/arm64/include/uapi/asm/hwcap.h b/arch/arm64/include/uapi/asm/hwcap.h
index 5023599fa278..285610e626f5 100644
--- a/arch/arm64/include/uapi/asm/hwcap.h
+++ b/arch/arm64/include/uapi/asm/hwcap.h
@@ -107,5 +107,20 @@
#define HWCAP2_SVE_B16B16 (1UL << 45)
#define HWCAP2_LRCPC3 (1UL << 46)
#define HWCAP2_LSE128 (1UL << 47)
+#define HWCAP2_FPMR (1UL << 48)
+#define HWCAP2_LUT (1UL << 49)
+#define HWCAP2_FAMINMAX (1UL << 50)
+#define HWCAP2_F8CVT (1UL << 51)
+#define HWCAP2_F8FMA (1UL << 52)
+#define HWCAP2_F8DP4 (1UL << 53)
+#define HWCAP2_F8DP2 (1UL << 54)
+#define HWCAP2_F8E4M3 (1UL << 55)
+#define HWCAP2_F8E5M2 (1UL << 56)
+#define HWCAP2_SME_LUTV2 (1UL << 57)
+#define HWCAP2_SME_F8F16 (1UL << 58)
+#define HWCAP2_SME_F8F32 (1UL << 59)
+#define HWCAP2_SME_SF8FMA (1UL << 60)
+#define HWCAP2_SME_SF8DP4 (1UL << 61)
+#define HWCAP2_SME_SF8DP2 (1UL << 62)
#endif /* _UAPI__ASM_HWCAP_H */
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 89d2fc872d9f..964df31da975 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -37,9 +37,7 @@
#include <asm/ptrace.h>
#include <asm/sve_context.h>
-#define __KVM_HAVE_GUEST_DEBUG
#define __KVM_HAVE_IRQ_LINE
-#define __KVM_HAVE_READONLY_MEM
#define __KVM_HAVE_VCPU_EVENTS
#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
@@ -76,11 +74,11 @@ struct kvm_regs {
/* KVM_ARM_SET_DEVICE_ADDR ioctl id encoding */
#define KVM_ARM_DEVICE_TYPE_SHIFT 0
-#define KVM_ARM_DEVICE_TYPE_MASK GENMASK(KVM_ARM_DEVICE_TYPE_SHIFT + 15, \
- KVM_ARM_DEVICE_TYPE_SHIFT)
+#define KVM_ARM_DEVICE_TYPE_MASK __GENMASK(KVM_ARM_DEVICE_TYPE_SHIFT + 15, \
+ KVM_ARM_DEVICE_TYPE_SHIFT)
#define KVM_ARM_DEVICE_ID_SHIFT 16
-#define KVM_ARM_DEVICE_ID_MASK GENMASK(KVM_ARM_DEVICE_ID_SHIFT + 15, \
- KVM_ARM_DEVICE_ID_SHIFT)
+#define KVM_ARM_DEVICE_ID_MASK __GENMASK(KVM_ARM_DEVICE_ID_SHIFT + 15, \
+ KVM_ARM_DEVICE_ID_SHIFT)
/* Supported device IDs */
#define KVM_ARM_DEVICE_VGIC_V2 0
@@ -162,6 +160,11 @@ struct kvm_sync_regs {
__u64 device_irq_level;
};
+/* Bits for run->s.regs.device_irq_level */
+#define KVM_ARM_DEV_EL1_VTIMER (1 << 0)
+#define KVM_ARM_DEV_EL1_PTIMER (1 << 1)
+#define KVM_ARM_DEV_PMU (1 << 2)
+
/*
* PMU filter structure. Describe a range of events with a particular
* action. To be used with KVM_ARM_VCPU_PMU_V3_FILTER.
diff --git a/arch/arm64/include/uapi/asm/sigcontext.h b/arch/arm64/include/uapi/asm/sigcontext.h
index f23c1dc3f002..8a45b7a411e0 100644
--- a/arch/arm64/include/uapi/asm/sigcontext.h
+++ b/arch/arm64/include/uapi/asm/sigcontext.h
@@ -152,6 +152,14 @@ struct tpidr2_context {
__u64 tpidr2;
};
+/* FPMR context */
+#define FPMR_MAGIC 0x46504d52
+
+struct fpmr_context {
+ struct _aarch64_ctx head;
+ __u64 fpmr;
+};
+
#define ZA_MAGIC 0x54366345
struct za_context {
diff --git a/arch/arm64/include/uapi/asm/sve_context.h b/arch/arm64/include/uapi/asm/sve_context.h
index 754ab751b523..72aefc081061 100644
--- a/arch/arm64/include/uapi/asm/sve_context.h
+++ b/arch/arm64/include/uapi/asm/sve_context.h
@@ -13,6 +13,17 @@
#define __SVE_VQ_BYTES 16 /* number of bytes per quadword */
+/*
+ * Yes, __SVE_VQ_MAX is 512 QUADWORDS.
+ *
+ * To help ensure forward portability, this is much larger than the
+ * current maximum value defined by the SVE architecture. While arrays
+ * or static allocations can be sized based on this value, watch out!
+ * It will waste a surprisingly large amount of memory.
+ *
+ * Dynamic sizing based on the actual runtime vector length is likely to
+ * be preferable for most purposes.
+ */
#define __SVE_VQ_MIN 1
#define __SVE_VQ_MAX 512
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 467cb7117273..763824963ed1 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -33,8 +33,7 @@ obj-y := debug-monitors.o entry.o irq.o fpsimd.o \
return_address.o cpuinfo.o cpu_errata.o \
cpufeature.o alternative.o cacheinfo.o \
smp.o smp_spin_table.o topology.o smccc-call.o \
- syscall.o proton-pack.o idreg-override.o idle.o \
- patching.o
+ syscall.o proton-pack.o idle.o patching.o pi/
obj-$(CONFIG_COMPAT) += sys32.o signal32.o \
sys_compat.o
@@ -57,7 +56,7 @@ obj-$(CONFIG_ACPI) += acpi.o
obj-$(CONFIG_ACPI_NUMA) += acpi_numa.o
obj-$(CONFIG_ARM64_ACPI_PARKING_PROTOCOL) += acpi_parking_protocol.o
obj-$(CONFIG_PARAVIRT) += paravirt.o
-obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o pi/
+obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o
obj-$(CONFIG_HIBERNATION) += hibernate.o hibernate-asm.o
obj-$(CONFIG_ELF_CORE) += elfcore.o
obj-$(CONFIG_KEXEC_CORE) += machine_kexec.o relocate_kernel.o \
@@ -66,20 +65,12 @@ obj-$(CONFIG_KEXEC_FILE) += machine_kexec_file.o kexec_image.o
obj-$(CONFIG_ARM64_RELOC_TEST) += arm64-reloc-test.o
arm64-reloc-test-y := reloc_test_core.o reloc_test_syms.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
-obj-$(CONFIG_CRASH_CORE) += crash_core.o
+obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o
obj-$(CONFIG_ARM_SDE_INTERFACE) += sdei.o
obj-$(CONFIG_ARM64_PTR_AUTH) += pointer_auth.o
obj-$(CONFIG_ARM64_MTE) += mte.o
obj-y += vdso-wrap.o
obj-$(CONFIG_COMPAT_VDSO) += vdso32-wrap.o
-obj-$(CONFIG_UNWIND_PATCH_PAC_INTO_SCS) += patch-scs.o
-
-# We need to prevent the SCS patching code from patching itself. Using
-# -mbranch-protection=none here to avoid the patchable PAC opcodes from being
-# generated triggers an issue with full LTO on Clang, which stops emitting PAC
-# instructions altogether. So disable LTO as well for the compilation unit.
-CFLAGS_patch-scs.o += -mbranch-protection=none
-CFLAGS_REMOVE_patch-scs.o += $(CC_FLAGS_LTO)
# Force dependency (vdso*-wrap.S includes vdso.so through incbin)
$(obj)/vdso-wrap.o: $(obj)/vdso/vdso.so
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index 5a7dbbe0ce63..81496083c041 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -75,8 +75,8 @@ int main(void)
DEFINE(S_FP, offsetof(struct pt_regs, regs[29]));
DEFINE(S_LR, offsetof(struct pt_regs, regs[30]));
DEFINE(S_SP, offsetof(struct pt_regs, sp));
- DEFINE(S_PSTATE, offsetof(struct pt_regs, pstate));
DEFINE(S_PC, offsetof(struct pt_regs, pc));
+ DEFINE(S_PSTATE, offsetof(struct pt_regs, pstate));
DEFINE(S_SYSCALLNO, offsetof(struct pt_regs, syscallno));
DEFINE(S_SDEI_TTBR1, offsetof(struct pt_regs, sdei_ttbr1));
DEFINE(S_PMR_SAVE, offsetof(struct pt_regs, pmr_save));
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 8d1a634a403e..56583677c1f2 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -140,12 +140,42 @@ void dump_cpu_features(void)
pr_emerg("0x%*pb\n", ARM64_NCAPS, &system_cpucaps);
}
+#define __ARM64_MAX_POSITIVE(reg, field) \
+ ((reg##_##field##_SIGNED ? \
+ BIT(reg##_##field##_WIDTH - 1) : \
+ BIT(reg##_##field##_WIDTH)) - 1)
+
+#define __ARM64_MIN_NEGATIVE(reg, field) BIT(reg##_##field##_WIDTH - 1)
+
+#define __ARM64_CPUID_FIELDS(reg, field, min_value, max_value) \
+ .sys_reg = SYS_##reg, \
+ .field_pos = reg##_##field##_SHIFT, \
+ .field_width = reg##_##field##_WIDTH, \
+ .sign = reg##_##field##_SIGNED, \
+ .min_field_value = min_value, \
+ .max_field_value = max_value,
+
+/*
+ * ARM64_CPUID_FIELDS() encodes a field with a range from min_value to
+ * an implicit maximum that depends on the sign-ess of the field.
+ *
+ * An unsigned field will be capped at all ones, while a signed field
+ * will be limited to the positive half only.
+ */
#define ARM64_CPUID_FIELDS(reg, field, min_value) \
- .sys_reg = SYS_##reg, \
- .field_pos = reg##_##field##_SHIFT, \
- .field_width = reg##_##field##_WIDTH, \
- .sign = reg##_##field##_SIGNED, \
- .min_field_value = reg##_##field##_##min_value,
+ __ARM64_CPUID_FIELDS(reg, field, \
+ SYS_FIELD_VALUE(reg, field, min_value), \
+ __ARM64_MAX_POSITIVE(reg, field))
+
+/*
+ * ARM64_CPUID_FIELDS_NEG() encodes a field with a range from an
+ * implicit minimal value to max_value. This should be used when
+ * matching a non-implemented property.
+ */
+#define ARM64_CPUID_FIELDS_NEG(reg, field, max_value) \
+ __ARM64_CPUID_FIELDS(reg, field, \
+ __ARM64_MIN_NEGATIVE(reg, field), \
+ SYS_FIELD_VALUE(reg, field, max_value))
#define __ARM64_FTR_BITS(SIGNED, VISIBLE, STRICT, TYPE, SHIFT, WIDTH, SAFE_VAL) \
{ \
@@ -220,6 +250,7 @@ static const struct arm64_ftr_bits ftr_id_aa64isar1[] = {
};
static const struct arm64_ftr_bits ftr_id_aa64isar2[] = {
+ ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_LUT_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_CSSC_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_RPRFM_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_CLRBHB_SHIFT, 4, 0),
@@ -234,6 +265,11 @@ static const struct arm64_ftr_bits ftr_id_aa64isar2[] = {
ARM64_FTR_END,
};
+static const struct arm64_ftr_bits ftr_id_aa64isar3[] = {
+ ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR3_EL1_FAMINMAX_SHIFT, 4, 0),
+ ARM64_FTR_END,
+};
+
static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = {
ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL1_CSV3_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL1_CSV2_SHIFT, 4, 0),
@@ -267,6 +303,11 @@ static const struct arm64_ftr_bits ftr_id_aa64pfr1[] = {
ARM64_FTR_END,
};
+static const struct arm64_ftr_bits ftr_id_aa64pfr2[] = {
+ ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR2_EL1_FPMR_SHIFT, 4, 0),
+ ARM64_FTR_END,
+};
+
static const struct arm64_ftr_bits ftr_id_aa64zfr0[] = {
ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE),
FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_EL1_F64MM_SHIFT, 4, 0),
@@ -295,6 +336,8 @@ static const struct arm64_ftr_bits ftr_id_aa64smfr0[] = {
ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_FA64_SHIFT, 1, 0),
ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+ FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_LUTv2_SHIFT, 1, 0),
+ ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_SMEver_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_I16I64_SHIFT, 4, 0),
@@ -307,6 +350,10 @@ static const struct arm64_ftr_bits ftr_id_aa64smfr0[] = {
ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_F16F16_SHIFT, 1, 0),
ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+ FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_F8F16_SHIFT, 1, 0),
+ ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+ FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_F8F32_SHIFT, 1, 0),
+ ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_I8I32_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_F16F32_SHIFT, 1, 0),
@@ -316,6 +363,22 @@ static const struct arm64_ftr_bits ftr_id_aa64smfr0[] = {
FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_BI32I32_SHIFT, 1, 0),
ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_F32F32_SHIFT, 1, 0),
+ ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+ FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_SF8FMA_SHIFT, 1, 0),
+ ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+ FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_SF8DP4_SHIFT, 1, 0),
+ ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+ FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_EL1_SF8DP2_SHIFT, 1, 0),
+ ARM64_FTR_END,
+};
+
+static const struct arm64_ftr_bits ftr_id_aa64fpfr0[] = {
+ ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64FPFR0_EL1_F8CVT_SHIFT, 1, 0),
+ ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64FPFR0_EL1_F8FMA_SHIFT, 1, 0),
+ ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64FPFR0_EL1_F8DP4_SHIFT, 1, 0),
+ ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64FPFR0_EL1_F8DP2_SHIFT, 1, 0),
+ ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64FPFR0_EL1_F8E4M3_SHIFT, 1, 0),
+ ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64FPFR0_EL1_F8E5M2_SHIFT, 1, 0),
ARM64_FTR_END,
};
@@ -407,6 +470,11 @@ static const struct arm64_ftr_bits ftr_id_aa64mmfr3[] = {
ARM64_FTR_END,
};
+static const struct arm64_ftr_bits ftr_id_aa64mmfr4[] = {
+ S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR4_EL1_E2H0_SHIFT, 4, 0),
+ ARM64_FTR_END,
+};
+
static const struct arm64_ftr_bits ftr_ctr[] = {
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, 31, 1, 1), /* RES1 */
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, CTR_EL0_DIC_SHIFT, 1, 1),
@@ -655,13 +723,15 @@ static const struct arm64_ftr_bits ftr_raz[] = {
#define ARM64_FTR_REG(id, table) \
__ARM64_FTR_REG_OVERRIDE(#id, id, table, &no_override)
-struct arm64_ftr_override __ro_after_init id_aa64mmfr1_override;
-struct arm64_ftr_override __ro_after_init id_aa64pfr0_override;
-struct arm64_ftr_override __ro_after_init id_aa64pfr1_override;
-struct arm64_ftr_override __ro_after_init id_aa64zfr0_override;
-struct arm64_ftr_override __ro_after_init id_aa64smfr0_override;
-struct arm64_ftr_override __ro_after_init id_aa64isar1_override;
-struct arm64_ftr_override __ro_after_init id_aa64isar2_override;
+struct arm64_ftr_override id_aa64mmfr0_override;
+struct arm64_ftr_override id_aa64mmfr1_override;
+struct arm64_ftr_override id_aa64mmfr2_override;
+struct arm64_ftr_override id_aa64pfr0_override;
+struct arm64_ftr_override id_aa64pfr1_override;
+struct arm64_ftr_override id_aa64zfr0_override;
+struct arm64_ftr_override id_aa64smfr0_override;
+struct arm64_ftr_override id_aa64isar1_override;
+struct arm64_ftr_override id_aa64isar2_override;
struct arm64_ftr_override arm64_sw_feature_override;
@@ -702,10 +772,12 @@ static const struct __ftr_reg_entry {
&id_aa64pfr0_override),
ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64PFR1_EL1, ftr_id_aa64pfr1,
&id_aa64pfr1_override),
+ ARM64_FTR_REG(SYS_ID_AA64PFR2_EL1, ftr_id_aa64pfr2),
ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64ZFR0_EL1, ftr_id_aa64zfr0,
&id_aa64zfr0_override),
ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64SMFR0_EL1, ftr_id_aa64smfr0,
&id_aa64smfr0_override),
+ ARM64_FTR_REG(SYS_ID_AA64FPFR0_EL1, ftr_id_aa64fpfr0),
/* Op1 = 0, CRn = 0, CRm = 5 */
ARM64_FTR_REG(SYS_ID_AA64DFR0_EL1, ftr_id_aa64dfr0),
@@ -717,13 +789,17 @@ static const struct __ftr_reg_entry {
&id_aa64isar1_override),
ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64ISAR2_EL1, ftr_id_aa64isar2,
&id_aa64isar2_override),
+ ARM64_FTR_REG(SYS_ID_AA64ISAR3_EL1, ftr_id_aa64isar3),
/* Op1 = 0, CRn = 0, CRm = 7 */
- ARM64_FTR_REG(SYS_ID_AA64MMFR0_EL1, ftr_id_aa64mmfr0),
+ ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64MMFR0_EL1, ftr_id_aa64mmfr0,
+ &id_aa64mmfr0_override),
ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64MMFR1_EL1, ftr_id_aa64mmfr1,
&id_aa64mmfr1_override),
- ARM64_FTR_REG(SYS_ID_AA64MMFR2_EL1, ftr_id_aa64mmfr2),
+ ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64MMFR2_EL1, ftr_id_aa64mmfr2,
+ &id_aa64mmfr2_override),
ARM64_FTR_REG(SYS_ID_AA64MMFR3_EL1, ftr_id_aa64mmfr3),
+ ARM64_FTR_REG(SYS_ID_AA64MMFR4_EL1, ftr_id_aa64mmfr4),
/* Op1 = 1, CRn = 0, CRm = 0 */
ARM64_FTR_REG(SYS_GMID_EL1, ftr_gmid),
@@ -919,7 +995,8 @@ static void init_cpu_ftr_reg(u32 sys_reg, u64 new)
pr_warn("%s[%d:%d]: %s to %llx\n",
reg->name,
ftrp->shift + ftrp->width - 1,
- ftrp->shift, str, tmp);
+ ftrp->shift, str,
+ tmp & (BIT(ftrp->width) - 1));
} else if ((ftr_mask & reg->override->val) == ftr_mask) {
reg->override->val &= ~ftr_mask;
pr_warn("%s[%d:%d]: impossible override, ignored\n",
@@ -1043,14 +1120,18 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
init_cpu_ftr_reg(SYS_ID_AA64ISAR0_EL1, info->reg_id_aa64isar0);
init_cpu_ftr_reg(SYS_ID_AA64ISAR1_EL1, info->reg_id_aa64isar1);
init_cpu_ftr_reg(SYS_ID_AA64ISAR2_EL1, info->reg_id_aa64isar2);
+ init_cpu_ftr_reg(SYS_ID_AA64ISAR3_EL1, info->reg_id_aa64isar3);
init_cpu_ftr_reg(SYS_ID_AA64MMFR0_EL1, info->reg_id_aa64mmfr0);
init_cpu_ftr_reg(SYS_ID_AA64MMFR1_EL1, info->reg_id_aa64mmfr1);
init_cpu_ftr_reg(SYS_ID_AA64MMFR2_EL1, info->reg_id_aa64mmfr2);
init_cpu_ftr_reg(SYS_ID_AA64MMFR3_EL1, info->reg_id_aa64mmfr3);
+ init_cpu_ftr_reg(SYS_ID_AA64MMFR4_EL1, info->reg_id_aa64mmfr4);
init_cpu_ftr_reg(SYS_ID_AA64PFR0_EL1, info->reg_id_aa64pfr0);
init_cpu_ftr_reg(SYS_ID_AA64PFR1_EL1, info->reg_id_aa64pfr1);
+ init_cpu_ftr_reg(SYS_ID_AA64PFR2_EL1, info->reg_id_aa64pfr2);
init_cpu_ftr_reg(SYS_ID_AA64ZFR0_EL1, info->reg_id_aa64zfr0);
init_cpu_ftr_reg(SYS_ID_AA64SMFR0_EL1, info->reg_id_aa64smfr0);
+ init_cpu_ftr_reg(SYS_ID_AA64FPFR0_EL1, info->reg_id_aa64fpfr0);
if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0))
init_32bit_cpu_features(&info->aarch32);
@@ -1272,6 +1353,8 @@ void update_cpu_features(int cpu,
info->reg_id_aa64isar1, boot->reg_id_aa64isar1);
taint |= check_update_ftr_reg(SYS_ID_AA64ISAR2_EL1, cpu,
info->reg_id_aa64isar2, boot->reg_id_aa64isar2);
+ taint |= check_update_ftr_reg(SYS_ID_AA64ISAR3_EL1, cpu,
+ info->reg_id_aa64isar3, boot->reg_id_aa64isar3);
/*
* Differing PARange support is fine as long as all peripherals and
@@ -1291,6 +1374,8 @@ void update_cpu_features(int cpu,
info->reg_id_aa64pfr0, boot->reg_id_aa64pfr0);
taint |= check_update_ftr_reg(SYS_ID_AA64PFR1_EL1, cpu,
info->reg_id_aa64pfr1, boot->reg_id_aa64pfr1);
+ taint |= check_update_ftr_reg(SYS_ID_AA64PFR2_EL1, cpu,
+ info->reg_id_aa64pfr2, boot->reg_id_aa64pfr2);
taint |= check_update_ftr_reg(SYS_ID_AA64ZFR0_EL1, cpu,
info->reg_id_aa64zfr0, boot->reg_id_aa64zfr0);
@@ -1298,6 +1383,9 @@ void update_cpu_features(int cpu,
taint |= check_update_ftr_reg(SYS_ID_AA64SMFR0_EL1, cpu,
info->reg_id_aa64smfr0, boot->reg_id_aa64smfr0);
+ taint |= check_update_ftr_reg(SYS_ID_AA64FPFR0_EL1, cpu,
+ info->reg_id_aa64fpfr0, boot->reg_id_aa64fpfr0);
+
/* Probe vector lengths */
if (IS_ENABLED(CONFIG_ARM64_SVE) &&
id_aa64pfr0_sve(read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1))) {
@@ -1410,17 +1498,21 @@ u64 __read_sysreg_by_encoding(u32 sys_id)
read_sysreg_case(SYS_ID_AA64PFR0_EL1);
read_sysreg_case(SYS_ID_AA64PFR1_EL1);
+ read_sysreg_case(SYS_ID_AA64PFR2_EL1);
read_sysreg_case(SYS_ID_AA64ZFR0_EL1);
read_sysreg_case(SYS_ID_AA64SMFR0_EL1);
+ read_sysreg_case(SYS_ID_AA64FPFR0_EL1);
read_sysreg_case(SYS_ID_AA64DFR0_EL1);
read_sysreg_case(SYS_ID_AA64DFR1_EL1);
read_sysreg_case(SYS_ID_AA64MMFR0_EL1);
read_sysreg_case(SYS_ID_AA64MMFR1_EL1);
read_sysreg_case(SYS_ID_AA64MMFR2_EL1);
read_sysreg_case(SYS_ID_AA64MMFR3_EL1);
+ read_sysreg_case(SYS_ID_AA64MMFR4_EL1);
read_sysreg_case(SYS_ID_AA64ISAR0_EL1);
read_sysreg_case(SYS_ID_AA64ISAR1_EL1);
read_sysreg_case(SYS_ID_AA64ISAR2_EL1);
+ read_sysreg_case(SYS_ID_AA64ISAR3_EL1);
read_sysreg_case(SYS_CNTFRQ_EL0);
read_sysreg_case(SYS_CTR_EL0);
@@ -1451,11 +1543,28 @@ has_always(const struct arm64_cpu_capabilities *entry, int scope)
static bool
feature_matches(u64 reg, const struct arm64_cpu_capabilities *entry)
{
- int val = cpuid_feature_extract_field_width(reg, entry->field_pos,
- entry->field_width,
- entry->sign);
+ int val, min, max;
+ u64 tmp;
+
+ val = cpuid_feature_extract_field_width(reg, entry->field_pos,
+ entry->field_width,
+ entry->sign);
+
+ tmp = entry->min_field_value;
+ tmp <<= entry->field_pos;
+
+ min = cpuid_feature_extract_field_width(tmp, entry->field_pos,
+ entry->field_width,
+ entry->sign);
- return val >= entry->min_field_value;
+ tmp = entry->max_field_value;
+ tmp <<= entry->field_pos;
+
+ max = cpuid_feature_extract_field_width(tmp, entry->field_pos,
+ entry->field_width,
+ entry->sign);
+
+ return val >= min && val <= max;
}
static u64
@@ -1620,46 +1729,6 @@ has_useable_cnp(const struct arm64_cpu_capabilities *entry, int scope)
return has_cpuid_feature(entry, scope);
}
-/*
- * This check is triggered during the early boot before the cpufeature
- * is initialised. Checking the status on the local CPU allows the boot
- * CPU to detect the need for non-global mappings and thus avoiding a
- * pagetable re-write after all the CPUs are booted. This check will be
- * anyway run on individual CPUs, allowing us to get the consistent
- * state once the SMP CPUs are up and thus make the switch to non-global
- * mappings if required.
- */
-bool kaslr_requires_kpti(void)
-{
- if (!IS_ENABLED(CONFIG_RANDOMIZE_BASE))
- return false;
-
- /*
- * E0PD does a similar job to KPTI so can be used instead
- * where available.
- */
- if (IS_ENABLED(CONFIG_ARM64_E0PD)) {
- u64 mmfr2 = read_sysreg_s(SYS_ID_AA64MMFR2_EL1);
- if (cpuid_feature_extract_unsigned_field(mmfr2,
- ID_AA64MMFR2_EL1_E0PD_SHIFT))
- return false;
- }
-
- /*
- * Systems affected by Cavium erratum 24756 are incompatible
- * with KPTI.
- */
- if (IS_ENABLED(CONFIG_CAVIUM_ERRATUM_27456)) {
- extern const struct midr_range cavium_erratum_27456_cpus[];
-
- if (is_midr_in_range_list(read_cpuid_id(),
- cavium_erratum_27456_cpus))
- return false;
- }
-
- return kaslr_enabled();
-}
-
static bool __meltdown_safe = true;
static int __kpti_forced; /* 0: not forced, >0: forced on, <0: forced off */
@@ -1712,7 +1781,7 @@ static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry,
}
/* Useful for KASLR robustness */
- if (kaslr_requires_kpti()) {
+ if (kaslr_enabled() && kaslr_requires_kpti()) {
if (!__kpti_forced) {
str = "KASLR";
__kpti_forced = 1;
@@ -1739,6 +1808,28 @@ static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry,
return !meltdown_safe;
}
+static bool has_nv1(const struct arm64_cpu_capabilities *entry, int scope)
+{
+ /*
+ * Although the Apple M2 family appears to support NV1, the
+ * PTW barfs on the nVHE EL2 S1 page table format. Pretend
+ * that it doesn't support NV1 at all.
+ */
+ static const struct midr_range nv1_ni_list[] = {
+ MIDR_ALL_VERSIONS(MIDR_APPLE_M2_BLIZZARD),
+ MIDR_ALL_VERSIONS(MIDR_APPLE_M2_AVALANCHE),
+ MIDR_ALL_VERSIONS(MIDR_APPLE_M2_BLIZZARD_PRO),
+ MIDR_ALL_VERSIONS(MIDR_APPLE_M2_AVALANCHE_PRO),
+ MIDR_ALL_VERSIONS(MIDR_APPLE_M2_BLIZZARD_MAX),
+ MIDR_ALL_VERSIONS(MIDR_APPLE_M2_AVALANCHE_MAX),
+ {}
+ };
+
+ return (__system_matches_cap(ARM64_HAS_NESTED_VIRT) &&
+ !(has_cpuid_feature(entry, scope) ||
+ is_midr_in_range_list(read_cpuid_id(), nv1_ni_list)));
+}
+
#if defined(ID_AA64MMFR0_EL1_TGRAN_LPA2) && defined(ID_AA64MMFR0_EL1_TGRAN_2_SUPPORTED_LPA2)
static bool has_lpa2_at_stage1(u64 mmfr0)
{
@@ -1801,6 +1892,11 @@ static int __init __kpti_install_ng_mappings(void *__unused)
pgd_t *kpti_ng_temp_pgd;
u64 alloc = 0;
+ if (levels == 5 && !pgtable_l5_enabled())
+ levels = 4;
+ else if (levels == 4 && !pgtable_l4_enabled())
+ levels = 3;
+
remap_fn = (void *)__pa_symbol(idmap_kpti_install_ng_mappings);
if (!cpu) {
@@ -1814,9 +1910,9 @@ static int __init __kpti_install_ng_mappings(void *__unused)
//
// The physical pages are laid out as follows:
//
- // +--------+-/-------+-/------ +-\\--------+
- // : PTE[] : | PMD[] : | PUD[] : || PGD[] :
- // +--------+-\-------+-\------ +-//--------+
+ // +--------+-/-------+-/------ +-/------ +-\\\--------+
+ // : PTE[] : | PMD[] : | PUD[] : | P4D[] : ||| PGD[] :
+ // +--------+-\-------+-\------ +-\------ +-///--------+
// ^
// The first page is mapped into this hierarchy at a PMD_SHIFT
// aligned virtual address, so that we can manipulate the PTE
@@ -2042,14 +2138,7 @@ static bool has_nested_virt_support(const struct arm64_cpu_capabilities *cap,
static bool hvhe_possible(const struct arm64_cpu_capabilities *entry,
int __unused)
{
- u64 val;
-
- val = read_sysreg(id_aa64mmfr1_el1);
- if (!cpuid_feature_extract_unsigned_field(val, ID_AA64MMFR1_EL1_VH_SHIFT))
- return false;
-
- val = arm64_sw_feature_override.val & arm64_sw_feature_override.mask;
- return cpuid_feature_extract_unsigned_field(val, ARM64_SW_FEATURE_OVERRIDE_HVHE);
+ return arm64_test_sw_feature_override(ARM64_SW_FEATURE_OVERRIDE_HVHE);
}
#ifdef CONFIG_ARM64_PAN
@@ -2739,6 +2828,39 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.type = ARM64_CPUCAP_SYSTEM_FEATURE,
.matches = has_lpa2,
},
+ {
+ .desc = "FPMR",
+ .type = ARM64_CPUCAP_SYSTEM_FEATURE,
+ .capability = ARM64_HAS_FPMR,
+ .matches = has_cpuid_feature,
+ .cpu_enable = cpu_enable_fpmr,
+ ARM64_CPUID_FIELDS(ID_AA64PFR2_EL1, FPMR, IMP)
+ },
+#ifdef CONFIG_ARM64_VA_BITS_52
+ {
+ .capability = ARM64_HAS_VA52,
+ .type = ARM64_CPUCAP_BOOT_CPU_FEATURE,
+ .matches = has_cpuid_feature,
+#ifdef CONFIG_ARM64_64K_PAGES
+ .desc = "52-bit Virtual Addressing (LVA)",
+ ARM64_CPUID_FIELDS(ID_AA64MMFR2_EL1, VARange, 52)
+#else
+ .desc = "52-bit Virtual Addressing (LPA2)",
+#ifdef CONFIG_ARM64_4K_PAGES
+ ARM64_CPUID_FIELDS(ID_AA64MMFR0_EL1, TGRAN4, 52_BIT)
+#else
+ ARM64_CPUID_FIELDS(ID_AA64MMFR0_EL1, TGRAN16, 52_BIT)
+#endif
+#endif
+ },
+#endif
+ {
+ .desc = "NV1",
+ .capability = ARM64_HAS_HCR_NV1,
+ .type = ARM64_CPUCAP_SYSTEM_FEATURE,
+ .matches = has_nv1,
+ ARM64_CPUID_FIELDS_NEG(ID_AA64MMFR4_EL1, E2H0, NI_NV1)
+ },
{},
};
@@ -2822,6 +2944,7 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
HWCAP_CAP(ID_AA64PFR0_EL1, AdvSIMD, IMP, CAP_HWCAP, KERNEL_HWCAP_ASIMD),
HWCAP_CAP(ID_AA64PFR0_EL1, AdvSIMD, FP16, CAP_HWCAP, KERNEL_HWCAP_ASIMDHP),
HWCAP_CAP(ID_AA64PFR0_EL1, DIT, IMP, CAP_HWCAP, KERNEL_HWCAP_DIT),
+ HWCAP_CAP(ID_AA64PFR2_EL1, FPMR, IMP, CAP_HWCAP, KERNEL_HWCAP_FPMR),
HWCAP_CAP(ID_AA64ISAR1_EL1, DPB, IMP, CAP_HWCAP, KERNEL_HWCAP_DCPOP),
HWCAP_CAP(ID_AA64ISAR1_EL1, DPB, DPB2, CAP_HWCAP, KERNEL_HWCAP_DCPODP),
HWCAP_CAP(ID_AA64ISAR1_EL1, JSCVT, IMP, CAP_HWCAP, KERNEL_HWCAP_JSCVT),
@@ -2835,6 +2958,8 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
HWCAP_CAP(ID_AA64ISAR1_EL1, BF16, EBF16, CAP_HWCAP, KERNEL_HWCAP_EBF16),
HWCAP_CAP(ID_AA64ISAR1_EL1, DGH, IMP, CAP_HWCAP, KERNEL_HWCAP_DGH),
HWCAP_CAP(ID_AA64ISAR1_EL1, I8MM, IMP, CAP_HWCAP, KERNEL_HWCAP_I8MM),
+ HWCAP_CAP(ID_AA64ISAR2_EL1, LUT, IMP, CAP_HWCAP, KERNEL_HWCAP_LUT),
+ HWCAP_CAP(ID_AA64ISAR3_EL1, FAMINMAX, IMP, CAP_HWCAP, KERNEL_HWCAP_FAMINMAX),
HWCAP_CAP(ID_AA64MMFR2_EL1, AT, IMP, CAP_HWCAP, KERNEL_HWCAP_USCAT),
#ifdef CONFIG_ARM64_SVE
HWCAP_CAP(ID_AA64PFR0_EL1, SVE, IMP, CAP_HWCAP, KERNEL_HWCAP_SVE),
@@ -2875,6 +3000,7 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
#ifdef CONFIG_ARM64_SME
HWCAP_CAP(ID_AA64PFR1_EL1, SME, IMP, CAP_HWCAP, KERNEL_HWCAP_SME),
HWCAP_CAP(ID_AA64SMFR0_EL1, FA64, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_FA64),
+ HWCAP_CAP(ID_AA64SMFR0_EL1, LUTv2, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_LUTV2),
HWCAP_CAP(ID_AA64SMFR0_EL1, SMEver, SME2p1, CAP_HWCAP, KERNEL_HWCAP_SME2P1),
HWCAP_CAP(ID_AA64SMFR0_EL1, SMEver, SME2, CAP_HWCAP, KERNEL_HWCAP_SME2),
HWCAP_CAP(ID_AA64SMFR0_EL1, I16I64, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_I16I64),
@@ -2882,12 +3008,23 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
HWCAP_CAP(ID_AA64SMFR0_EL1, I16I32, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_I16I32),
HWCAP_CAP(ID_AA64SMFR0_EL1, B16B16, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_B16B16),
HWCAP_CAP(ID_AA64SMFR0_EL1, F16F16, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_F16F16),
+ HWCAP_CAP(ID_AA64SMFR0_EL1, F8F16, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_F8F16),
+ HWCAP_CAP(ID_AA64SMFR0_EL1, F8F32, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_F8F32),
HWCAP_CAP(ID_AA64SMFR0_EL1, I8I32, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_I8I32),
HWCAP_CAP(ID_AA64SMFR0_EL1, F16F32, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_F16F32),
HWCAP_CAP(ID_AA64SMFR0_EL1, B16F32, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_B16F32),
HWCAP_CAP(ID_AA64SMFR0_EL1, BI32I32, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_BI32I32),
HWCAP_CAP(ID_AA64SMFR0_EL1, F32F32, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_F32F32),
+ HWCAP_CAP(ID_AA64SMFR0_EL1, SF8FMA, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SF8FMA),
+ HWCAP_CAP(ID_AA64SMFR0_EL1, SF8DP4, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SF8DP4),
+ HWCAP_CAP(ID_AA64SMFR0_EL1, SF8DP2, IMP, CAP_HWCAP, KERNEL_HWCAP_SME_SF8DP2),
#endif /* CONFIG_ARM64_SME */
+ HWCAP_CAP(ID_AA64FPFR0_EL1, F8CVT, IMP, CAP_HWCAP, KERNEL_HWCAP_F8CVT),
+ HWCAP_CAP(ID_AA64FPFR0_EL1, F8FMA, IMP, CAP_HWCAP, KERNEL_HWCAP_F8FMA),
+ HWCAP_CAP(ID_AA64FPFR0_EL1, F8DP4, IMP, CAP_HWCAP, KERNEL_HWCAP_F8DP4),
+ HWCAP_CAP(ID_AA64FPFR0_EL1, F8DP2, IMP, CAP_HWCAP, KERNEL_HWCAP_F8DP2),
+ HWCAP_CAP(ID_AA64FPFR0_EL1, F8E4M3, IMP, CAP_HWCAP, KERNEL_HWCAP_F8E4M3),
+ HWCAP_CAP(ID_AA64FPFR0_EL1, F8E5M2, IMP, CAP_HWCAP, KERNEL_HWCAP_F8E5M2),
{},
};
@@ -3052,13 +3189,9 @@ static void __init enable_cpu_capabilities(u16 scope_mask)
boot_scope = !!(scope_mask & SCOPE_BOOT_CPU);
for (i = 0; i < ARM64_NCAPS; i++) {
- unsigned int num;
-
caps = cpucap_ptrs[i];
- if (!caps || !(caps->type & scope_mask))
- continue;
- num = caps->capability;
- if (!cpus_have_cap(num))
+ if (!caps || !(caps->type & scope_mask) ||
+ !cpus_have_cap(caps->capability))
continue;
if (boot_scope && caps->cpu_enable)
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index 47043c0d95ec..09eeaa24d456 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -128,6 +128,21 @@ static const char *const hwcap_str[] = {
[KERNEL_HWCAP_SVE_B16B16] = "sveb16b16",
[KERNEL_HWCAP_LRCPC3] = "lrcpc3",
[KERNEL_HWCAP_LSE128] = "lse128",
+ [KERNEL_HWCAP_FPMR] = "fpmr",
+ [KERNEL_HWCAP_LUT] = "lut",
+ [KERNEL_HWCAP_FAMINMAX] = "faminmax",
+ [KERNEL_HWCAP_F8CVT] = "f8cvt",
+ [KERNEL_HWCAP_F8FMA] = "f8fma",
+ [KERNEL_HWCAP_F8DP4] = "f8dp4",
+ [KERNEL_HWCAP_F8DP2] = "f8dp2",
+ [KERNEL_HWCAP_F8E4M3] = "f8e4m3",
+ [KERNEL_HWCAP_F8E5M2] = "f8e5m2",
+ [KERNEL_HWCAP_SME_LUTV2] = "smelutv2",
+ [KERNEL_HWCAP_SME_F8F16] = "smef8f16",
+ [KERNEL_HWCAP_SME_F8F32] = "smef8f32",
+ [KERNEL_HWCAP_SME_SF8FMA] = "smesf8fma",
+ [KERNEL_HWCAP_SME_SF8DP4] = "smesf8dp4",
+ [KERNEL_HWCAP_SME_SF8DP2] = "smesf8dp2",
};
#ifdef CONFIG_COMPAT
@@ -443,14 +458,18 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
info->reg_id_aa64isar0 = read_cpuid(ID_AA64ISAR0_EL1);
info->reg_id_aa64isar1 = read_cpuid(ID_AA64ISAR1_EL1);
info->reg_id_aa64isar2 = read_cpuid(ID_AA64ISAR2_EL1);
+ info->reg_id_aa64isar3 = read_cpuid(ID_AA64ISAR3_EL1);
info->reg_id_aa64mmfr0 = read_cpuid(ID_AA64MMFR0_EL1);
info->reg_id_aa64mmfr1 = read_cpuid(ID_AA64MMFR1_EL1);
info->reg_id_aa64mmfr2 = read_cpuid(ID_AA64MMFR2_EL1);
info->reg_id_aa64mmfr3 = read_cpuid(ID_AA64MMFR3_EL1);
+ info->reg_id_aa64mmfr4 = read_cpuid(ID_AA64MMFR4_EL1);
info->reg_id_aa64pfr0 = read_cpuid(ID_AA64PFR0_EL1);
info->reg_id_aa64pfr1 = read_cpuid(ID_AA64PFR1_EL1);
+ info->reg_id_aa64pfr2 = read_cpuid(ID_AA64PFR2_EL1);
info->reg_id_aa64zfr0 = read_cpuid(ID_AA64ZFR0_EL1);
info->reg_id_aa64smfr0 = read_cpuid(ID_AA64SMFR0_EL1);
+ info->reg_id_aa64fpfr0 = read_cpuid(ID_AA64FPFR0_EL1);
if (id_aa64pfr1_mte(info->reg_id_aa64pfr1))
info->reg_gmid = read_cpuid(GMID_EL1);
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index 0228001347be..9afcc690fe73 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -103,7 +103,7 @@ static int __init set_permissions(pte_t *ptep, unsigned long addr, void *data)
{
struct set_perm_data *spd = data;
const efi_memory_desc_t *md = spd->md;
- pte_t pte = READ_ONCE(*ptep);
+ pte_t pte = __ptep_get(ptep);
if (md->attribute & EFI_MEMORY_RO)
pte = set_pte_bit(pte, __pgprot(PTE_RDONLY));
@@ -111,7 +111,7 @@ static int __init set_permissions(pte_t *ptep, unsigned long addr, void *data)
pte = set_pte_bit(pte, __pgprot(PTE_PXN));
else if (system_supports_bti_kernel() && spd->has_bti)
pte = set_pte_bit(pte, __pgprot(PTE_GP));
- set_pte(ptep, pte);
+ __set_pte(ptep, pte);
return 0;
}
diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
index 0fc94207e69a..b77a15955f28 100644
--- a/arch/arm64/kernel/entry-common.c
+++ b/arch/arm64/kernel/entry-common.c
@@ -10,6 +10,7 @@
#include <linux/linkage.h>
#include <linux/lockdep.h>
#include <linux/ptrace.h>
+#include <linux/resume_user_mode.h>
#include <linux/sched.h>
#include <linux/sched/debug.h>
#include <linux/thread_info.h>
@@ -126,16 +127,49 @@ static __always_inline void __exit_to_user_mode(void)
lockdep_hardirqs_on(CALLER_ADDR0);
}
+static void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags)
+{
+ do {
+ local_irq_enable();
+
+ if (thread_flags & _TIF_NEED_RESCHED)
+ schedule();
+
+ if (thread_flags & _TIF_UPROBE)
+ uprobe_notify_resume(regs);
+
+ if (thread_flags & _TIF_MTE_ASYNC_FAULT) {
+ clear_thread_flag(TIF_MTE_ASYNC_FAULT);
+ send_sig_fault(SIGSEGV, SEGV_MTEAERR,
+ (void __user *)NULL, current);
+ }
+
+ if (thread_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
+ do_signal(regs);
+
+ if (thread_flags & _TIF_NOTIFY_RESUME)
+ resume_user_mode_work(regs);
+
+ if (thread_flags & _TIF_FOREIGN_FPSTATE)
+ fpsimd_restore_current_state();
+
+ local_irq_disable();
+ thread_flags = read_thread_flags();
+ } while (thread_flags & _TIF_WORK_MASK);
+}
+
static __always_inline void exit_to_user_mode_prepare(struct pt_regs *regs)
{
unsigned long flags;
- local_daif_mask();
+ local_irq_disable();
flags = read_thread_flags();
if (unlikely(flags & _TIF_WORK_MASK))
do_notify_resume(regs, flags);
+ local_daif_mask();
+
lockdep_sys_exit();
}
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index f27acca550d5..ebb0158997ca 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -359,6 +359,9 @@ static void task_fpsimd_load(void)
WARN_ON(preemptible());
WARN_ON(test_thread_flag(TIF_KERNEL_FPSTATE));
+ if (system_supports_fpmr())
+ write_sysreg_s(current->thread.uw.fpmr, SYS_FPMR);
+
if (system_supports_sve() || system_supports_sme()) {
switch (current->thread.fp_type) {
case FP_STATE_FPSIMD:
@@ -446,6 +449,9 @@ static void fpsimd_save_user_state(void)
if (test_thread_flag(TIF_FOREIGN_FPSTATE))
return;
+ if (system_supports_fpmr())
+ *(last->fpmr) = read_sysreg_s(SYS_FPMR);
+
/*
* If a task is in a syscall the ABI allows us to only
* preserve the state shared with FPSIMD so don't bother
@@ -688,6 +694,12 @@ static void sve_to_fpsimd(struct task_struct *task)
}
}
+void cpu_enable_fpmr(const struct arm64_cpu_capabilities *__always_unused p)
+{
+ write_sysreg_s(read_sysreg_s(SYS_SCTLR_EL1) | SCTLR_EL1_EnFPM_MASK,
+ SYS_SCTLR_EL1);
+}
+
#ifdef CONFIG_ARM64_SVE
/*
* Call __sve_free() directly only if you know task can't be scheduled
@@ -1134,6 +1146,8 @@ void cpu_enable_sve(const struct arm64_cpu_capabilities *__always_unused p)
{
write_sysreg(read_sysreg(CPACR_EL1) | CPACR_EL1_ZEN_EL1EN, CPACR_EL1);
isb();
+
+ write_sysreg_s(0, SYS_ZCR_EL1);
}
void __init sve_setup(void)
@@ -1245,6 +1259,9 @@ void cpu_enable_sme(const struct arm64_cpu_capabilities *__always_unused p)
write_sysreg(read_sysreg(CPACR_EL1) | CPACR_EL1_SMEN_EL1EN, CPACR_EL1);
isb();
+ /* Ensure all bits in SMCR are set to known values */
+ write_sysreg_s(0, SYS_SMCR_EL1);
+
/* Allow EL0 to access TPIDR2 */
write_sysreg(read_sysreg(SCTLR_EL1) | SCTLR_ELx_ENTP2, SCTLR_EL1);
isb();
@@ -1696,6 +1713,7 @@ static void fpsimd_bind_task_to_cpu(void)
last->sve_vl = task_get_sve_vl(current);
last->sme_vl = task_get_sme_vl(current);
last->svcr = &current->thread.svcr;
+ last->fpmr = &current->thread.uw.fpmr;
last->fp_type = &current->thread.fp_type;
last->to_save = FP_STATE_CURRENT;
current->thread.fpsimd_cpu = smp_processor_id();
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index cab7f91949d8..06234c3a15f3 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -80,28 +80,42 @@
* x19 primary_entry() .. start_kernel() whether we entered with the MMU on
* x20 primary_entry() .. __primary_switch() CPU boot mode
* x21 primary_entry() .. start_kernel() FDT pointer passed at boot in x0
- * x22 create_idmap() .. start_kernel() ID map VA of the DT blob
- * x23 primary_entry() .. start_kernel() physical misalignment/KASLR offset
- * x24 __primary_switch() linear map KASLR seed
- * x25 primary_entry() .. start_kernel() supported VA size
- * x28 create_idmap() callee preserved temp register
*/
SYM_CODE_START(primary_entry)
bl record_mmu_state
bl preserve_boot_args
- bl create_idmap
+
+ adrp x1, early_init_stack
+ mov sp, x1
+ mov x29, xzr
+ adrp x0, init_idmap_pg_dir
+ mov x1, xzr
+ bl __pi_create_init_idmap
+
+ /*
+ * If the page tables have been populated with non-cacheable
+ * accesses (MMU disabled), invalidate those tables again to
+ * remove any speculatively loaded cache lines.
+ */
+ cbnz x19, 0f
+ dmb sy
+ mov x1, x0 // end of used region
+ adrp x0, init_idmap_pg_dir
+ adr_l x2, dcache_inval_poc
+ blr x2
+ b 1f
/*
* If we entered with the MMU and caches on, clean the ID mapped part
* of the primary boot code to the PoC so we can safely execute it with
* the MMU off.
*/
- cbz x19, 0f
- adrp x0, __idmap_text_start
+0: adrp x0, __idmap_text_start
adr_l x1, __idmap_text_end
adr_l x2, dcache_clean_poc
blr x2
-0: mov x0, x19
+
+1: mov x0, x19
bl init_kernel_el // w0=cpu_boot_mode
mov x20, x0
@@ -111,14 +125,6 @@ SYM_CODE_START(primary_entry)
* On return, the CPU will be ready for the MMU to be turned on and
* the TCR will have been set.
*/
-#if VA_BITS > 48
- mrs_s x0, SYS_ID_AA64MMFR2_EL1
- tst x0, ID_AA64MMFR2_EL1_VARange_MASK
- mov x0, #VA_BITS
- mov x25, #VA_BITS_MIN
- csel x25, x25, x0, eq
- mov x0, x25
-#endif
bl __cpu_setup // initialise processor
b __primary_switch
SYM_CODE_END(primary_entry)
@@ -177,267 +183,6 @@ SYM_CODE_START_LOCAL(preserve_boot_args)
ret
SYM_CODE_END(preserve_boot_args)
-SYM_FUNC_START_LOCAL(clear_page_tables)
- /*
- * Clear the init page tables.
- */
- adrp x0, init_pg_dir
- adrp x1, init_pg_end
- sub x2, x1, x0
- mov x1, xzr
- b __pi_memset // tail call
-SYM_FUNC_END(clear_page_tables)
-
-/*
- * Macro to populate page table entries, these entries can be pointers to the next level
- * or last level entries pointing to physical memory.
- *
- * tbl: page table address
- * rtbl: pointer to page table or physical memory
- * index: start index to write
- * eindex: end index to write - [index, eindex] written to
- * flags: flags for pagetable entry to or in
- * inc: increment to rtbl between each entry
- * tmp1: temporary variable
- *
- * Preserves: tbl, eindex, flags, inc
- * Corrupts: index, tmp1
- * Returns: rtbl
- */
- .macro populate_entries, tbl, rtbl, index, eindex, flags, inc, tmp1
-.Lpe\@: phys_to_pte \tmp1, \rtbl
- orr \tmp1, \tmp1, \flags // tmp1 = table entry
- str \tmp1, [\tbl, \index, lsl #3]
- add \rtbl, \rtbl, \inc // rtbl = pa next level
- add \index, \index, #1
- cmp \index, \eindex
- b.ls .Lpe\@
- .endm
-
-/*
- * Compute indices of table entries from virtual address range. If multiple entries
- * were needed in the previous page table level then the next page table level is assumed
- * to be composed of multiple pages. (This effectively scales the end index).
- *
- * vstart: virtual address of start of range
- * vend: virtual address of end of range - we map [vstart, vend]
- * shift: shift used to transform virtual address into index
- * order: #imm 2log(number of entries in page table)
- * istart: index in table corresponding to vstart
- * iend: index in table corresponding to vend
- * count: On entry: how many extra entries were required in previous level, scales
- * our end index.
- * On exit: returns how many extra entries required for next page table level
- *
- * Preserves: vstart, vend
- * Returns: istart, iend, count
- */
- .macro compute_indices, vstart, vend, shift, order, istart, iend, count
- ubfx \istart, \vstart, \shift, \order
- ubfx \iend, \vend, \shift, \order
- add \iend, \iend, \count, lsl \order
- sub \count, \iend, \istart
- .endm
-
-/*
- * Map memory for specified virtual address range. Each level of page table needed supports
- * multiple entries. If a level requires n entries the next page table level is assumed to be
- * formed from n pages.
- *
- * tbl: location of page table
- * rtbl: address to be used for first level page table entry (typically tbl + PAGE_SIZE)
- * vstart: virtual address of start of range
- * vend: virtual address of end of range - we map [vstart, vend - 1]
- * flags: flags to use to map last level entries
- * phys: physical address corresponding to vstart - physical memory is contiguous
- * order: #imm 2log(number of entries in PGD table)
- *
- * If extra_shift is set, an extra level will be populated if the end address does
- * not fit in 'extra_shift' bits. This assumes vend is in the TTBR0 range.
- *
- * Temporaries: istart, iend, tmp, count, sv - these need to be different registers
- * Preserves: vstart, flags
- * Corrupts: tbl, rtbl, vend, istart, iend, tmp, count, sv
- */
- .macro map_memory, tbl, rtbl, vstart, vend, flags, phys, order, istart, iend, tmp, count, sv, extra_shift
- sub \vend, \vend, #1
- add \rtbl, \tbl, #PAGE_SIZE
- mov \count, #0
-
- .ifnb \extra_shift
- tst \vend, #~((1 << (\extra_shift)) - 1)
- b.eq .L_\@
- compute_indices \vstart, \vend, #\extra_shift, #(PAGE_SHIFT - 3), \istart, \iend, \count
- mov \sv, \rtbl
- populate_entries \tbl, \rtbl, \istart, \iend, #PMD_TYPE_TABLE, #PAGE_SIZE, \tmp
- mov \tbl, \sv
- .endif
-.L_\@:
- compute_indices \vstart, \vend, #PGDIR_SHIFT, #\order, \istart, \iend, \count
- mov \sv, \rtbl
- populate_entries \tbl, \rtbl, \istart, \iend, #PMD_TYPE_TABLE, #PAGE_SIZE, \tmp
- mov \tbl, \sv
-
-#if SWAPPER_PGTABLE_LEVELS > 3
- compute_indices \vstart, \vend, #PUD_SHIFT, #(PAGE_SHIFT - 3), \istart, \iend, \count
- mov \sv, \rtbl
- populate_entries \tbl, \rtbl, \istart, \iend, #PMD_TYPE_TABLE, #PAGE_SIZE, \tmp
- mov \tbl, \sv
-#endif
-
-#if SWAPPER_PGTABLE_LEVELS > 2
- compute_indices \vstart, \vend, #SWAPPER_TABLE_SHIFT, #(PAGE_SHIFT - 3), \istart, \iend, \count
- mov \sv, \rtbl
- populate_entries \tbl, \rtbl, \istart, \iend, #PMD_TYPE_TABLE, #PAGE_SIZE, \tmp
- mov \tbl, \sv
-#endif
-
- compute_indices \vstart, \vend, #SWAPPER_BLOCK_SHIFT, #(PAGE_SHIFT - 3), \istart, \iend, \count
- bic \rtbl, \phys, #SWAPPER_BLOCK_SIZE - 1
- populate_entries \tbl, \rtbl, \istart, \iend, \flags, #SWAPPER_BLOCK_SIZE, \tmp
- .endm
-
-/*
- * Remap a subregion created with the map_memory macro with modified attributes
- * or output address. The entire remapped region must have been covered in the
- * invocation of map_memory.
- *
- * x0: last level table address (returned in first argument to map_memory)
- * x1: start VA of the existing mapping
- * x2: start VA of the region to update
- * x3: end VA of the region to update (exclusive)
- * x4: start PA associated with the region to update
- * x5: attributes to set on the updated region
- * x6: order of the last level mappings
- */
-SYM_FUNC_START_LOCAL(remap_region)
- sub x3, x3, #1 // make end inclusive
-
- // Get the index offset for the start of the last level table
- lsr x1, x1, x6
- bfi x1, xzr, #0, #PAGE_SHIFT - 3
-
- // Derive the start and end indexes into the last level table
- // associated with the provided region
- lsr x2, x2, x6
- lsr x3, x3, x6
- sub x2, x2, x1
- sub x3, x3, x1
-
- mov x1, #1
- lsl x6, x1, x6 // block size at this level
-
- populate_entries x0, x4, x2, x3, x5, x6, x7
- ret
-SYM_FUNC_END(remap_region)
-
-SYM_FUNC_START_LOCAL(create_idmap)
- mov x28, lr
- /*
- * The ID map carries a 1:1 mapping of the physical address range
- * covered by the loaded image, which could be anywhere in DRAM. This
- * means that the required size of the VA (== PA) space is decided at
- * boot time, and could be more than the configured size of the VA
- * space for ordinary kernel and user space mappings.
- *
- * There are three cases to consider here:
- * - 39 <= VA_BITS < 48, and the ID map needs up to 48 VA bits to cover
- * the placement of the image. In this case, we configure one extra
- * level of translation on the fly for the ID map only. (This case
- * also covers 42-bit VA/52-bit PA on 64k pages).
- *
- * - VA_BITS == 48, and the ID map needs more than 48 VA bits. This can
- * only happen when using 64k pages, in which case we need to extend
- * the root level table rather than add a level. Note that we can
- * treat this case as 'always extended' as long as we take care not
- * to program an unsupported T0SZ value into the TCR register.
- *
- * - Combinations that would require two additional levels of
- * translation are not supported, e.g., VA_BITS==36 on 16k pages, or
- * VA_BITS==39/4k pages with 5-level paging, where the input address
- * requires more than 47 or 48 bits, respectively.
- */
-#if (VA_BITS < 48)
-#define IDMAP_PGD_ORDER (VA_BITS - PGDIR_SHIFT)
-#define EXTRA_SHIFT (PGDIR_SHIFT + PAGE_SHIFT - 3)
-
- /*
- * If VA_BITS < 48, we have to configure an additional table level.
- * First, we have to verify our assumption that the current value of
- * VA_BITS was chosen such that all translation levels are fully
- * utilised, and that lowering T0SZ will always result in an additional
- * translation level to be configured.
- */
-#if VA_BITS != EXTRA_SHIFT
-#error "Mismatch between VA_BITS and page size/number of translation levels"
-#endif
-#else
-#define IDMAP_PGD_ORDER (PHYS_MASK_SHIFT - PGDIR_SHIFT)
-#define EXTRA_SHIFT
- /*
- * If VA_BITS == 48, we don't have to configure an additional
- * translation level, but the top-level table has more entries.
- */
-#endif
- adrp x0, init_idmap_pg_dir
- adrp x3, _text
- adrp x6, _end + MAX_FDT_SIZE + SWAPPER_BLOCK_SIZE
- mov_q x7, SWAPPER_RX_MMUFLAGS
-
- map_memory x0, x1, x3, x6, x7, x3, IDMAP_PGD_ORDER, x10, x11, x12, x13, x14, EXTRA_SHIFT
-
- /* Remap the kernel page tables r/w in the ID map */
- adrp x1, _text
- adrp x2, init_pg_dir
- adrp x3, init_pg_end
- bic x4, x2, #SWAPPER_BLOCK_SIZE - 1
- mov_q x5, SWAPPER_RW_MMUFLAGS
- mov x6, #SWAPPER_BLOCK_SHIFT
- bl remap_region
-
- /* Remap the FDT after the kernel image */
- adrp x1, _text
- adrp x22, _end + SWAPPER_BLOCK_SIZE
- bic x2, x22, #SWAPPER_BLOCK_SIZE - 1
- bfi x22, x21, #0, #SWAPPER_BLOCK_SHIFT // remapped FDT address
- add x3, x2, #MAX_FDT_SIZE + SWAPPER_BLOCK_SIZE
- bic x4, x21, #SWAPPER_BLOCK_SIZE - 1
- mov_q x5, SWAPPER_RW_MMUFLAGS
- mov x6, #SWAPPER_BLOCK_SHIFT
- bl remap_region
-
- /*
- * Since the page tables have been populated with non-cacheable
- * accesses (MMU disabled), invalidate those tables again to
- * remove any speculatively loaded cache lines.
- */
- cbnz x19, 0f // skip cache invalidation if MMU is on
- dmb sy
-
- adrp x0, init_idmap_pg_dir
- adrp x1, init_idmap_pg_end
- bl dcache_inval_poc
-0: ret x28
-SYM_FUNC_END(create_idmap)
-
-SYM_FUNC_START_LOCAL(create_kernel_mapping)
- adrp x0, init_pg_dir
- mov_q x5, KIMAGE_VADDR // compile time __va(_text)
-#ifdef CONFIG_RELOCATABLE
- add x5, x5, x23 // add KASLR displacement
-#endif
- adrp x6, _end // runtime __pa(_end)
- adrp x3, _text // runtime __pa(_text)
- sub x6, x6, x3 // _end - _text
- add x6, x6, x5 // runtime __va(_end)
- mov_q x7, SWAPPER_RW_MMUFLAGS
-
- map_memory x0, x1, x5, x6, x7, x3, (VA_BITS - PGDIR_SHIFT), x10, x11, x12, x13, x14
-
- dsb ishst // sync with page table walker
- ret
-SYM_FUNC_END(create_kernel_mapping)
-
/*
* Initialize CPU registers with task-specific and cpu-specific context.
*
@@ -489,34 +234,9 @@ SYM_FUNC_START_LOCAL(__primary_switched)
mov x0, x20
bl set_cpu_boot_mode_flag
- // Clear BSS
- adr_l x0, __bss_start
- mov x1, xzr
- adr_l x2, __bss_stop
- sub x2, x2, x0
- bl __pi_memset
- dsb ishst // Make zero page visible to PTW
-
-#if VA_BITS > 48
- adr_l x8, vabits_actual // Set this early so KASAN early init
- str x25, [x8] // ... observes the correct value
- dc civac, x8 // Make visible to booting secondaries
-#endif
-
-#ifdef CONFIG_RANDOMIZE_BASE
- adrp x5, memstart_offset_seed // Save KASLR linear map seed
- strh w24, [x5, :lo12:memstart_offset_seed]
-#endif
#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
bl kasan_early_init
#endif
- mov x0, x21 // pass FDT address in x0
- bl early_fdt_map // Try mapping the FDT early
- mov x0, x20 // pass the full boot status
- bl init_feature_override // Parse cpu feature overrides
-#ifdef CONFIG_UNWIND_PATCH_PAC_INTO_SCS
- bl scs_patch_vmlinux
-#endif
mov x0, x20
bl finalise_el2 // Prefer VHE if possible
ldp x29, x30, [sp], #16
@@ -571,6 +291,21 @@ SYM_INNER_LABEL(init_el2, SYM_L_LOCAL)
blr x2
0:
mov_q x0, HCR_HOST_NVHE_FLAGS
+
+ /*
+ * Compliant CPUs advertise their VHE-onlyness with
+ * ID_AA64MMFR4_EL1.E2H0 < 0. HCR_EL2.E2H can be
+ * RES1 in that case. Publish the E2H bit early so that
+ * it can be picked up by the init_el2_state macro.
+ *
+ * Fruity CPUs seem to have HCR_EL2.E2H set to RAO/WI, but
+ * don't advertise it (they predate this relaxation).
+ */
+ mrs_s x1, SYS_ID_AA64MMFR4_EL1
+ tbz x1, #(ID_AA64MMFR4_EL1_E2H0_SHIFT + ID_AA64MMFR4_EL1_E2H0_WIDTH - 1), 1f
+
+ orr x0, x0, #HCR_E2H
+1:
msr hcr_el2, x0
isb
@@ -583,26 +318,21 @@ SYM_INNER_LABEL(init_el2, SYM_L_LOCAL)
mov_q x1, INIT_SCTLR_EL1_MMU_OFF
- /*
- * Fruity CPUs seem to have HCR_EL2.E2H set to RES1,
- * making it impossible to start in nVHE mode. Is that
- * compliant with the architecture? Absolutely not!
- */
mrs x0, hcr_el2
and x0, x0, #HCR_E2H
- cbz x0, 1f
+ cbz x0, 2f
/* Set a sane SCTLR_EL1, the VHE way */
pre_disable_mmu_workaround
msr_s SYS_SCTLR_EL12, x1
mov x2, #BOOT_CPU_FLAG_E2H
- b 2f
+ b 3f
-1:
+2:
pre_disable_mmu_workaround
msr sctlr_el1, x1
mov x2, xzr
-2:
+3:
__init_el2_nvhe_prepare_eret
mov w0, #BOOT_CPU_MODE_EL2
@@ -643,10 +373,13 @@ SYM_FUNC_START_LOCAL(secondary_startup)
* Common entry point for secondary CPUs.
*/
mov x20, x0 // preserve boot mode
+
+#ifdef CONFIG_ARM64_VA_BITS_52
+alternative_if ARM64_HAS_VA52
bl __cpu_secondary_check52bitva
-#if VA_BITS > 48
- ldr_l x0, vabits_actual
+alternative_else_nop_endif
#endif
+
bl __cpu_setup // initialise processor
adrp x1, swapper_pg_dir
adrp x2, idmap_pg_dir
@@ -749,15 +482,18 @@ SYM_FUNC_START(__enable_mmu)
ret
SYM_FUNC_END(__enable_mmu)
+#ifdef CONFIG_ARM64_VA_BITS_52
SYM_FUNC_START(__cpu_secondary_check52bitva)
-#if VA_BITS > 48
- ldr_l x0, vabits_actual
- cmp x0, #52
- b.ne 2f
-
+#ifndef CONFIG_ARM64_LPA2
mrs_s x0, SYS_ID_AA64MMFR2_EL1
and x0, x0, ID_AA64MMFR2_EL1_VARange_MASK
cbnz x0, 2f
+#else
+ mrs x0, id_aa64mmfr0_el1
+ sbfx x0, x0, #ID_AA64MMFR0_EL1_TGRAN_SHIFT, 4
+ cmp x0, #ID_AA64MMFR0_EL1_TGRAN_LPA2
+ b.ge 2f
+#endif
update_early_cpu_boot_status \
CPU_STUCK_IN_KERNEL | CPU_STUCK_REASON_52_BIT_VA, x0, x1
@@ -765,9 +501,9 @@ SYM_FUNC_START(__cpu_secondary_check52bitva)
wfi
b 1b
-#endif
2: ret
SYM_FUNC_END(__cpu_secondary_check52bitva)
+#endif
SYM_FUNC_START_LOCAL(__no_granule_support)
/* Indicate that this CPU can't boot and is stuck in the kernel */
@@ -779,123 +515,18 @@ SYM_FUNC_START_LOCAL(__no_granule_support)
b 1b
SYM_FUNC_END(__no_granule_support)
-#ifdef CONFIG_RELOCATABLE
-SYM_FUNC_START_LOCAL(__relocate_kernel)
- /*
- * Iterate over each entry in the relocation table, and apply the
- * relocations in place.
- */
- adr_l x9, __rela_start
- adr_l x10, __rela_end
- mov_q x11, KIMAGE_VADDR // default virtual offset
- add x11, x11, x23 // actual virtual offset
-
-0: cmp x9, x10
- b.hs 1f
- ldp x12, x13, [x9], #24
- ldr x14, [x9, #-8]
- cmp w13, #R_AARCH64_RELATIVE
- b.ne 0b
- add x14, x14, x23 // relocate
- str x14, [x12, x23]
- b 0b
-
-1:
-#ifdef CONFIG_RELR
- /*
- * Apply RELR relocations.
- *
- * RELR is a compressed format for storing relative relocations. The
- * encoded sequence of entries looks like:
- * [ AAAAAAAA BBBBBBB1 BBBBBBB1 ... AAAAAAAA BBBBBB1 ... ]
- *
- * i.e. start with an address, followed by any number of bitmaps. The
- * address entry encodes 1 relocation. The subsequent bitmap entries
- * encode up to 63 relocations each, at subsequent offsets following
- * the last address entry.
- *
- * The bitmap entries must have 1 in the least significant bit. The
- * assumption here is that an address cannot have 1 in lsb. Odd
- * addresses are not supported. Any odd addresses are stored in the RELA
- * section, which is handled above.
- *
- * Excluding the least significant bit in the bitmap, each non-zero
- * bit in the bitmap represents a relocation to be applied to
- * a corresponding machine word that follows the base address
- * word. The second least significant bit represents the machine
- * word immediately following the initial address, and each bit
- * that follows represents the next word, in linear order. As such,
- * a single bitmap can encode up to 63 relocations in a 64-bit object.
- *
- * In this implementation we store the address of the next RELR table
- * entry in x9, the address being relocated by the current address or
- * bitmap entry in x13 and the address being relocated by the current
- * bit in x14.
- */
- adr_l x9, __relr_start
- adr_l x10, __relr_end
-
-2: cmp x9, x10
- b.hs 7f
- ldr x11, [x9], #8
- tbnz x11, #0, 3f // branch to handle bitmaps
- add x13, x11, x23
- ldr x12, [x13] // relocate address entry
- add x12, x12, x23
- str x12, [x13], #8 // adjust to start of bitmap
- b 2b
-
-3: mov x14, x13
-4: lsr x11, x11, #1
- cbz x11, 6f
- tbz x11, #0, 5f // skip bit if not set
- ldr x12, [x14] // relocate bit
- add x12, x12, x23
- str x12, [x14]
-
-5: add x14, x14, #8 // move to next bit's address
- b 4b
-
-6: /*
- * Move to the next bitmap's address. 8 is the word size, and 63 is the
- * number of significant bits in a bitmap entry.
- */
- add x13, x13, #(8 * 63)
- b 2b
-
-7:
-#endif
- ret
-
-SYM_FUNC_END(__relocate_kernel)
-#endif
-
SYM_FUNC_START_LOCAL(__primary_switch)
adrp x1, reserved_pg_dir
adrp x2, init_idmap_pg_dir
bl __enable_mmu
-#ifdef CONFIG_RELOCATABLE
- adrp x23, KERNEL_START
- and x23, x23, MIN_KIMG_ALIGN - 1
-#ifdef CONFIG_RANDOMIZE_BASE
- mov x0, x22
- adrp x1, init_pg_end
+
+ adrp x1, early_init_stack
mov sp, x1
mov x29, xzr
- bl __pi_kaslr_early_init
- and x24, x0, #SZ_2M - 1 // capture memstart offset seed
- bic x0, x0, #SZ_2M - 1
- orr x23, x23, x0 // record kernel offset
-#endif
-#endif
- bl clear_page_tables
- bl create_kernel_mapping
+ mov x0, x20 // pass the full boot status
+ mov x1, x21 // pass the FDT
+ bl __pi_early_map_kernel // Map and relocate the kernel
- adrp x1, init_pg_dir
- load_ttbr1 x1, x1, x2
-#ifdef CONFIG_RELOCATABLE
- bl __relocate_kernel
-#endif
ldr x8, =__primary_switched
adrp x0, KERNEL_START // __pa(KERNEL_START)
br x8
diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
index 35225632d70a..2f5755192c2b 100644
--- a/arch/arm64/kernel/hw_breakpoint.c
+++ b/arch/arm64/kernel/hw_breakpoint.c
@@ -21,6 +21,7 @@
#include <asm/current.h>
#include <asm/debug-monitors.h>
+#include <asm/esr.h>
#include <asm/hw_breakpoint.h>
#include <asm/traps.h>
#include <asm/cputype.h>
@@ -779,7 +780,7 @@ static int watchpoint_handler(unsigned long addr, unsigned long esr,
* Check that the access type matches.
* 0 => load, otherwise => store
*/
- access = (esr & AARCH64_ESR_ACCESS_MASK) ? HW_BREAKPOINT_W :
+ access = (esr & ESR_ELx_WNR) ? HW_BREAKPOINT_W :
HW_BREAKPOINT_R;
if (!(access & hw_breakpoint_type(wp)))
continue;
diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index 5e4dc72ab1bd..ba4f8f7d6a91 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -36,6 +36,41 @@ PROVIDE(__pi___memcpy = __pi_memcpy);
PROVIDE(__pi___memmove = __pi_memmove);
PROVIDE(__pi___memset = __pi_memset);
+PROVIDE(__pi_id_aa64isar1_override = id_aa64isar1_override);
+PROVIDE(__pi_id_aa64isar2_override = id_aa64isar2_override);
+PROVIDE(__pi_id_aa64mmfr0_override = id_aa64mmfr0_override);
+PROVIDE(__pi_id_aa64mmfr1_override = id_aa64mmfr1_override);
+PROVIDE(__pi_id_aa64mmfr2_override = id_aa64mmfr2_override);
+PROVIDE(__pi_id_aa64pfr0_override = id_aa64pfr0_override);
+PROVIDE(__pi_id_aa64pfr1_override = id_aa64pfr1_override);
+PROVIDE(__pi_id_aa64smfr0_override = id_aa64smfr0_override);
+PROVIDE(__pi_id_aa64zfr0_override = id_aa64zfr0_override);
+PROVIDE(__pi_arm64_sw_feature_override = arm64_sw_feature_override);
+PROVIDE(__pi_arm64_use_ng_mappings = arm64_use_ng_mappings);
+#ifdef CONFIG_CAVIUM_ERRATUM_27456
+PROVIDE(__pi_cavium_erratum_27456_cpus = cavium_erratum_27456_cpus);
+#endif
+PROVIDE(__pi__ctype = _ctype);
+PROVIDE(__pi_memstart_offset_seed = memstart_offset_seed);
+
+PROVIDE(__pi_init_idmap_pg_dir = init_idmap_pg_dir);
+PROVIDE(__pi_init_idmap_pg_end = init_idmap_pg_end);
+PROVIDE(__pi_init_pg_dir = init_pg_dir);
+PROVIDE(__pi_init_pg_end = init_pg_end);
+PROVIDE(__pi_swapper_pg_dir = swapper_pg_dir);
+
+PROVIDE(__pi__text = _text);
+PROVIDE(__pi__stext = _stext);
+PROVIDE(__pi__etext = _etext);
+PROVIDE(__pi___start_rodata = __start_rodata);
+PROVIDE(__pi___inittext_begin = __inittext_begin);
+PROVIDE(__pi___inittext_end = __inittext_end);
+PROVIDE(__pi___initdata_begin = __initdata_begin);
+PROVIDE(__pi___initdata_end = __initdata_end);
+PROVIDE(__pi__data = _data);
+PROVIDE(__pi___bss_start = __bss_start);
+PROVIDE(__pi__end = _end);
+
#ifdef CONFIG_KVM
/*
diff --git a/arch/arm64/kernel/kaslr.c b/arch/arm64/kernel/kaslr.c
index 12c7f3c8ba76..1da3e25f9d9e 100644
--- a/arch/arm64/kernel/kaslr.c
+++ b/arch/arm64/kernel/kaslr.c
@@ -16,9 +16,7 @@ bool __ro_after_init __kaslr_is_enabled = false;
void __init kaslr_init(void)
{
- if (cpuid_feature_extract_unsigned_field(arm64_sw_feature_override.val &
- arm64_sw_feature_override.mask,
- ARM64_SW_FEATURE_OVERRIDE_NOKASLR)) {
+ if (kaslr_disabled_cmdline()) {
pr_info("KASLR disabled on command line\n");
return;
}
diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
index b38aae5b488d..82e2203d86a3 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -255,7 +255,7 @@ void machine_crash_shutdown(struct pt_regs *regs)
pr_info("Starting crashdump kernel...\n");
}
-#ifdef CONFIG_HIBERNATION
+#if defined(CONFIG_CRASH_DUMP) && defined(CONFIG_HIBERNATION)
/*
* To preserve the crash dump kernel image, the relevant memory segments
* should be mapped again around the hibernation.
diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c
index 0e017358f4ba..af1ca875c52c 100644
--- a/arch/arm64/kernel/machine_kexec_file.c
+++ b/arch/arm64/kernel/machine_kexec_file.c
@@ -39,6 +39,7 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image)
return kexec_image_post_load_cleanup_default(image);
}
+#ifdef CONFIG_CRASH_DUMP
static int prepare_elf_headers(void **addr, unsigned long *sz)
{
struct crash_mem *cmem;
@@ -80,6 +81,7 @@ out:
kfree(cmem);
return ret;
}
+#endif
/*
* Tries to add the initrd and DTB to the image. If it is not possible to find
@@ -93,8 +95,8 @@ int load_other_segments(struct kimage *image,
char *cmdline)
{
struct kexec_buf kbuf;
- void *headers, *dtb = NULL;
- unsigned long headers_sz, initrd_load_addr = 0, dtb_len,
+ void *dtb = NULL;
+ unsigned long initrd_load_addr = 0, dtb_len,
orig_segments = image->nr_segments;
int ret = 0;
@@ -102,7 +104,10 @@ int load_other_segments(struct kimage *image,
/* not allocate anything below the kernel */
kbuf.buf_min = kernel_load_addr + kernel_size;
+#ifdef CONFIG_CRASH_DUMP
/* load elf core header */
+ void *headers;
+ unsigned long headers_sz;
if (image->type == KEXEC_TYPE_CRASH) {
ret = prepare_elf_headers(&headers, &headers_sz);
if (ret) {
@@ -130,6 +135,7 @@ int load_other_segments(struct kimage *image,
kexec_dprintk("Loaded elf core header at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
image->elf_load_addr, kbuf.bufsz, kbuf.memsz);
}
+#endif
/* load initrd */
if (initrd) {
diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c
index dd851297596e..47e0be610bb6 100644
--- a/arch/arm64/kernel/module.c
+++ b/arch/arm64/kernel/module.c
@@ -595,7 +595,7 @@ int module_finalize(const Elf_Ehdr *hdr,
if (scs_is_dynamic()) {
s = find_section(hdr, sechdrs, ".init.eh_frame");
if (s)
- scs_patch((void *)s->sh_addr, s->sh_size);
+ __pi_scs_patch((void *)s->sh_addr, s->sh_size);
}
return module_init_ftrace_plt(hdr, sechdrs, me);
diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c
index a41ef3213e1e..dcdcccd40891 100644
--- a/arch/arm64/kernel/mte.c
+++ b/arch/arm64/kernel/mte.c
@@ -67,7 +67,7 @@ int memcmp_pages(struct page *page1, struct page *page2)
/*
* If the page content is identical but at least one of the pages is
* tagged, return non-zero to avoid KSM merging. If only one of the
- * pages is tagged, set_pte_at() may zero or change the tags of the
+ * pages is tagged, __set_ptes() may zero or change the tags of the
* other page via mte_sync_tags().
*/
if (page_mte_tagged(page1) || page_mte_tagged(page2))
diff --git a/arch/arm64/kernel/patching.c b/arch/arm64/kernel/patching.c
index b4835f6d594b..255534930368 100644
--- a/arch/arm64/kernel/patching.c
+++ b/arch/arm64/kernel/patching.c
@@ -105,6 +105,81 @@ noinstr int aarch64_insn_write_literal_u64(void *addr, u64 val)
return ret;
}
+typedef void text_poke_f(void *dst, void *src, size_t patched, size_t len);
+
+static void *__text_poke(text_poke_f func, void *addr, void *src, size_t len)
+{
+ unsigned long flags;
+ size_t patched = 0;
+ size_t size;
+ void *waddr;
+ void *ptr;
+
+ raw_spin_lock_irqsave(&patch_lock, flags);
+
+ while (patched < len) {
+ ptr = addr + patched;
+ size = min_t(size_t, PAGE_SIZE - offset_in_page(ptr),
+ len - patched);
+
+ waddr = patch_map(ptr, FIX_TEXT_POKE0);
+ func(waddr, src, patched, size);
+ patch_unmap(FIX_TEXT_POKE0);
+
+ patched += size;
+ }
+ raw_spin_unlock_irqrestore(&patch_lock, flags);
+
+ flush_icache_range((uintptr_t)addr, (uintptr_t)addr + len);
+
+ return addr;
+}
+
+static void text_poke_memcpy(void *dst, void *src, size_t patched, size_t len)
+{
+ copy_to_kernel_nofault(dst, src + patched, len);
+}
+
+static void text_poke_memset(void *dst, void *src, size_t patched, size_t len)
+{
+ u32 c = *(u32 *)src;
+
+ memset32(dst, c, len / 4);
+}
+
+/**
+ * aarch64_insn_copy - Copy instructions into (an unused part of) RX memory
+ * @dst: address to modify
+ * @src: source of the copy
+ * @len: length to copy
+ *
+ * Useful for JITs to dump new code blocks into unused regions of RX memory.
+ */
+noinstr void *aarch64_insn_copy(void *dst, void *src, size_t len)
+{
+ /* A64 instructions must be word aligned */
+ if ((uintptr_t)dst & 0x3)
+ return NULL;
+
+ return __text_poke(text_poke_memcpy, dst, src, len);
+}
+
+/**
+ * aarch64_insn_set - memset for RX memory regions.
+ * @dst: address to modify
+ * @insn: value to set
+ * @len: length of memory region.
+ *
+ * Useful for JITs to fill regions of RX memory with illegal instructions.
+ */
+noinstr void *aarch64_insn_set(void *dst, u32 insn, size_t len)
+{
+ if ((uintptr_t)dst & 0x3)
+ return NULL;
+
+ return __text_poke(text_poke_memset, dst, &insn, len);
+}
+
int __kprobes aarch64_insn_patch_text_nosync(void *addr, u32 insn)
{
u32 *tp = addr;
diff --git a/arch/arm64/kernel/pi/.gitignore b/arch/arm64/kernel/pi/.gitignore
new file mode 100644
index 000000000000..efb29b663e85
--- /dev/null
+++ b/arch/arm64/kernel/pi/.gitignore
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+relacheck
diff --git a/arch/arm64/kernel/pi/Makefile b/arch/arm64/kernel/pi/Makefile
index c844a0546d7f..4393b41f0b71 100644
--- a/arch/arm64/kernel/pi/Makefile
+++ b/arch/arm64/kernel/pi/Makefile
@@ -11,6 +11,9 @@ KBUILD_CFLAGS := $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) -fpie \
-fno-asynchronous-unwind-tables -fno-unwind-tables \
$(call cc-option,-fno-addrsig)
+# this code may run with the MMU off so disable unaligned accesses
+CFLAGS_map_range.o += -mstrict-align
+
# remove SCS flags from all objects in this directory
KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_SCS), $(KBUILD_CFLAGS))
# disable LTO
@@ -22,14 +25,26 @@ KCSAN_SANITIZE := n
UBSAN_SANITIZE := n
KCOV_INSTRUMENT := n
+hostprogs := relacheck
+
+quiet_cmd_piobjcopy = $(quiet_cmd_objcopy)
+ cmd_piobjcopy = $(cmd_objcopy) && $(obj)/relacheck $(@) $(<)
+
$(obj)/%.pi.o: OBJCOPYFLAGS := --prefix-symbols=__pi_ \
- --remove-section=.note.gnu.property \
- --prefix-alloc-sections=.init
-$(obj)/%.pi.o: $(obj)/%.o FORCE
- $(call if_changed,objcopy)
+ --remove-section=.note.gnu.property
+$(obj)/%.pi.o: $(obj)/%.o $(obj)/relacheck FORCE
+ $(call if_changed,piobjcopy)
+
+# ensure that all the lib- code ends up as __init code and data
+$(obj)/lib-%.pi.o: OBJCOPYFLAGS += --prefix-alloc-sections=.init
$(obj)/lib-%.o: $(srctree)/lib/%.c FORCE
$(call if_changed_rule,cc_o_c)
-obj-y := kaslr_early.pi.o lib-fdt.pi.o lib-fdt_ro.pi.o
-extra-y := $(patsubst %.pi.o,%.o,$(obj-y))
+obj-y := idreg-override.pi.o \
+ map_kernel.pi.o map_range.pi.o \
+ lib-fdt.pi.o lib-fdt_ro.pi.o
+obj-$(CONFIG_RELOCATABLE) += relocate.pi.o
+obj-$(CONFIG_RANDOMIZE_BASE) += kaslr_early.pi.o
+obj-$(CONFIG_UNWIND_PATCH_PAC_INTO_SCS) += patch-scs.pi.o
+extra-y := $(patsubst %.pi.o,%.o,$(obj-y))
diff --git a/arch/arm64/kernel/idreg-override.c b/arch/arm64/kernel/pi/idreg-override.c
index e30fd9e32ef3..aad399796e81 100644
--- a/arch/arm64/kernel/idreg-override.c
+++ b/arch/arm64/kernel/pi/idreg-override.c
@@ -14,6 +14,8 @@
#include <asm/cpufeature.h>
#include <asm/setup.h>
+#include "pi.h"
+
#define FTR_DESC_NAME_LEN 20
#define FTR_DESC_FIELD_LEN 10
#define FTR_ALIAS_NAME_LEN 30
@@ -21,15 +23,6 @@
static u64 __boot_status __initdata;
-// temporary __prel64 related definitions
-// to be removed when this code is moved under pi/
-
-#define __prel64_initconst __initconst
-
-#define PREL64(type, name) union { type *name; }
-
-#define prel64_pointer(__d) (__d)
-
typedef bool filter_t(u64 val);
struct ftr_set_desc {
@@ -66,6 +59,35 @@ static const struct ftr_set_desc mmfr1 __prel64_initconst = {
},
};
+
+static bool __init mmfr2_varange_filter(u64 val)
+{
+ int __maybe_unused feat;
+
+ if (val)
+ return false;
+
+#ifdef CONFIG_ARM64_LPA2
+ feat = cpuid_feature_extract_signed_field(read_sysreg(id_aa64mmfr0_el1),
+ ID_AA64MMFR0_EL1_TGRAN_SHIFT);
+ if (feat >= ID_AA64MMFR0_EL1_TGRAN_LPA2) {
+ id_aa64mmfr0_override.val |=
+ (ID_AA64MMFR0_EL1_TGRAN_LPA2 - 1) << ID_AA64MMFR0_EL1_TGRAN_SHIFT;
+ id_aa64mmfr0_override.mask |= 0xfU << ID_AA64MMFR0_EL1_TGRAN_SHIFT;
+ }
+#endif
+ return true;
+}
+
+static const struct ftr_set_desc mmfr2 __prel64_initconst = {
+ .name = "id_aa64mmfr2",
+ .override = &id_aa64mmfr2_override,
+ .fields = {
+ FIELD("varange", ID_AA64MMFR2_EL1_VARange_SHIFT, mmfr2_varange_filter),
+ {}
+ },
+};
+
static bool __init pfr0_sve_filter(u64 val)
{
/*
@@ -166,6 +188,7 @@ static const struct ftr_set_desc sw_features __prel64_initconst = {
.fields = {
FIELD("nokaslr", ARM64_SW_FEATURE_OVERRIDE_NOKASLR, NULL),
FIELD("hvhe", ARM64_SW_FEATURE_OVERRIDE_HVHE, hvhe_filter),
+ FIELD("rodataoff", ARM64_SW_FEATURE_OVERRIDE_RODATA_OFF, NULL),
{}
},
};
@@ -173,6 +196,7 @@ static const struct ftr_set_desc sw_features __prel64_initconst = {
static const
PREL64(const struct ftr_set_desc, reg) regs[] __prel64_initconst = {
{ &mmfr1 },
+ { &mmfr2 },
{ &pfr0 },
{ &pfr1 },
{ &isar1 },
@@ -197,6 +221,8 @@ static const struct {
{ "arm64.nomops", "id_aa64isar2.mops=0" },
{ "arm64.nomte", "id_aa64pfr1.mte=0" },
{ "nokaslr", "arm64_sw.nokaslr=1" },
+ { "rodata=off", "arm64_sw.rodataoff=1" },
+ { "arm64.nolva", "id_aa64mmfr2.varange=0" },
};
static int __init parse_hexdigit(const char *p, u64 *v)
@@ -313,42 +339,35 @@ static __init void __parse_cmdline(const char *cmdline, bool parse_aliases)
} while (1);
}
-static __init const u8 *get_bootargs_cmdline(void)
+static __init const u8 *get_bootargs_cmdline(const void *fdt, int node)
{
+ static char const bootargs[] __initconst = "bootargs";
const u8 *prop;
- void *fdt;
- int node;
- fdt = get_early_fdt_ptr();
- if (!fdt)
- return NULL;
-
- node = fdt_path_offset(fdt, "/chosen");
if (node < 0)
return NULL;
- prop = fdt_getprop(fdt, node, "bootargs", NULL);
+ prop = fdt_getprop(fdt, node, bootargs, NULL);
if (!prop)
return NULL;
return strlen(prop) ? prop : NULL;
}
-static __init void parse_cmdline(void)
+static __init void parse_cmdline(const void *fdt, int chosen)
{
- const u8 *prop = get_bootargs_cmdline();
+ static char const cmdline[] __initconst = CONFIG_CMDLINE;
+ const u8 *prop = get_bootargs_cmdline(fdt, chosen);
if (IS_ENABLED(CONFIG_CMDLINE_FORCE) || !prop)
- __parse_cmdline(CONFIG_CMDLINE, true);
+ __parse_cmdline(cmdline, true);
if (!IS_ENABLED(CONFIG_CMDLINE_FORCE) && prop)
__parse_cmdline(prop, true);
}
-/* Keep checkers quiet */
-void init_feature_override(u64 boot_status);
-
-asmlinkage void __init init_feature_override(u64 boot_status)
+void __init init_feature_override(u64 boot_status, const void *fdt,
+ int chosen)
{
struct arm64_ftr_override *override;
const struct ftr_set_desc *reg;
@@ -364,7 +383,7 @@ asmlinkage void __init init_feature_override(u64 boot_status)
__boot_status = boot_status;
- parse_cmdline();
+ parse_cmdline(fdt, chosen);
for (i = 0; i < ARRAY_SIZE(regs); i++) {
reg = prel64_pointer(regs[i].reg);
@@ -373,3 +392,10 @@ asmlinkage void __init init_feature_override(u64 boot_status)
(unsigned long)(override + 1));
}
}
+
+char * __init skip_spaces(const char *str)
+{
+ while (isspace(*str))
+ ++str;
+ return (char *)str;
+}
diff --git a/arch/arm64/kernel/pi/kaslr_early.c b/arch/arm64/kernel/pi/kaslr_early.c
index 17bff6e399e4..0257b43819db 100644
--- a/arch/arm64/kernel/pi/kaslr_early.c
+++ b/arch/arm64/kernel/pi/kaslr_early.c
@@ -14,69 +14,23 @@
#include <asm/archrandom.h>
#include <asm/memory.h>
+#include <asm/pgtable.h>
-/* taken from lib/string.c */
-static char *__strstr(const char *s1, const char *s2)
-{
- size_t l1, l2;
-
- l2 = strlen(s2);
- if (!l2)
- return (char *)s1;
- l1 = strlen(s1);
- while (l1 >= l2) {
- l1--;
- if (!memcmp(s1, s2, l2))
- return (char *)s1;
- s1++;
- }
- return NULL;
-}
-static bool cmdline_contains_nokaslr(const u8 *cmdline)
-{
- const u8 *str;
-
- str = __strstr(cmdline, "nokaslr");
- return str == cmdline || (str > cmdline && *(str - 1) == ' ');
-}
-
-static bool is_kaslr_disabled_cmdline(void *fdt)
-{
- if (!IS_ENABLED(CONFIG_CMDLINE_FORCE)) {
- int node;
- const u8 *prop;
-
- node = fdt_path_offset(fdt, "/chosen");
- if (node < 0)
- goto out;
-
- prop = fdt_getprop(fdt, node, "bootargs", NULL);
- if (!prop)
- goto out;
-
- if (cmdline_contains_nokaslr(prop))
- return true;
+#include "pi.h"
- if (IS_ENABLED(CONFIG_CMDLINE_EXTEND))
- goto out;
+extern u16 memstart_offset_seed;
- return false;
- }
-out:
- return cmdline_contains_nokaslr(CONFIG_CMDLINE);
-}
-
-static u64 get_kaslr_seed(void *fdt)
+static u64 __init get_kaslr_seed(void *fdt, int node)
{
- int node, len;
+ static char const seed_str[] __initconst = "kaslr-seed";
fdt64_t *prop;
u64 ret;
+ int len;
- node = fdt_path_offset(fdt, "/chosen");
if (node < 0)
return 0;
- prop = fdt_getprop_w(fdt, node, "kaslr-seed", &len);
+ prop = fdt_getprop_w(fdt, node, seed_str, &len);
if (!prop || len != sizeof(u64))
return 0;
@@ -85,26 +39,28 @@ static u64 get_kaslr_seed(void *fdt)
return ret;
}
-asmlinkage u64 kaslr_early_init(void *fdt)
+u64 __init kaslr_early_init(void *fdt, int chosen)
{
- u64 seed;
+ u64 seed, range;
- if (is_kaslr_disabled_cmdline(fdt))
+ if (kaslr_disabled_cmdline())
return 0;
- seed = get_kaslr_seed(fdt);
+ seed = get_kaslr_seed(fdt, chosen);
if (!seed) {
if (!__early_cpu_has_rndr() ||
!__arm64_rndr((unsigned long *)&seed))
return 0;
}
+ memstart_offset_seed = seed & U16_MAX;
+
/*
* OK, so we are proceeding with KASLR enabled. Calculate a suitable
* kernel image offset from the seed. Let's place the kernel in the
- * middle half of the VMALLOC area (VA_BITS_MIN - 2), and stay clear of
- * the lower and upper quarters to avoid colliding with other
- * allocations.
+ * 'middle' half of the VMALLOC area, and stay clear of the lower and
+ * upper quarters to avoid colliding with other allocations.
*/
- return BIT(VA_BITS_MIN - 3) + (seed & GENMASK(VA_BITS_MIN - 3, 0));
+ range = (VMALLOC_END - KIMAGE_VADDR) / 2;
+ return range / 2 + (((__uint128_t)range * seed) >> 64);
}
diff --git a/arch/arm64/kernel/pi/map_kernel.c b/arch/arm64/kernel/pi/map_kernel.c
new file mode 100644
index 000000000000..5fa08e13e17e
--- /dev/null
+++ b/arch/arm64/kernel/pi/map_kernel.c
@@ -0,0 +1,253 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright 2023 Google LLC
+// Author: Ard Biesheuvel <ardb@google.com>
+
+#include <linux/init.h>
+#include <linux/libfdt.h>
+#include <linux/linkage.h>
+#include <linux/types.h>
+#include <linux/sizes.h>
+#include <linux/string.h>
+
+#include <asm/memory.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+
+#include "pi.h"
+
+extern const u8 __eh_frame_start[], __eh_frame_end[];
+
+extern void idmap_cpu_replace_ttbr1(void *pgdir);
+
+static void __init map_segment(pgd_t *pg_dir, u64 *pgd, u64 va_offset,
+ void *start, void *end, pgprot_t prot,
+ bool may_use_cont, int root_level)
+{
+ map_range(pgd, ((u64)start + va_offset) & ~PAGE_OFFSET,
+ ((u64)end + va_offset) & ~PAGE_OFFSET, (u64)start,
+ prot, root_level, (pte_t *)pg_dir, may_use_cont, 0);
+}
+
+static void __init unmap_segment(pgd_t *pg_dir, u64 va_offset, void *start,
+ void *end, int root_level)
+{
+ map_segment(pg_dir, NULL, va_offset, start, end, __pgprot(0),
+ false, root_level);
+}
+
+static void __init map_kernel(u64 kaslr_offset, u64 va_offset, int root_level)
+{
+ bool enable_scs = IS_ENABLED(CONFIG_UNWIND_PATCH_PAC_INTO_SCS);
+ bool twopass = IS_ENABLED(CONFIG_RELOCATABLE);
+ u64 pgdp = (u64)init_pg_dir + PAGE_SIZE;
+ pgprot_t text_prot = PAGE_KERNEL_ROX;
+ pgprot_t data_prot = PAGE_KERNEL;
+ pgprot_t prot;
+
+ /*
+ * External debuggers may need to write directly to the text mapping to
+ * install SW breakpoints. Allow this (only) when explicitly requested
+ * with rodata=off.
+ */
+ if (arm64_test_sw_feature_override(ARM64_SW_FEATURE_OVERRIDE_RODATA_OFF))
+ text_prot = PAGE_KERNEL_EXEC;
+
+ /*
+ * We only enable the shadow call stack dynamically if we are running
+ * on a system that does not implement PAC or BTI. PAC and SCS provide
+ * roughly the same level of protection, and BTI relies on the PACIASP
+ * instructions serving as landing pads, preventing us from patching
+ * those instructions into something else.
+ */
+ if (IS_ENABLED(CONFIG_ARM64_PTR_AUTH_KERNEL) && cpu_has_pac())
+ enable_scs = false;
+
+ if (IS_ENABLED(CONFIG_ARM64_BTI_KERNEL) && cpu_has_bti()) {
+ enable_scs = false;
+
+ /*
+ * If we have a CPU that supports BTI and a kernel built for
+ * BTI then mark the kernel executable text as guarded pages
+ * now so we don't have to rewrite the page tables later.
+ */
+ text_prot = __pgprot_modify(text_prot, PTE_GP, PTE_GP);
+ }
+
+ /* Map all code read-write on the first pass if needed */
+ twopass |= enable_scs;
+ prot = twopass ? data_prot : text_prot;
+
+ map_segment(init_pg_dir, &pgdp, va_offset, _stext, _etext, prot,
+ !twopass, root_level);
+ map_segment(init_pg_dir, &pgdp, va_offset, __start_rodata,
+ __inittext_begin, data_prot, false, root_level);
+ map_segment(init_pg_dir, &pgdp, va_offset, __inittext_begin,
+ __inittext_end, prot, false, root_level);
+ map_segment(init_pg_dir, &pgdp, va_offset, __initdata_begin,
+ __initdata_end, data_prot, false, root_level);
+ map_segment(init_pg_dir, &pgdp, va_offset, _data, _end, data_prot,
+ true, root_level);
+ dsb(ishst);
+
+ idmap_cpu_replace_ttbr1(init_pg_dir);
+
+ if (twopass) {
+ if (IS_ENABLED(CONFIG_RELOCATABLE))
+ relocate_kernel(kaslr_offset);
+
+ if (enable_scs) {
+ scs_patch(__eh_frame_start + va_offset,
+ __eh_frame_end - __eh_frame_start);
+ asm("ic ialluis");
+
+ dynamic_scs_is_enabled = true;
+ }
+
+ /*
+ * Unmap the text region before remapping it, to avoid
+ * potential TLB conflicts when creating the contiguous
+ * descriptors.
+ */
+ unmap_segment(init_pg_dir, va_offset, _stext, _etext,
+ root_level);
+ dsb(ishst);
+ isb();
+ __tlbi(vmalle1);
+ isb();
+
+ /*
+ * Remap these segments with different permissions
+ * No new page table allocations should be needed
+ */
+ map_segment(init_pg_dir, NULL, va_offset, _stext, _etext,
+ text_prot, true, root_level);
+ map_segment(init_pg_dir, NULL, va_offset, __inittext_begin,
+ __inittext_end, text_prot, false, root_level);
+ }
+
+ /* Copy the root page table to its final location */
+ memcpy((void *)swapper_pg_dir + va_offset, init_pg_dir, PAGE_SIZE);
+ dsb(ishst);
+ idmap_cpu_replace_ttbr1(swapper_pg_dir);
+}
+
+static void noinline __section(".idmap.text") set_ttbr0_for_lpa2(u64 ttbr)
+{
+ u64 sctlr = read_sysreg(sctlr_el1);
+ u64 tcr = read_sysreg(tcr_el1) | TCR_DS;
+
+ asm(" msr sctlr_el1, %0 ;"
+ " isb ;"
+ " msr ttbr0_el1, %1 ;"
+ " msr tcr_el1, %2 ;"
+ " isb ;"
+ " tlbi vmalle1 ;"
+ " dsb nsh ;"
+ " isb ;"
+ " msr sctlr_el1, %3 ;"
+ " isb ;"
+ :: "r"(sctlr & ~SCTLR_ELx_M), "r"(ttbr), "r"(tcr), "r"(sctlr));
+}
+
+static void __init remap_idmap_for_lpa2(void)
+{
+ /* clear the bits that change meaning once LPA2 is turned on */
+ pteval_t mask = PTE_SHARED;
+
+ /*
+ * We have to clear bits [9:8] in all block or page descriptors in the
+ * initial ID map, as otherwise they will be (mis)interpreted as
+ * physical address bits once we flick the LPA2 switch (TCR.DS). Since
+ * we cannot manipulate live descriptors in that way without creating
+ * potential TLB conflicts, let's create another temporary ID map in a
+ * LPA2 compatible fashion, and update the initial ID map while running
+ * from that.
+ */
+ create_init_idmap(init_pg_dir, mask);
+ dsb(ishst);
+ set_ttbr0_for_lpa2((u64)init_pg_dir);
+
+ /*
+ * Recreate the initial ID map with the same granularity as before.
+ * 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);
+
+ create_init_idmap(init_idmap_pg_dir, mask);
+ dsb(ishst);
+
+ /* switch back to the updated initial ID map */
+ set_ttbr0_for_lpa2((u64)init_idmap_pg_dir);
+
+ /* wipe the temporary ID map from memory */
+ memset(init_pg_dir, 0, (u64)init_pg_end - (u64)init_pg_dir);
+}
+
+static void __init map_fdt(u64 fdt)
+{
+ static u8 ptes[INIT_IDMAP_FDT_SIZE] __initdata __aligned(PAGE_SIZE);
+ u64 efdt = fdt + MAX_FDT_SIZE;
+ u64 ptep = (u64)ptes;
+
+ /*
+ * Map up to MAX_FDT_SIZE bytes, but avoid overlap with
+ * the kernel image.
+ */
+ map_range(&ptep, fdt, (u64)_text > fdt ? min((u64)_text, efdt) : efdt,
+ fdt, PAGE_KERNEL, IDMAP_ROOT_LEVEL,
+ (pte_t *)init_idmap_pg_dir, false, 0);
+ dsb(ishst);
+}
+
+asmlinkage void __init early_map_kernel(u64 boot_status, void *fdt)
+{
+ static char const chosen_str[] __initconst = "/chosen";
+ u64 va_base, pa_base = (u64)&_text;
+ u64 kaslr_offset = pa_base % MIN_KIMG_ALIGN;
+ int root_level = 4 - CONFIG_PGTABLE_LEVELS;
+ int va_bits = VA_BITS;
+ int chosen;
+
+ map_fdt((u64)fdt);
+
+ /* Clear BSS and the initial page tables */
+ memset(__bss_start, 0, (u64)init_pg_end - (u64)__bss_start);
+
+ /* Parse the command line for CPU feature overrides */
+ chosen = fdt_path_offset(fdt, chosen_str);
+ init_feature_override(boot_status, fdt, chosen);
+
+ if (IS_ENABLED(CONFIG_ARM64_64K_PAGES) && !cpu_has_lva()) {
+ va_bits = VA_BITS_MIN;
+ } else if (IS_ENABLED(CONFIG_ARM64_LPA2) && !cpu_has_lpa2()) {
+ va_bits = VA_BITS_MIN;
+ root_level++;
+ }
+
+ if (va_bits > VA_BITS_MIN)
+ sysreg_clear_set(tcr_el1, TCR_T1SZ_MASK, TCR_T1SZ(va_bits));
+
+ /*
+ * The virtual KASLR displacement modulo 2MiB is decided by the
+ * physical placement of the image, as otherwise, we might not be able
+ * to create the early kernel mapping using 2 MiB block descriptors. So
+ * take the low bits of the KASLR offset from the physical address, and
+ * fill in the high bits from the seed.
+ */
+ if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
+ u64 kaslr_seed = kaslr_early_init(fdt, chosen);
+
+ if (kaslr_seed && kaslr_requires_kpti())
+ arm64_use_ng_mappings = true;
+
+ kaslr_offset |= kaslr_seed & ~(MIN_KIMG_ALIGN - 1);
+ }
+
+ if (IS_ENABLED(CONFIG_ARM64_LPA2) && va_bits > VA_BITS_MIN)
+ remap_idmap_for_lpa2();
+
+ va_base = KIMAGE_VADDR + kaslr_offset;
+ map_kernel(kaslr_offset, va_base - pa_base, root_level);
+}
diff --git a/arch/arm64/kernel/pi/map_range.c b/arch/arm64/kernel/pi/map_range.c
new file mode 100644
index 000000000000..5410b2cac590
--- /dev/null
+++ b/arch/arm64/kernel/pi/map_range.c
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright 2023 Google LLC
+// Author: Ard Biesheuvel <ardb@google.com>
+
+#include <linux/types.h>
+#include <linux/sizes.h>
+
+#include <asm/memory.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+
+#include "pi.h"
+
+/**
+ * map_range - Map a contiguous range of physical pages into virtual memory
+ *
+ * @pte: Address of physical pointer to array of pages to
+ * allocate page tables from
+ * @start: Virtual address of the start of the range
+ * @end: Virtual address of the end of the range (exclusive)
+ * @pa: Physical address of the start of the range
+ * @prot: Access permissions of the range
+ * @level: Translation level for the mapping
+ * @tbl: The level @level page table to create the mappings in
+ * @may_use_cont: Whether the use of the contiguous attribute is allowed
+ * @va_offset: Offset between a physical page and its current mapping
+ * in the VA space
+ */
+void __init map_range(u64 *pte, u64 start, u64 end, u64 pa, pgprot_t prot,
+ int level, pte_t *tbl, bool may_use_cont, u64 va_offset)
+{
+ u64 cmask = (level == 3) ? CONT_PTE_SIZE - 1 : U64_MAX;
+ u64 protval = pgprot_val(prot) & ~PTE_TYPE_MASK;
+ int lshift = (3 - level) * (PAGE_SHIFT - 3);
+ u64 lmask = (PAGE_SIZE << lshift) - 1;
+
+ start &= PAGE_MASK;
+ pa &= PAGE_MASK;
+
+ /* Advance tbl to the entry that covers start */
+ tbl += (start >> (lshift + PAGE_SHIFT)) % PTRS_PER_PTE;
+
+ /*
+ * Set the right block/page bits for this level unless we are
+ * clearing the mapping
+ */
+ if (protval)
+ protval |= (level < 3) ? PMD_TYPE_SECT : PTE_TYPE_PAGE;
+
+ while (start < end) {
+ u64 next = min((start | lmask) + 1, PAGE_ALIGN(end));
+
+ if (level < 3 && (start | next | pa) & lmask) {
+ /*
+ * This chunk needs a finer grained mapping. Create a
+ * table mapping if necessary and recurse.
+ */
+ if (pte_none(*tbl)) {
+ *tbl = __pte(__phys_to_pte_val(*pte) |
+ PMD_TYPE_TABLE | PMD_TABLE_UXN);
+ *pte += PTRS_PER_PTE * sizeof(pte_t);
+ }
+ map_range(pte, start, next, pa, prot, level + 1,
+ (pte_t *)(__pte_to_phys(*tbl) + va_offset),
+ may_use_cont, va_offset);
+ } else {
+ /*
+ * Start a contiguous range if start and pa are
+ * suitably aligned
+ */
+ if (((start | pa) & cmask) == 0 && may_use_cont)
+ protval |= PTE_CONT;
+
+ /*
+ * Clear the contiguous attribute if the remaining
+ * range does not cover a contiguous block
+ */
+ if ((end & ~cmask) <= start)
+ protval &= ~PTE_CONT;
+
+ /* Put down a block or page mapping */
+ *tbl = __pte(__phys_to_pte_val(pa) | protval);
+ }
+ pa += next - start;
+ start = next;
+ tbl++;
+ }
+}
+
+asmlinkage u64 __init create_init_idmap(pgd_t *pg_dir, pteval_t clrmask)
+{
+ u64 ptep = (u64)pg_dir + PAGE_SIZE;
+ pgprot_t text_prot = PAGE_KERNEL_ROX;
+ pgprot_t data_prot = PAGE_KERNEL;
+
+ pgprot_val(text_prot) &= ~clrmask;
+ pgprot_val(data_prot) &= ~clrmask;
+
+ map_range(&ptep, (u64)_stext, (u64)__initdata_begin, (u64)_stext,
+ text_prot, IDMAP_ROOT_LEVEL, (pte_t *)pg_dir, false, 0);
+ map_range(&ptep, (u64)__initdata_begin, (u64)_end, (u64)__initdata_begin,
+ data_prot, IDMAP_ROOT_LEVEL, (pte_t *)pg_dir, false, 0);
+
+ return ptep;
+}
diff --git a/arch/arm64/kernel/patch-scs.c b/arch/arm64/kernel/pi/patch-scs.c
index a1fe4b4ff591..49d8b40e61bc 100644
--- a/arch/arm64/kernel/patch-scs.c
+++ b/arch/arm64/kernel/pi/patch-scs.c
@@ -4,16 +4,17 @@
* Author: Ard Biesheuvel <ardb@google.com>
*/
-#include <linux/bug.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/linkage.h>
-#include <linux/printk.h>
#include <linux/types.h>
-#include <asm/cacheflush.h>
#include <asm/scs.h>
+#include "pi.h"
+
+bool dynamic_scs_is_enabled;
+
//
// This minimal DWARF CFI parser is partially based on the code in
// arch/arc/kernel/unwind.c, and on the document below:
@@ -49,8 +50,6 @@
#define DW_CFA_GNU_negative_offset_extended 0x2f
#define DW_CFA_hi_user 0x3f
-extern const u8 __eh_frame_start[], __eh_frame_end[];
-
enum {
PACIASP = 0xd503233f,
AUTIASP = 0xd50323bf,
@@ -81,7 +80,11 @@ static void __always_inline scs_patch_loc(u64 loc)
*/
return;
}
- dcache_clean_pou(loc, loc + sizeof(u32));
+ if (IS_ENABLED(CONFIG_ARM64_WORKAROUND_CLEAN_CACHE))
+ asm("dc civac, %0" :: "r"(loc));
+ else
+ asm(ALTERNATIVE("dc cvau, %0", "nop", ARM64_HAS_CACHE_IDC)
+ :: "r"(loc));
}
/*
@@ -128,10 +131,10 @@ struct eh_frame {
};
};
-static int noinstr scs_handle_fde_frame(const struct eh_frame *frame,
- bool fde_has_augmentation_data,
- int code_alignment_factor,
- bool dry_run)
+static int scs_handle_fde_frame(const struct eh_frame *frame,
+ bool fde_has_augmentation_data,
+ int code_alignment_factor,
+ bool dry_run)
{
int size = frame->size - offsetof(struct eh_frame, opcodes) + 4;
u64 loc = (u64)offset_to_ptr(&frame->initial_loc);
@@ -198,14 +201,13 @@ static int noinstr scs_handle_fde_frame(const struct eh_frame *frame,
break;
default:
- pr_err("unhandled opcode: %02x in FDE frame %lx\n", opcode[-1], (uintptr_t)frame);
return -ENOEXEC;
}
}
return 0;
}
-int noinstr scs_patch(const u8 eh_frame[], int size)
+int scs_patch(const u8 eh_frame[], int size)
{
const u8 *p = eh_frame;
@@ -250,13 +252,3 @@ int noinstr scs_patch(const u8 eh_frame[], int size)
}
return 0;
}
-
-asmlinkage void __init scs_patch_vmlinux(void)
-{
- if (!should_patch_pac_into_scs())
- return;
-
- WARN_ON(scs_patch(__eh_frame_start, __eh_frame_end - __eh_frame_start));
- icache_inval_all_pou();
- isb();
-}
diff --git a/arch/arm64/kernel/pi/pi.h b/arch/arm64/kernel/pi/pi.h
new file mode 100644
index 000000000000..c91e5e965cd3
--- /dev/null
+++ b/arch/arm64/kernel/pi/pi.h
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright 2023 Google LLC
+// Author: Ard Biesheuvel <ardb@google.com>
+
+#include <linux/types.h>
+
+#define __prel64_initconst __section(".init.rodata.prel64")
+
+#define PREL64(type, name) union { type *name; prel64_t name ## _prel; }
+
+#define prel64_pointer(__d) (typeof(__d))prel64_to_pointer(&__d##_prel)
+
+typedef volatile signed long prel64_t;
+
+static inline void *prel64_to_pointer(const prel64_t *offset)
+{
+ if (!*offset)
+ return NULL;
+ return (void *)offset + *offset;
+}
+
+extern bool dynamic_scs_is_enabled;
+
+extern pgd_t init_idmap_pg_dir[], init_idmap_pg_end[];
+
+void init_feature_override(u64 boot_status, const void *fdt, int chosen);
+u64 kaslr_early_init(void *fdt, int chosen);
+void relocate_kernel(u64 offset);
+int scs_patch(const u8 eh_frame[], int size);
+
+void map_range(u64 *pgd, u64 start, u64 end, u64 pa, pgprot_t prot,
+ int level, pte_t *tbl, bool may_use_cont, u64 va_offset);
+
+asmlinkage void early_map_kernel(u64 boot_status, void *fdt);
+
+asmlinkage u64 create_init_idmap(pgd_t *pgd, pteval_t clrmask);
diff --git a/arch/arm64/kernel/pi/relacheck.c b/arch/arm64/kernel/pi/relacheck.c
new file mode 100644
index 000000000000..b0cd4d0d275b
--- /dev/null
+++ b/arch/arm64/kernel/pi/relacheck.c
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023 - Google LLC
+ * Author: Ard Biesheuvel <ardb@google.com>
+ */
+
+#include <elf.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#define HOST_ORDER ELFDATA2LSB
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+#define HOST_ORDER ELFDATA2MSB
+#endif
+
+static Elf64_Ehdr *ehdr;
+static Elf64_Shdr *shdr;
+static const char *strtab;
+static bool swap;
+
+static uint64_t swab_elfxword(uint64_t val)
+{
+ return swap ? __builtin_bswap64(val) : val;
+}
+
+static uint32_t swab_elfword(uint32_t val)
+{
+ return swap ? __builtin_bswap32(val) : val;
+}
+
+static uint16_t swab_elfhword(uint16_t val)
+{
+ return swap ? __builtin_bswap16(val) : val;
+}
+
+int main(int argc, char *argv[])
+{
+ struct stat stat;
+ int fd, ret;
+
+ if (argc < 3) {
+ fprintf(stderr, "file arguments missing\n");
+ exit(EXIT_FAILURE);
+ }
+
+ fd = open(argv[1], O_RDWR);
+ if (fd < 0) {
+ fprintf(stderr, "failed to open %s\n", argv[1]);
+ exit(EXIT_FAILURE);
+ }
+
+ ret = fstat(fd, &stat);
+ if (ret < 0) {
+ fprintf(stderr, "failed to stat() %s\n", argv[1]);
+ exit(EXIT_FAILURE);
+ }
+
+ ehdr = mmap(0, stat.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (ehdr == MAP_FAILED) {
+ fprintf(stderr, "failed to mmap() %s\n", argv[1]);
+ exit(EXIT_FAILURE);
+ }
+
+ swap = ehdr->e_ident[EI_DATA] != HOST_ORDER;
+ shdr = (void *)ehdr + swab_elfxword(ehdr->e_shoff);
+ strtab = (void *)ehdr +
+ swab_elfxword(shdr[swab_elfhword(ehdr->e_shstrndx)].sh_offset);
+
+ for (int i = 0; i < swab_elfhword(ehdr->e_shnum); i++) {
+ unsigned long info, flags;
+ bool prel64 = false;
+ Elf64_Rela *rela;
+ int numrela;
+
+ if (swab_elfword(shdr[i].sh_type) != SHT_RELA)
+ continue;
+
+ /* only consider RELA sections operating on data */
+ info = swab_elfword(shdr[i].sh_info);
+ flags = swab_elfxword(shdr[info].sh_flags);
+ if ((flags & (SHF_ALLOC | SHF_EXECINSTR)) != SHF_ALLOC)
+ continue;
+
+ /*
+ * We generally don't permit ABS64 relocations in the code that
+ * runs before relocation processing occurs. If statically
+ * initialized absolute symbol references are unavoidable, they
+ * may be emitted into a *.rodata.prel64 section and they will
+ * be converted to place-relative 64-bit references. This
+ * requires special handling in the referring code.
+ */
+ if (strstr(strtab + swab_elfword(shdr[info].sh_name),
+ ".rodata.prel64")) {
+ prel64 = true;
+ }
+
+ rela = (void *)ehdr + swab_elfxword(shdr[i].sh_offset);
+ numrela = swab_elfxword(shdr[i].sh_size) / sizeof(*rela);
+
+ for (int j = 0; j < numrela; j++) {
+ uint64_t info = swab_elfxword(rela[j].r_info);
+
+ if (ELF64_R_TYPE(info) != R_AARCH64_ABS64)
+ continue;
+
+ if (prel64) {
+ /* convert ABS64 into PREL64 */
+ info ^= R_AARCH64_ABS64 ^ R_AARCH64_PREL64;
+ rela[j].r_info = swab_elfxword(info);
+ } else {
+ fprintf(stderr,
+ "Unexpected absolute relocations detected in %s\n",
+ argv[2]);
+ close(fd);
+ unlink(argv[1]);
+ exit(EXIT_FAILURE);
+ }
+ }
+ }
+ close(fd);
+ return 0;
+}
diff --git a/arch/arm64/kernel/pi/relocate.c b/arch/arm64/kernel/pi/relocate.c
new file mode 100644
index 000000000000..2407d2696398
--- /dev/null
+++ b/arch/arm64/kernel/pi/relocate.c
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright 2023 Google LLC
+// Authors: Ard Biesheuvel <ardb@google.com>
+// Peter Collingbourne <pcc@google.com>
+
+#include <linux/elf.h>
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include "pi.h"
+
+extern const Elf64_Rela rela_start[], rela_end[];
+extern const u64 relr_start[], relr_end[];
+
+void __init relocate_kernel(u64 offset)
+{
+ u64 *place = NULL;
+
+ for (const Elf64_Rela *rela = rela_start; rela < rela_end; rela++) {
+ if (ELF64_R_TYPE(rela->r_info) != R_AARCH64_RELATIVE)
+ continue;
+ *(u64 *)(rela->r_offset + offset) = rela->r_addend + offset;
+ }
+
+ if (!IS_ENABLED(CONFIG_RELR) || !offset)
+ return;
+
+ /*
+ * Apply RELR relocations.
+ *
+ * RELR is a compressed format for storing relative relocations. The
+ * encoded sequence of entries looks like:
+ * [ AAAAAAAA BBBBBBB1 BBBBBBB1 ... AAAAAAAA BBBBBB1 ... ]
+ *
+ * i.e. start with an address, followed by any number of bitmaps. The
+ * address entry encodes 1 relocation. The subsequent bitmap entries
+ * encode up to 63 relocations each, at subsequent offsets following
+ * the last address entry.
+ *
+ * The bitmap entries must have 1 in the least significant bit. The
+ * assumption here is that an address cannot have 1 in lsb. Odd
+ * addresses are not supported. Any odd addresses are stored in the
+ * RELA section, which is handled above.
+ *
+ * With the exception of the least significant bit, each bit in the
+ * bitmap corresponds with a machine word that follows the base address
+ * word, and the bit value indicates whether or not a relocation needs
+ * to be applied to it. The second least significant bit represents the
+ * machine word immediately following the initial address, and each bit
+ * that follows represents the next word, in linear order. As such, a
+ * single bitmap can encode up to 63 relocations in a 64-bit object.
+ */
+ for (const u64 *relr = relr_start; relr < relr_end; relr++) {
+ if ((*relr & 1) == 0) {
+ place = (u64 *)(*relr + offset);
+ *place++ += offset;
+ } else {
+ for (u64 *p = place, r = *relr >> 1; r; p++, r >>= 1)
+ if (r & 1)
+ *p += offset;
+ place += 63;
+ }
+ }
+}
diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c
index 70b91a8c6bb3..327855a11df2 100644
--- a/arch/arm64/kernel/probes/kprobes.c
+++ b/arch/arm64/kernel/probes/kprobes.c
@@ -371,6 +371,21 @@ static struct break_hook kprobes_break_ss_hook = {
.fn = kprobe_breakpoint_ss_handler,
};
+static int __kprobes
+kretprobe_breakpoint_handler(struct pt_regs *regs, unsigned long esr)
+{
+ if (regs->pc != (unsigned long)__kretprobe_trampoline)
+ return DBG_HOOK_ERROR;
+
+ regs->pc = kretprobe_trampoline_handler(regs, (void *)regs->regs[29]);
+ return DBG_HOOK_HANDLED;
+}
+
+static struct break_hook kretprobes_break_hook = {
+ .imm = KRETPROBES_BRK_IMM,
+ .fn = kretprobe_breakpoint_handler,
+};
+
/*
* Provide a blacklist of symbols identifying ranges which cannot be kprobed.
* This blacklist is exposed to userspace via debugfs (kprobes/blacklist).
@@ -396,11 +411,6 @@ int __init arch_populate_kprobe_blacklist(void)
return ret;
}
-void __kprobes __used *trampoline_probe_handler(struct pt_regs *regs)
-{
- return (void *)kretprobe_trampoline_handler(regs, (void *)regs->regs[29]);
-}
-
void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
struct pt_regs *regs)
{
@@ -420,6 +430,7 @@ int __init arch_init_kprobes(void)
{
register_kernel_break_hook(&kprobes_break_hook);
register_kernel_break_hook(&kprobes_break_ss_hook);
+ register_kernel_break_hook(&kretprobes_break_hook);
return 0;
}
diff --git a/arch/arm64/kernel/probes/kprobes_trampoline.S b/arch/arm64/kernel/probes/kprobes_trampoline.S
index 9a6499bed58b..a362f3dbb3d1 100644
--- a/arch/arm64/kernel/probes/kprobes_trampoline.S
+++ b/arch/arm64/kernel/probes/kprobes_trampoline.S
@@ -4,83 +4,17 @@
*/
#include <linux/linkage.h>
-#include <asm/asm-offsets.h>
+#include <asm/asm-bug.h>
#include <asm/assembler.h>
.text
- .macro save_all_base_regs
- stp x0, x1, [sp, #S_X0]
- stp x2, x3, [sp, #S_X2]
- stp x4, x5, [sp, #S_X4]
- stp x6, x7, [sp, #S_X6]
- stp x8, x9, [sp, #S_X8]
- stp x10, x11, [sp, #S_X10]
- stp x12, x13, [sp, #S_X12]
- stp x14, x15, [sp, #S_X14]
- stp x16, x17, [sp, #S_X16]
- stp x18, x19, [sp, #S_X18]
- stp x20, x21, [sp, #S_X20]
- stp x22, x23, [sp, #S_X22]
- stp x24, x25, [sp, #S_X24]
- stp x26, x27, [sp, #S_X26]
- stp x28, x29, [sp, #S_X28]
- add x0, sp, #PT_REGS_SIZE
- stp lr, x0, [sp, #S_LR]
- /*
- * Construct a useful saved PSTATE
- */
- mrs x0, nzcv
- mrs x1, daif
- orr x0, x0, x1
- mrs x1, CurrentEL
- orr x0, x0, x1
- mrs x1, SPSel
- orr x0, x0, x1
- stp xzr, x0, [sp, #S_PC]
- .endm
-
- .macro restore_all_base_regs
- ldr x0, [sp, #S_PSTATE]
- and x0, x0, #(PSR_N_BIT | PSR_Z_BIT | PSR_C_BIT | PSR_V_BIT)
- msr nzcv, x0
- ldp x0, x1, [sp, #S_X0]
- ldp x2, x3, [sp, #S_X2]
- ldp x4, x5, [sp, #S_X4]
- ldp x6, x7, [sp, #S_X6]
- ldp x8, x9, [sp, #S_X8]
- ldp x10, x11, [sp, #S_X10]
- ldp x12, x13, [sp, #S_X12]
- ldp x14, x15, [sp, #S_X14]
- ldp x16, x17, [sp, #S_X16]
- ldp x18, x19, [sp, #S_X18]
- ldp x20, x21, [sp, #S_X20]
- ldp x22, x23, [sp, #S_X22]
- ldp x24, x25, [sp, #S_X24]
- ldp x26, x27, [sp, #S_X26]
- ldp x28, x29, [sp, #S_X28]
- .endm
-
SYM_CODE_START(__kretprobe_trampoline)
- sub sp, sp, #PT_REGS_SIZE
-
- save_all_base_regs
-
- /* Setup a frame pointer. */
- add x29, sp, #S_FP
-
- mov x0, sp
- bl trampoline_probe_handler
/*
- * Replace trampoline address in lr with actual orig_ret_addr return
- * address.
+ * Trigger a breakpoint exception. The PC will be adjusted by
+ * kretprobe_breakpoint_handler(), and no subsequent instructions will
+ * be executed from the trampoline.
*/
- mov lr, x0
-
- /* The frame pointer (x29) is restored with other registers. */
- restore_all_base_regs
-
- add sp, sp, #PT_REGS_SIZE
- ret
-
+ brk #KRETPROBES_BRK_IMM
+ ASM_BUG()
SYM_CODE_END(__kretprobe_trampoline)
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 7387b68c745b..4ae31b7af6c3 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -290,9 +290,6 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
fpsimd_preserve_current_state();
*dst = *src;
- /* We rely on the above assignment to initialize dst's thread_flags: */
- BUILD_BUG_ON(!IS_ENABLED(CONFIG_THREAD_INFO_IN_TASK));
-
/*
* Detach src's sve_state (if any) from dst so that it does not
* get erroneously used or freed prematurely. dst's copies
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index e3bef38fc2e2..0d022599eb61 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -174,7 +174,6 @@ static void ptrace_hbptriggered(struct perf_event *bp,
struct arch_hw_breakpoint *bkpt = counter_arch_bp(bp);
const char *desc = "Hardware breakpoint trap (ptrace)";
-#ifdef CONFIG_COMPAT
if (is_compat_task()) {
int si_errno = 0;
int i;
@@ -196,7 +195,7 @@ static void ptrace_hbptriggered(struct perf_event *bp,
desc);
return;
}
-#endif
+
arm64_force_sig_fault(SIGTRAP, TRAP_HWBKPT, bkpt->trigger, desc);
}
@@ -698,6 +697,39 @@ static int tls_set(struct task_struct *target, const struct user_regset *regset,
return ret;
}
+static int fpmr_get(struct task_struct *target, const struct user_regset *regset,
+ struct membuf to)
+{
+ if (!system_supports_fpmr())
+ return -EINVAL;
+
+ if (target == current)
+ fpsimd_preserve_current_state();
+
+ return membuf_store(&to, target->thread.uw.fpmr);
+}
+
+static int fpmr_set(struct task_struct *target, const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+ int ret;
+ unsigned long fpmr;
+
+ if (!system_supports_fpmr())
+ return -EINVAL;
+
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &fpmr, 0, count);
+ if (ret)
+ return ret;
+
+ target->thread.uw.fpmr = fpmr;
+
+ fpsimd_flush_task_state(target);
+
+ return 0;
+}
+
static int system_call_get(struct task_struct *target,
const struct user_regset *regset,
struct membuf to)
@@ -729,7 +761,6 @@ static void sve_init_header_from_task(struct user_sve_header *header,
{
unsigned int vq;
bool active;
- bool fpsimd_only;
enum vec_type task_type;
memset(header, 0, sizeof(*header));
@@ -745,12 +776,10 @@ static void sve_init_header_from_task(struct user_sve_header *header,
case ARM64_VEC_SVE:
if (test_tsk_thread_flag(target, TIF_SVE_VL_INHERIT))
header->flags |= SVE_PT_VL_INHERIT;
- fpsimd_only = !test_tsk_thread_flag(target, TIF_SVE);
break;
case ARM64_VEC_SME:
if (test_tsk_thread_flag(target, TIF_SME_VL_INHERIT))
header->flags |= SVE_PT_VL_INHERIT;
- fpsimd_only = false;
break;
default:
WARN_ON_ONCE(1);
@@ -758,7 +787,7 @@ static void sve_init_header_from_task(struct user_sve_header *header,
}
if (active) {
- if (fpsimd_only) {
+ if (target->thread.fp_type == FP_STATE_FPSIMD) {
header->flags |= SVE_PT_REGS_FPSIMD;
} else {
header->flags |= SVE_PT_REGS_SVE;
@@ -1419,6 +1448,7 @@ enum aarch64_regset {
REGSET_HW_BREAK,
REGSET_HW_WATCH,
#endif
+ REGSET_FPMR,
REGSET_SYSTEM_CALL,
#ifdef CONFIG_ARM64_SVE
REGSET_SVE,
@@ -1497,6 +1527,14 @@ static const struct user_regset aarch64_regsets[] = {
.regset_get = system_call_get,
.set = system_call_set,
},
+ [REGSET_FPMR] = {
+ .core_note_type = NT_ARM_FPMR,
+ .n = 1,
+ .size = sizeof(u64),
+ .align = sizeof(u64),
+ .regset_get = fpmr_get,
+ .set = fpmr_set,
+ },
#ifdef CONFIG_ARM64_SVE
[REGSET_SVE] = { /* Scalable Vector Extension */
.core_note_type = NT_ARM_SVE,
@@ -1597,7 +1635,6 @@ static const struct user_regset_view user_aarch64_view = {
.regsets = aarch64_regsets, .n = ARRAY_SIZE(aarch64_regsets)
};
-#ifdef CONFIG_COMPAT
enum compat_regset {
REGSET_COMPAT_GPR,
REGSET_COMPAT_VFP,
@@ -1854,6 +1891,7 @@ static const struct user_regset_view user_aarch32_ptrace_view = {
.regsets = aarch32_ptrace_regsets, .n = ARRAY_SIZE(aarch32_ptrace_regsets)
};
+#ifdef CONFIG_COMPAT
static int compat_ptrace_read_user(struct task_struct *tsk, compat_ulong_t off,
compat_ulong_t __user *ret)
{
@@ -2115,7 +2153,6 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
const struct user_regset_view *task_user_regset_view(struct task_struct *task)
{
-#ifdef CONFIG_COMPAT
/*
* Core dumping of 32-bit tasks or compat ptrace requests must use the
* user_aarch32_view compatible with arm32. Native ptrace requests on
@@ -2126,7 +2163,7 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)
return &user_aarch32_view;
else if (is_compat_thread(task_thread_info(task)))
return &user_aarch32_ptrace_view;
-#endif
+
return &user_aarch64_view;
}
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 42c690bb2d60..65a052bf741f 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -166,21 +166,6 @@ static void __init smp_build_mpidr_hash(void)
pr_warn("Large number of MPIDR hash buckets detected\n");
}
-static void *early_fdt_ptr __initdata;
-
-void __init *get_early_fdt_ptr(void)
-{
- return early_fdt_ptr;
-}
-
-asmlinkage void __init early_fdt_map(u64 dt_phys)
-{
- int fdt_size;
-
- early_fixmap_init();
- early_fdt_ptr = fixmap_remap_fdt(dt_phys, &fdt_size, PAGE_KERNEL);
-}
-
static void __init setup_machine_fdt(phys_addr_t dt_phys)
{
int size;
@@ -298,13 +283,6 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)
kaslr_init();
- /*
- * If know now we are going to need KPTI then use non-global
- * mappings from the start, avoiding the cost of rewriting
- * everything later.
- */
- arm64_use_ng_mappings = kaslr_requires_kpti();
-
early_fixmap_init();
early_ioremap_init();
@@ -320,9 +298,8 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)
dynamic_scs_init();
/*
- * Unmask asynchronous aborts and fiq after bringing up possible
- * earlycon. (Report possible System Errors once we can report this
- * occurred).
+ * Unmask SError as soon as possible after initializing earlycon so
+ * that we can report any SErrors immediately.
*/
local_daif_restore(DAIF_PROCCTX_NOIRQ);
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 425b1bc17a3f..4a77f4976e11 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -16,8 +16,8 @@
#include <linux/uaccess.h>
#include <linux/sizes.h>
#include <linux/string.h>
-#include <linux/resume_user_mode.h>
#include <linux/ratelimit.h>
+#include <linux/rseq.h>
#include <linux/syscalls.h>
#include <asm/daifflags.h>
@@ -60,6 +60,7 @@ struct rt_sigframe_user_layout {
unsigned long tpidr2_offset;
unsigned long za_offset;
unsigned long zt_offset;
+ unsigned long fpmr_offset;
unsigned long extra_offset;
unsigned long end_offset;
};
@@ -182,6 +183,8 @@ struct user_ctxs {
u32 za_size;
struct zt_context __user *zt;
u32 zt_size;
+ struct fpmr_context __user *fpmr;
+ u32 fpmr_size;
};
static int preserve_fpsimd_context(struct fpsimd_context __user *ctx)
@@ -227,6 +230,33 @@ static int restore_fpsimd_context(struct user_ctxs *user)
return err ? -EFAULT : 0;
}
+static int preserve_fpmr_context(struct fpmr_context __user *ctx)
+{
+ int err = 0;
+
+ current->thread.uw.fpmr = read_sysreg_s(SYS_FPMR);
+
+ __put_user_error(FPMR_MAGIC, &ctx->head.magic, err);
+ __put_user_error(sizeof(*ctx), &ctx->head.size, err);
+ __put_user_error(current->thread.uw.fpmr, &ctx->fpmr, err);
+
+ return err;
+}
+
+static int restore_fpmr_context(struct user_ctxs *user)
+{
+ u64 fpmr;
+ int err = 0;
+
+ if (user->fpmr_size != sizeof(*user->fpmr))
+ return -EINVAL;
+
+ __get_user_error(fpmr, &user->fpmr->fpmr, err);
+ if (!err)
+ write_sysreg_s(fpmr, SYS_FPMR);
+
+ return err;
+}
#ifdef CONFIG_ARM64_SVE
@@ -590,6 +620,7 @@ static int parse_user_sigframe(struct user_ctxs *user,
user->tpidr2 = NULL;
user->za = NULL;
user->zt = NULL;
+ user->fpmr = NULL;
if (!IS_ALIGNED((unsigned long)base, 16))
goto invalid;
@@ -684,6 +715,17 @@ static int parse_user_sigframe(struct user_ctxs *user,
user->zt_size = size;
break;
+ case FPMR_MAGIC:
+ if (!system_supports_fpmr())
+ goto invalid;
+
+ if (user->fpmr)
+ goto invalid;
+
+ user->fpmr = (struct fpmr_context __user *)head;
+ user->fpmr_size = size;
+ break;
+
case EXTRA_MAGIC:
if (have_extra_context)
goto invalid;
@@ -806,6 +848,9 @@ static int restore_sigframe(struct pt_regs *regs,
if (err == 0 && system_supports_tpidr2() && user.tpidr2)
err = restore_tpidr2_context(&user);
+ if (err == 0 && system_supports_fpmr() && user.fpmr)
+ err = restore_fpmr_context(&user);
+
if (err == 0 && system_supports_sme() && user.za)
err = restore_za_context(&user);
@@ -928,6 +973,13 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user,
}
}
+ if (system_supports_fpmr()) {
+ err = sigframe_alloc(user, &user->fpmr_offset,
+ sizeof(struct fpmr_context));
+ if (err)
+ return err;
+ }
+
return sigframe_alloc_end(user);
}
@@ -983,6 +1035,13 @@ static int setup_sigframe(struct rt_sigframe_user_layout *user,
err |= preserve_tpidr2_context(tpidr2_ctx);
}
+ /* FPMR if supported */
+ if (system_supports_fpmr() && err == 0) {
+ struct fpmr_context __user *fpmr_ctx =
+ apply_user_offset(user, user->fpmr_offset);
+ err |= preserve_fpmr_context(fpmr_ctx);
+ }
+
/* ZA state if present */
if (system_supports_sme() && err == 0 && user->za_offset) {
struct za_context __user *za_ctx =
@@ -1207,7 +1266,7 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
* the kernel can handle, and then we build all the user-level signal handling
* stack-frames in one go after that.
*/
-static void do_signal(struct pt_regs *regs)
+void do_signal(struct pt_regs *regs)
{
unsigned long continue_addr = 0, restart_addr = 0;
int retval = 0;
@@ -1278,41 +1337,6 @@ static void do_signal(struct pt_regs *regs)
restore_saved_sigmask();
}
-void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags)
-{
- do {
- if (thread_flags & _TIF_NEED_RESCHED) {
- /* Unmask Debug and SError for the next task */
- local_daif_restore(DAIF_PROCCTX_NOIRQ);
-
- schedule();
- } else {
- local_daif_restore(DAIF_PROCCTX);
-
- if (thread_flags & _TIF_UPROBE)
- uprobe_notify_resume(regs);
-
- if (thread_flags & _TIF_MTE_ASYNC_FAULT) {
- clear_thread_flag(TIF_MTE_ASYNC_FAULT);
- send_sig_fault(SIGSEGV, SEGV_MTEAERR,
- (void __user *)NULL, current);
- }
-
- if (thread_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
- do_signal(regs);
-
- if (thread_flags & _TIF_NOTIFY_RESUME)
- resume_user_mode_work(regs);
-
- if (thread_flags & _TIF_FOREIGN_FPSTATE)
- fpsimd_restore_current_state();
- }
-
- local_daif_mask();
- thread_flags = read_thread_flags();
- } while (thread_flags & _TIF_WORK_MASK);
-}
-
unsigned long __ro_after_init signal_minsigstksz;
/*
diff --git a/arch/arm64/kernel/sleep.S b/arch/arm64/kernel/sleep.S
index 2aa5129d8253..f093cdf71be1 100644
--- a/arch/arm64/kernel/sleep.S
+++ b/arch/arm64/kernel/sleep.S
@@ -102,9 +102,6 @@ SYM_CODE_START(cpu_resume)
mov x0, xzr
bl init_kernel_el
mov x19, x0 // preserve boot mode
-#if VA_BITS > 48
- ldr_l x0, vabits_actual
-#endif
bl __cpu_setup
/* enable the MMU early - so we can access sleep_save_stash by va */
adrp x1, swapper_pg_dir
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index b2a60e0bcfd2..684c26511696 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -7,6 +7,7 @@
#include <linux/kernel.h>
#include <linux/efi.h>
#include <linux/export.h>
+#include <linux/filter.h>
#include <linux/ftrace.h>
#include <linux/kprobes.h>
#include <linux/sched.h>
@@ -266,6 +267,31 @@ noinline noinstr void arch_stack_walk(stack_trace_consume_fn consume_entry,
kunwind_stack_walk(arch_kunwind_consume_entry, &data, task, regs);
}
+struct bpf_unwind_consume_entry_data {
+ bool (*consume_entry)(void *cookie, u64 ip, u64 sp, u64 fp);
+ void *cookie;
+};
+
+static bool
+arch_bpf_unwind_consume_entry(const struct kunwind_state *state, void *cookie)
+{
+ struct bpf_unwind_consume_entry_data *data = cookie;
+
+ return data->consume_entry(data->cookie, state->common.pc, 0,
+ state->common.fp);
+}
+
+noinline noinstr void arch_bpf_stack_walk(bool (*consume_entry)(void *cookie, u64 ip, u64 sp,
+ u64 fp), void *cookie)
+{
+ struct bpf_unwind_consume_entry_data data = {
+ .consume_entry = consume_entry,
+ .cookie = cookie,
+ };
+
+ kunwind_stack_walk(arch_bpf_unwind_consume_entry, &data, current, NULL);
+}
+
static bool dump_backtrace_entry(void *arg, unsigned long where)
{
char *loglvl = arg;
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index 9a70d9746b66..ad198262b981 100644
--- a/arch/arm64/kernel/syscall.c
+++ b/arch/arm64/kernel/syscall.c
@@ -20,14 +20,11 @@ long sys_ni_syscall(void);
static long do_ni_syscall(struct pt_regs *regs, int scno)
{
-#ifdef CONFIG_COMPAT
- long ret;
if (is_compat_task()) {
- ret = compat_arm_syscall(regs, scno);
+ long ret = compat_arm_syscall(regs, scno);
if (ret != -ENOSYS)
return ret;
}
-#endif
return sys_ni_syscall();
}
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index 5562daf38a22..89b6e7840002 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -69,10 +69,7 @@ static struct vdso_abi_info vdso_info[] __ro_after_init = {
/*
* The vDSO data page.
*/
-static union {
- struct vdso_data data[CS_BASES];
- u8 page[PAGE_SIZE];
-} vdso_data_store __page_aligned_data;
+static union vdso_data_store vdso_data_store __page_aligned_data;
struct vdso_data *vdso_data = vdso_data_store.data;
static int vdso_mremap(const struct vm_special_mapping *sm,
diff --git a/arch/arm64/kernel/crash_core.c b/arch/arm64/kernel/vmcore_info.c
index 66cde752cd74..b19d5d6cb8b3 100644
--- a/arch/arm64/kernel/crash_core.c
+++ b/arch/arm64/kernel/vmcore_info.c
@@ -4,7 +4,7 @@
* Copyright (C) Huawei Futurewei Technologies.
*/
-#include <linux/crash_core.h>
+#include <linux/vmcore_info.h>
#include <asm/cpufeature.h>
#include <asm/memory.h>
#include <asm/pgtable-hwdef.h>
@@ -23,7 +23,6 @@ void arch_crash_save_vmcoreinfo(void)
/* Please note VMCOREINFO_NUMBER() uses "%d", not "%x" */
vmcoreinfo_append_str("NUMBER(MODULES_VADDR)=0x%lx\n", MODULES_VADDR);
vmcoreinfo_append_str("NUMBER(MODULES_END)=0x%lx\n", MODULES_END);
- vmcoreinfo_append_str("NUMBER(VMALLOC_START)=0x%lx\n", VMALLOC_START);
vmcoreinfo_append_str("NUMBER(VMALLOC_END)=0x%lx\n", VMALLOC_END);
vmcoreinfo_append_str("NUMBER(VMEMMAP_START)=0x%lx\n", VMEMMAP_START);
vmcoreinfo_append_str("NUMBER(VMEMMAP_END)=0x%lx\n", VMEMMAP_END);
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index 3cd7e76cc562..755a22d4f840 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -126,9 +126,9 @@ jiffies = jiffies_64;
#ifdef CONFIG_UNWIND_TABLES
#define UNWIND_DATA_SECTIONS \
.eh_frame : { \
- __eh_frame_start = .; \
+ __pi___eh_frame_start = .; \
*(.eh_frame) \
- __eh_frame_end = .; \
+ __pi___eh_frame_end = .; \
}
#else
#define UNWIND_DATA_SECTIONS
@@ -270,15 +270,15 @@ SECTIONS
HYPERVISOR_RELOC_SECTION
.rela.dyn : ALIGN(8) {
- __rela_start = .;
+ __pi_rela_start = .;
*(.rela .rela*)
- __rela_end = .;
+ __pi_rela_end = .;
}
.relr.dyn : ALIGN(8) {
- __relr_start = .;
+ __pi_relr_start = .;
*(.relr.dyn)
- __relr_end = .;
+ __pi_relr_end = .;
}
. = ALIGN(SEGMENT_ALIGN);
@@ -311,12 +311,17 @@ SECTIONS
__pecoff_data_rawsize = ABSOLUTE(. - __initdata_begin);
_edata = .;
+ /* start of zero-init region */
BSS_SECTION(SBSS_ALIGN, 0, 0)
. = ALIGN(PAGE_SIZE);
init_pg_dir = .;
. += INIT_DIR_SIZE;
init_pg_end = .;
+ /* end of zero-init region */
+
+ . += SZ_4K; /* stack for the early C runtime */
+ early_init_stack = .;
. = ALIGN(SEGMENT_ALIGN);
__pecoff_data_size = ABSOLUTE(. - __initdata_begin);
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 27ca89b628a0..58f09370d17e 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -19,7 +19,6 @@ if VIRTUALIZATION
menuconfig KVM
bool "Kernel-based Virtual Machine (KVM) support"
- depends on HAVE_KVM
select KVM_COMMON
select KVM_GENERIC_HARDWARE_ENABLING
select KVM_GENERIC_MMU_NOTIFIER
@@ -33,12 +32,11 @@ menuconfig KVM
select HAVE_KVM_MSI
select HAVE_KVM_IRQCHIP
select HAVE_KVM_IRQ_ROUTING
- select IRQ_BYPASS_MANAGER
select HAVE_KVM_IRQ_BYPASS
+ select HAVE_KVM_READONLY_MEM
select HAVE_KVM_VCPU_RUN_PID_CHANGE
select SCHED_INFO
select GUEST_PERF_EVENTS if PERF_EVENTS
- select XARRAY_MULTI
help
Support hosting virtualized guest machines.
diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index 9dec8c419bf4..879982b1cc73 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -745,7 +745,7 @@ static void kvm_timer_vcpu_load_nested_switch(struct kvm_vcpu *vcpu,
WARN_ON_ONCE(ret);
/*
- * The virtual offset behaviour is "interresting", as it
+ * The virtual offset behaviour is "interesting", as it
* always applies when HCR_EL2.E2H==0, but only when
* accessed from EL1 when HCR_EL2.E2H==1. So make sure we
* track E2H when putting the HV timer in "direct" mode.
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index a25265aca432..c4a0a35e02c7 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -190,6 +190,10 @@ vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
return VM_FAULT_SIGBUS;
}
+void kvm_arch_create_vm_debugfs(struct kvm *kvm)
+{
+ kvm_sys_regs_create_debugfs(kvm);
+}
/**
* kvm_arch_destroy_vm - destroy the VM data structure
@@ -206,6 +210,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
pkvm_destroy_hyp_vm(kvm);
kfree(kvm->arch.mpidr_data);
+ kfree(kvm->arch.sysreg_masks);
kvm_destroy_vcpus(kvm);
kvm_unshare_hyp(kvm, kvm + 1);
@@ -674,6 +679,12 @@ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
return ret;
}
+ /*
+ * This needs to happen after NV has imposed its own restrictions on
+ * the feature set
+ */
+ kvm_init_sysreg(vcpu);
+
ret = kvm_timer_enable(vcpu);
if (ret)
return ret;
@@ -2586,13 +2597,11 @@ static __init int kvm_arm_init(void)
if (err)
goto out_hyp;
- if (is_protected_kvm_enabled()) {
- kvm_info("Protected nVHE mode initialized successfully\n");
- } else if (in_hyp_mode) {
- kvm_info("VHE mode initialized successfully\n");
- } else {
- kvm_info("Hyp mode initialized successfully\n");
- }
+ kvm_info("%s%sVHE mode initialized successfully\n",
+ in_hyp_mode ? "" : (is_protected_kvm_enabled() ?
+ "Protected " : "Hyp "),
+ in_hyp_mode ? "" : (cpus_have_final_cap(ARM64_KVM_HVHE) ?
+ "h" : "n"));
/*
* FIXME: Do something reasonable if kvm_init() fails after pKVM
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index 8725291cb00a..ce8886122ed3 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -23,7 +23,7 @@
static DEFINE_PER_CPU(u64, mdcr_el2);
-/**
+/*
* save/restore_guest_debug_regs
*
* For some debug operations we need to tweak some guest registers. As
@@ -143,6 +143,7 @@ void kvm_arm_vcpu_init_debug(struct kvm_vcpu *vcpu)
/**
* kvm_arm_reset_debug_ptr - reset the debug ptr to point to the vcpu state
+ * @vcpu: the vcpu pointer
*/
void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu)
diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 431fd429932d..4697ba41b3a9 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -427,12 +427,14 @@ static const complex_condition_check ccc[] = {
* [19:14] bit number in the FGT register (6 bits)
* [20] trap polarity (1 bit)
* [25:21] FG filter (5 bits)
- * [62:26] Unused (37 bits)
+ * [35:26] Main SysReg table index (10 bits)
+ * [62:36] Unused (27 bits)
* [63] RES0 - Must be zero, as lost on insertion in the xarray
*/
#define TC_CGT_BITS 10
#define TC_FGT_BITS 4
#define TC_FGF_BITS 5
+#define TC_SRI_BITS 10
union trap_config {
u64 val;
@@ -442,7 +444,8 @@ union trap_config {
unsigned long bit:6; /* Bit number */
unsigned long pol:1; /* Polarity */
unsigned long fgf:TC_FGF_BITS; /* Fine Grained Filter */
- unsigned long unused:37; /* Unused, should be zero */
+ unsigned long sri:TC_SRI_BITS; /* SysReg Index */
+ unsigned long unused:27; /* Unused, should be zero */
unsigned long mbz:1; /* Must Be Zero */
};
};
@@ -1006,18 +1009,6 @@ static const struct encoding_to_trap_config encoding_to_cgt[] __initconst = {
static DEFINE_XARRAY(sr_forward_xa);
-enum fgt_group_id {
- __NO_FGT_GROUP__,
- HFGxTR_GROUP,
- HDFGRTR_GROUP,
- HDFGWTR_GROUP,
- HFGITR_GROUP,
- HAFGRTR_GROUP,
-
- /* Must be last */
- __NR_FGT_GROUP_IDS__
-};
-
enum fg_filter_id {
__NO_FGF__,
HCRX_FGTnXS,
@@ -1757,6 +1748,28 @@ static __init void print_nv_trap_error(const struct encoding_to_trap_config *tc,
err);
}
+static u32 encoding_next(u32 encoding)
+{
+ u8 op0, op1, crn, crm, op2;
+
+ op0 = sys_reg_Op0(encoding);
+ op1 = sys_reg_Op1(encoding);
+ crn = sys_reg_CRn(encoding);
+ crm = sys_reg_CRm(encoding);
+ op2 = sys_reg_Op2(encoding);
+
+ if (op2 < Op2_mask)
+ return sys_reg(op0, op1, crn, crm, op2 + 1);
+ if (crm < CRm_mask)
+ return sys_reg(op0, op1, crn, crm + 1, 0);
+ if (crn < CRn_mask)
+ return sys_reg(op0, op1, crn + 1, 0, 0);
+ if (op1 < Op1_mask)
+ return sys_reg(op0, op1 + 1, 0, 0, 0);
+
+ return sys_reg(op0 + 1, 0, 0, 0, 0);
+}
+
int __init populate_nv_trap_config(void)
{
int ret = 0;
@@ -1775,23 +1788,18 @@ int __init populate_nv_trap_config(void)
ret = -EINVAL;
}
- if (cgt->encoding != cgt->end) {
- prev = xa_store_range(&sr_forward_xa,
- cgt->encoding, cgt->end,
- xa_mk_value(cgt->tc.val),
- GFP_KERNEL);
- } else {
- prev = xa_store(&sr_forward_xa, cgt->encoding,
+ for (u32 enc = cgt->encoding; enc <= cgt->end; enc = encoding_next(enc)) {
+ prev = xa_store(&sr_forward_xa, enc,
xa_mk_value(cgt->tc.val), GFP_KERNEL);
if (prev && !xa_is_err(prev)) {
ret = -EINVAL;
print_nv_trap_error(cgt, "Duplicate CGT", ret);
}
- }
- if (xa_is_err(prev)) {
- ret = xa_err(prev);
- print_nv_trap_error(cgt, "Failed CGT insertion", ret);
+ if (xa_is_err(prev)) {
+ ret = xa_err(prev);
+ print_nv_trap_error(cgt, "Failed CGT insertion", ret);
+ }
}
}
@@ -1804,6 +1812,7 @@ int __init populate_nv_trap_config(void)
for (int i = 0; i < ARRAY_SIZE(encoding_to_fgt); i++) {
const struct encoding_to_trap_config *fgt = &encoding_to_fgt[i];
union trap_config tc;
+ void *prev;
if (fgt->tc.fgt >= __NR_FGT_GROUP_IDS__) {
ret = -EINVAL;
@@ -1818,8 +1827,13 @@ int __init populate_nv_trap_config(void)
}
tc.val |= fgt->tc.val;
- xa_store(&sr_forward_xa, fgt->encoding,
- xa_mk_value(tc.val), GFP_KERNEL);
+ prev = xa_store(&sr_forward_xa, fgt->encoding,
+ xa_mk_value(tc.val), GFP_KERNEL);
+
+ if (xa_is_err(prev)) {
+ ret = xa_err(prev);
+ print_nv_trap_error(fgt, "Failed FGT insertion", ret);
+ }
}
kvm_info("nv: %ld fine grained trap handlers\n",
@@ -1845,6 +1859,38 @@ check_mcb:
return ret;
}
+int __init populate_sysreg_config(const struct sys_reg_desc *sr,
+ unsigned int idx)
+{
+ union trap_config tc;
+ u32 encoding;
+ void *ret;
+
+ /*
+ * 0 is a valid value for the index, but not for the storage.
+ * We'll store (idx+1), so check against an offset'd limit.
+ */
+ if (idx >= (BIT(TC_SRI_BITS) - 1)) {
+ kvm_err("sysreg %s (%d) out of range\n", sr->name, idx);
+ return -EINVAL;
+ }
+
+ encoding = sys_reg(sr->Op0, sr->Op1, sr->CRn, sr->CRm, sr->Op2);
+ tc = get_trap_config(encoding);
+
+ if (tc.sri) {
+ kvm_err("sysreg %s (%d) duplicate entry (%d)\n",
+ sr->name, idx - 1, tc.sri);
+ return -EINVAL;
+ }
+
+ tc.sri = idx + 1;
+ ret = xa_store(&sr_forward_xa, encoding,
+ xa_mk_value(tc.val), GFP_KERNEL);
+
+ return xa_err(ret);
+}
+
static enum trap_behaviour get_behaviour(struct kvm_vcpu *vcpu,
const struct trap_bits *tb)
{
@@ -1892,20 +1938,64 @@ static enum trap_behaviour compute_trap_behaviour(struct kvm_vcpu *vcpu,
return __compute_trap_behaviour(vcpu, tc.cgt, b);
}
-static bool check_fgt_bit(u64 val, const union trap_config tc)
+static u64 kvm_get_sysreg_res0(struct kvm *kvm, enum vcpu_sysreg sr)
{
- return ((val >> tc.bit) & 1) == tc.pol;
+ struct kvm_sysreg_masks *masks;
+
+ /* Only handle the VNCR-backed regs for now */
+ if (sr < __VNCR_START__)
+ return 0;
+
+ masks = kvm->arch.sysreg_masks;
+
+ return masks->mask[sr - __VNCR_START__].res0;
}
-#define sanitised_sys_reg(vcpu, reg) \
- ({ \
- u64 __val; \
- __val = __vcpu_sys_reg(vcpu, reg); \
- __val &= ~__ ## reg ## _RES0; \
- (__val); \
- })
+static bool check_fgt_bit(struct kvm *kvm, bool is_read,
+ u64 val, const union trap_config tc)
+{
+ enum vcpu_sysreg sr;
+
+ if (tc.pol)
+ return (val & BIT(tc.bit));
+
+ /*
+ * FGTs with negative polarities are an absolute nightmare, as
+ * we need to evaluate the bit in the light of the feature
+ * that defines it. WTF were they thinking?
+ *
+ * So let's check if the bit has been earmarked as RES0, as
+ * this indicates an unimplemented feature.
+ */
+ if (val & BIT(tc.bit))
+ return false;
+
+ switch ((enum fgt_group_id)tc.fgt) {
+ case HFGxTR_GROUP:
+ sr = is_read ? HFGRTR_EL2 : HFGWTR_EL2;
+ break;
+
+ case HDFGRTR_GROUP:
+ sr = is_read ? HDFGRTR_EL2 : HDFGWTR_EL2;
+ break;
+
+ case HAFGRTR_GROUP:
+ sr = HAFGRTR_EL2;
+ break;
+
+ case HFGITR_GROUP:
+ sr = HFGITR_EL2;
+ break;
+
+ default:
+ WARN_ONCE(1, "Unhandled FGT group");
+ return false;
+ }
+
+ return !(kvm_get_sysreg_res0(kvm, sr) & BIT(tc.bit));
+}
-bool __check_nv_sr_forward(struct kvm_vcpu *vcpu)
+bool triage_sysreg_trap(struct kvm_vcpu *vcpu, int *sr_index)
{
union trap_config tc;
enum trap_behaviour b;
@@ -1913,9 +2003,6 @@ bool __check_nv_sr_forward(struct kvm_vcpu *vcpu)
u32 sysreg;
u64 esr, val;
- if (!vcpu_has_nv(vcpu) || is_hyp_ctxt(vcpu))
- return false;
-
esr = kvm_vcpu_get_esr(vcpu);
sysreg = esr_sys64_to_sysreg(esr);
is_read = (esr & ESR_ELx_SYS64_ISS_DIR_MASK) == ESR_ELx_SYS64_ISS_DIR_READ;
@@ -1926,13 +2013,27 @@ bool __check_nv_sr_forward(struct kvm_vcpu *vcpu)
* A value of 0 for the whole entry means that we know nothing
* for this sysreg, and that it cannot be re-injected into the
* nested hypervisor. In this situation, let's cut it short.
- *
- * Note that ultimately, we could also make use of the xarray
- * to store the index of the sysreg in the local descriptor
- * array, avoiding another search... Hint, hint...
*/
if (!tc.val)
- return false;
+ goto local;
+
+ /*
+ * If a sysreg can be trapped using a FGT, first check whether we
+ * trap for the purpose of forbidding the feature. In that case,
+ * inject an UNDEF.
+ */
+ if (tc.fgt != __NO_FGT_GROUP__ &&
+ (vcpu->kvm->arch.fgu[tc.fgt] & BIT(tc.bit))) {
+ kvm_inject_undefined(vcpu);
+ return true;
+ }
+
+ /*
+ * If we're not nesting, immediately return to the caller, with the
+ * sysreg index, should we have it.
+ */
+ if (!vcpu_has_nv(vcpu) || is_hyp_ctxt(vcpu))
+ goto local;
switch ((enum fgt_group_id)tc.fgt) {
case __NO_FGT_GROUP__:
@@ -1940,25 +2041,24 @@ bool __check_nv_sr_forward(struct kvm_vcpu *vcpu)
case HFGxTR_GROUP:
if (is_read)
- val = sanitised_sys_reg(vcpu, HFGRTR_EL2);
+ val = __vcpu_sys_reg(vcpu, HFGRTR_EL2);
else
- val = sanitised_sys_reg(vcpu, HFGWTR_EL2);
+ val = __vcpu_sys_reg(vcpu, HFGWTR_EL2);
break;
case HDFGRTR_GROUP:
- case HDFGWTR_GROUP:
if (is_read)
- val = sanitised_sys_reg(vcpu, HDFGRTR_EL2);
+ val = __vcpu_sys_reg(vcpu, HDFGRTR_EL2);
else
- val = sanitised_sys_reg(vcpu, HDFGWTR_EL2);
+ val = __vcpu_sys_reg(vcpu, HDFGWTR_EL2);
break;
case HAFGRTR_GROUP:
- val = sanitised_sys_reg(vcpu, HAFGRTR_EL2);
+ val = __vcpu_sys_reg(vcpu, HAFGRTR_EL2);
break;
case HFGITR_GROUP:
- val = sanitised_sys_reg(vcpu, HFGITR_EL2);
+ val = __vcpu_sys_reg(vcpu, HFGITR_EL2);
switch (tc.fgf) {
u64 tmp;
@@ -1966,7 +2066,7 @@ bool __check_nv_sr_forward(struct kvm_vcpu *vcpu)
break;
case HCRX_FGTnXS:
- tmp = sanitised_sys_reg(vcpu, HCRX_EL2);
+ tmp = __vcpu_sys_reg(vcpu, HCRX_EL2);
if (tmp & HCRX_EL2_FGTnXS)
tc.fgt = __NO_FGT_GROUP__;
}
@@ -1975,10 +2075,11 @@ bool __check_nv_sr_forward(struct kvm_vcpu *vcpu)
case __NR_FGT_GROUP_IDS__:
/* Something is really wrong, bail out */
WARN_ONCE(1, "__NR_FGT_GROUP_IDS__");
- return false;
+ goto local;
}
- if (tc.fgt != __NO_FGT_GROUP__ && check_fgt_bit(val, tc))
+ if (tc.fgt != __NO_FGT_GROUP__ && check_fgt_bit(vcpu->kvm, is_read,
+ val, tc))
goto inject;
b = compute_trap_behaviour(vcpu, tc);
@@ -1987,6 +2088,26 @@ bool __check_nv_sr_forward(struct kvm_vcpu *vcpu)
((b & BEHAVE_FORWARD_WRITE) && !is_read))
goto inject;
+local:
+ if (!tc.sri) {
+ struct sys_reg_params params;
+
+ params = esr_sys64_to_params(esr);
+
+ /*
+ * Check for the IMPDEF range, as per DDI0487 J.a,
+ * D18.3.2 Reserved encodings for IMPLEMENTATION
+ * DEFINED registers.
+ */
+ if (!(params.Op0 == 3 && (params.CRn & 0b1011) == 0b1011))
+ print_sys_reg_msg(&params,
+ "Unsupported guest access at: %lx\n",
+ *vcpu_pc(vcpu));
+ kvm_inject_undefined(vcpu);
+ return true;
+ }
+
+ *sr_index = tc.sri - 1;
return false;
inject:
diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
index 8c1d0d4853df..826307e19e3a 100644
--- a/arch/arm64/kvm/fpsimd.c
+++ b/arch/arm64/kvm/fpsimd.c
@@ -117,7 +117,7 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu)
}
/*
- * Called just before entering the guest once we are no longer preemptable
+ * Called just before entering the guest once we are no longer preemptible
* and interrupts are disabled. If we have managed to run anything using
* FP while we were preemptible (such as off the back of an interrupt),
* then neither the host nor the guest own the FP hardware (and it was the
@@ -153,6 +153,7 @@ void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu)
fp_state.sve_vl = vcpu->arch.sve_max_vl;
fp_state.sme_state = NULL;
fp_state.svcr = &vcpu->arch.svcr;
+ fp_state.fpmr = &vcpu->arch.fpmr;
fp_state.fp_type = &vcpu->arch.fp_type;
if (vcpu_has_sve(vcpu))
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index aaf1d4939739..e2f762d959bb 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -711,6 +711,7 @@ static int copy_sve_reg_indices(const struct kvm_vcpu *vcpu,
/**
* kvm_arm_num_regs - how many registers do we present via KVM_GET_ONE_REG
+ * @vcpu: the vCPU pointer
*
* This is for all registers.
*/
@@ -729,6 +730,8 @@ unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu)
/**
* kvm_arm_copy_reg_indices - get indices of all registers.
+ * @vcpu: the vCPU pointer
+ * @uindices: register list to copy
*
* We do core registers right here, then we append system regs.
*/
@@ -902,8 +905,8 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
/**
* kvm_arch_vcpu_ioctl_set_guest_debug - set up guest debugging
- * @kvm: pointer to the KVM struct
- * @kvm_guest_debug: the ioctl data buffer
+ * @vcpu: the vCPU pointer
+ * @dbg: the ioctl data buffer
*
* This sets up and enables the VM for guest debugging. Userspace
* passes in a control flag to enable different debug types and
@@ -1072,7 +1075,7 @@ int kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm,
} else {
/*
* Only locking to serialise with a concurrent
- * set_pte_at() in the VMM but still overriding the
+ * __set_ptes() in the VMM but still overriding the
* tags, hence ignoring the return value.
*/
try_page_mte_tagging(page);
diff --git a/arch/arm64/kvm/hyp/aarch32.c b/arch/arm64/kvm/hyp/aarch32.c
index f98cbe2626a1..8d9670e6615d 100644
--- a/arch/arm64/kvm/hyp/aarch32.c
+++ b/arch/arm64/kvm/hyp/aarch32.c
@@ -84,7 +84,7 @@ bool kvm_condition_valid32(const struct kvm_vcpu *vcpu)
}
/**
- * adjust_itstate - adjust ITSTATE when emulating instructions in IT-block
+ * kvm_adjust_itstate - adjust ITSTATE when emulating instructions in IT-block
* @vcpu: The VCPU pointer
*
* When exceptions occur while instructions are executed in Thumb IF-THEN
@@ -120,7 +120,7 @@ static void kvm_adjust_itstate(struct kvm_vcpu *vcpu)
}
/**
- * kvm_skip_instr - skip a trapped instruction and proceed to the next
+ * kvm_skip_instr32 - skip a trapped instruction and proceed to the next
* @vcpu: The vcpu pointer
*/
void kvm_skip_instr32(struct kvm_vcpu *vcpu)
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index a038320cdb08..e3fcf8c4d5b4 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -79,14 +79,48 @@ static inline void __activate_traps_fpsimd32(struct kvm_vcpu *vcpu)
clr |= ~hfg & __ ## reg ## _nMASK; \
} while(0)
-#define update_fgt_traps_cs(vcpu, reg, clr, set) \
+#define reg_to_fgt_group_id(reg) \
+ ({ \
+ enum fgt_group_id id; \
+ switch(reg) { \
+ case HFGRTR_EL2: \
+ case HFGWTR_EL2: \
+ id = HFGxTR_GROUP; \
+ break; \
+ case HFGITR_EL2: \
+ id = HFGITR_GROUP; \
+ break; \
+ case HDFGRTR_EL2: \
+ case HDFGWTR_EL2: \
+ id = HDFGRTR_GROUP; \
+ break; \
+ case HAFGRTR_EL2: \
+ id = HAFGRTR_GROUP; \
+ break; \
+ default: \
+ BUILD_BUG_ON(1); \
+ } \
+ \
+ id; \
+ })
+
+#define compute_undef_clr_set(vcpu, kvm, reg, clr, set) \
+ do { \
+ u64 hfg = kvm->arch.fgu[reg_to_fgt_group_id(reg)]; \
+ set |= hfg & __ ## reg ## _MASK; \
+ clr |= hfg & __ ## reg ## _nMASK; \
+ } while(0)
+
+#define update_fgt_traps_cs(hctxt, vcpu, kvm, reg, clr, set) \
do { \
- struct kvm_cpu_context *hctxt = \
- &this_cpu_ptr(&kvm_host_data)->host_ctxt; \
u64 c = 0, s = 0; \
\
ctxt_sys_reg(hctxt, reg) = read_sysreg_s(SYS_ ## reg); \
- compute_clr_set(vcpu, reg, c, s); \
+ if (vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu)) \
+ compute_clr_set(vcpu, reg, c, s); \
+ \
+ compute_undef_clr_set(vcpu, kvm, reg, c, s); \
+ \
s |= set; \
c |= clr; \
if (c || s) { \
@@ -97,8 +131,8 @@ static inline void __activate_traps_fpsimd32(struct kvm_vcpu *vcpu)
} \
} while(0)
-#define update_fgt_traps(vcpu, reg) \
- update_fgt_traps_cs(vcpu, reg, 0, 0)
+#define update_fgt_traps(hctxt, vcpu, kvm, reg) \
+ update_fgt_traps_cs(hctxt, vcpu, kvm, reg, 0, 0)
/*
* Validate the fine grain trap masks.
@@ -122,8 +156,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;
- u64 r_clr = 0, w_clr = 0, r_set = 0, w_set = 0, tmp;
- u64 r_val, w_val;
+ struct kvm *kvm = kern_hyp_va(vcpu->kvm);
CHECK_FGT_MASKS(HFGRTR_EL2);
CHECK_FGT_MASKS(HFGWTR_EL2);
@@ -136,72 +169,45 @@ static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
if (!cpus_have_final_cap(ARM64_HAS_FGT))
return;
- ctxt_sys_reg(hctxt, HFGRTR_EL2) = read_sysreg_s(SYS_HFGRTR_EL2);
- ctxt_sys_reg(hctxt, HFGWTR_EL2) = read_sysreg_s(SYS_HFGWTR_EL2);
-
- if (cpus_have_final_cap(ARM64_SME)) {
- tmp = HFGxTR_EL2_nSMPRI_EL1_MASK | HFGxTR_EL2_nTPIDR2_EL0_MASK;
-
- r_clr |= tmp;
- w_clr |= tmp;
- }
-
- /*
- * Trap guest writes to TCR_EL1 to prevent it from enabling HA or HD.
- */
- if (cpus_have_final_cap(ARM64_WORKAROUND_AMPERE_AC03_CPU_38))
- w_set |= HFGxTR_EL2_TCR_EL1_MASK;
-
- if (vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu)) {
- compute_clr_set(vcpu, HFGRTR_EL2, r_clr, r_set);
- compute_clr_set(vcpu, HFGWTR_EL2, w_clr, w_set);
- }
-
- /* The default to trap everything not handled or supported in KVM. */
- tmp = HFGxTR_EL2_nAMAIR2_EL1 | HFGxTR_EL2_nMAIR2_EL1 | HFGxTR_EL2_nS2POR_EL1 |
- HFGxTR_EL2_nPOR_EL1 | HFGxTR_EL2_nPOR_EL0 | HFGxTR_EL2_nACCDATA_EL1;
-
- r_val = __HFGRTR_EL2_nMASK & ~tmp;
- r_val |= r_set;
- r_val &= ~r_clr;
-
- w_val = __HFGWTR_EL2_nMASK & ~tmp;
- w_val |= w_set;
- w_val &= ~w_clr;
-
- write_sysreg_s(r_val, SYS_HFGRTR_EL2);
- write_sysreg_s(w_val, SYS_HFGWTR_EL2);
-
- if (!vcpu_has_nv(vcpu) || is_hyp_ctxt(vcpu))
- return;
-
- update_fgt_traps(vcpu, HFGITR_EL2);
- update_fgt_traps(vcpu, HDFGRTR_EL2);
- update_fgt_traps(vcpu, HDFGWTR_EL2);
+ update_fgt_traps(hctxt, vcpu, kvm, HFGRTR_EL2);
+ update_fgt_traps_cs(hctxt, vcpu, kvm, HFGWTR_EL2, 0,
+ cpus_have_final_cap(ARM64_WORKAROUND_AMPERE_AC03_CPU_38) ?
+ HFGxTR_EL2_TCR_EL1_MASK : 0);
+ update_fgt_traps(hctxt, vcpu, kvm, HFGITR_EL2);
+ update_fgt_traps(hctxt, vcpu, kvm, HDFGRTR_EL2);
+ update_fgt_traps(hctxt, vcpu, kvm, HDFGWTR_EL2);
if (cpu_has_amu())
- update_fgt_traps(vcpu, HAFGRTR_EL2);
+ update_fgt_traps(hctxt, vcpu, kvm, HAFGRTR_EL2);
}
+#define __deactivate_fgt(htcxt, vcpu, kvm, reg) \
+ do { \
+ if ((vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu)) || \
+ kvm->arch.fgu[reg_to_fgt_group_id(reg)]) \
+ write_sysreg_s(ctxt_sys_reg(hctxt, reg), \
+ SYS_ ## reg); \
+ } while(0)
+
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 *kvm = kern_hyp_va(vcpu->kvm);
if (!cpus_have_final_cap(ARM64_HAS_FGT))
return;
- write_sysreg_s(ctxt_sys_reg(hctxt, HFGRTR_EL2), SYS_HFGRTR_EL2);
- write_sysreg_s(ctxt_sys_reg(hctxt, HFGWTR_EL2), SYS_HFGWTR_EL2);
-
- if (!vcpu_has_nv(vcpu) || is_hyp_ctxt(vcpu))
- return;
-
- write_sysreg_s(ctxt_sys_reg(hctxt, HFGITR_EL2), SYS_HFGITR_EL2);
- write_sysreg_s(ctxt_sys_reg(hctxt, HDFGRTR_EL2), SYS_HDFGRTR_EL2);
- write_sysreg_s(ctxt_sys_reg(hctxt, HDFGWTR_EL2), SYS_HDFGWTR_EL2);
+ __deactivate_fgt(hctxt, vcpu, kvm, HFGRTR_EL2);
+ if (cpus_have_final_cap(ARM64_WORKAROUND_AMPERE_AC03_CPU_38))
+ write_sysreg_s(ctxt_sys_reg(hctxt, HFGWTR_EL2), SYS_HFGWTR_EL2);
+ else
+ __deactivate_fgt(hctxt, vcpu, kvm, HFGWTR_EL2);
+ __deactivate_fgt(hctxt, vcpu, kvm, HFGITR_EL2);
+ __deactivate_fgt(hctxt, vcpu, kvm, HDFGRTR_EL2);
+ __deactivate_fgt(hctxt, vcpu, kvm, HDFGWTR_EL2);
if (cpu_has_amu())
- write_sysreg_s(ctxt_sys_reg(hctxt, HAFGRTR_EL2), SYS_HAFGRTR_EL2);
+ __deactivate_fgt(hctxt, vcpu, kvm, HAFGRTR_EL2);
}
static inline void __activate_traps_common(struct kvm_vcpu *vcpu)
@@ -230,7 +236,7 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu)
write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2);
if (cpus_have_final_cap(ARM64_HAS_HCX)) {
- u64 hcrx = HCRX_GUEST_FLAGS;
+ u64 hcrx = vcpu->arch.hcrx_el2;
if (vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu)) {
u64 clr = 0, set = 0;
diff --git a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
index bb6b571ec627..4be6a7fa0070 100644
--- a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
+++ b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
@@ -27,16 +27,34 @@ static inline void __sysreg_save_user_state(struct kvm_cpu_context *ctxt)
ctxt_sys_reg(ctxt, TPIDRRO_EL0) = read_sysreg(tpidrro_el0);
}
-static inline bool ctxt_has_mte(struct kvm_cpu_context *ctxt)
+static inline struct kvm_vcpu *ctxt_to_vcpu(struct kvm_cpu_context *ctxt)
{
struct kvm_vcpu *vcpu = ctxt->__hyp_running_vcpu;
if (!vcpu)
vcpu = container_of(ctxt, struct kvm_vcpu, arch.ctxt);
+ return vcpu;
+}
+
+static inline bool ctxt_has_mte(struct kvm_cpu_context *ctxt)
+{
+ struct kvm_vcpu *vcpu = ctxt_to_vcpu(ctxt);
+
return kvm_has_mte(kern_hyp_va(vcpu->kvm));
}
+static inline bool ctxt_has_s1pie(struct kvm_cpu_context *ctxt)
+{
+ struct kvm_vcpu *vcpu;
+
+ if (!cpus_have_final_cap(ARM64_HAS_S1PIE))
+ return false;
+
+ vcpu = ctxt_to_vcpu(ctxt);
+ return kvm_has_feat(kern_hyp_va(vcpu->kvm), ID_AA64MMFR3_EL1, S1PIE, IMP);
+}
+
static inline void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt)
{
ctxt_sys_reg(ctxt, SCTLR_EL1) = read_sysreg_el1(SYS_SCTLR);
@@ -55,7 +73,7 @@ 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 (cpus_have_final_cap(ARM64_HAS_S1PIE)) {
+ 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);
}
@@ -131,7 +149,7 @@ 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 (cpus_have_final_cap(ARM64_HAS_S1PIE)) {
+ 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);
}
diff --git a/arch/arm64/kvm/hyp/nvhe/debug-sr.c b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
index 4558c02eb352..7746ea507b6f 100644
--- a/arch/arm64/kvm/hyp/nvhe/debug-sr.c
+++ b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
@@ -31,8 +31,8 @@ static void __debug_save_spe(u64 *pmscr_el1)
return;
/* Yes; save the control register and disable data generation */
- *pmscr_el1 = read_sysreg_s(SYS_PMSCR_EL1);
- write_sysreg_s(0, SYS_PMSCR_EL1);
+ *pmscr_el1 = read_sysreg_el1(SYS_PMSCR);
+ write_sysreg_el1(0, SYS_PMSCR);
isb();
/* Now drain all buffered data to memory */
@@ -48,7 +48,7 @@ static void __debug_restore_spe(u64 pmscr_el1)
isb();
/* Re-enable data generation */
- write_sysreg_s(pmscr_el1, SYS_PMSCR_EL1);
+ write_sysreg_el1(pmscr_el1, SYS_PMSCR);
}
static void __debug_save_trace(u64 *trfcr_el1)
@@ -63,8 +63,8 @@ static void __debug_save_trace(u64 *trfcr_el1)
* Since access to TRFCR_EL1 is trapped, the guest can't
* modify the filtering set by the host.
*/
- *trfcr_el1 = read_sysreg_s(SYS_TRFCR_EL1);
- write_sysreg_s(0, SYS_TRFCR_EL1);
+ *trfcr_el1 = read_sysreg_el1(SYS_TRFCR);
+ write_sysreg_el1(0, SYS_TRFCR);
isb();
/* Drain the trace buffer to memory */
tsb_csync();
@@ -76,7 +76,7 @@ static void __debug_restore_trace(u64 trfcr_el1)
return;
/* Restore trace filter controls */
- write_sysreg_s(trfcr_el1, SYS_TRFCR_EL1);
+ write_sysreg_el1(trfcr_el1, SYS_TRFCR);
}
void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu)
diff --git a/arch/arm64/kvm/hyp/nvhe/host.S b/arch/arm64/kvm/hyp/nvhe/host.S
index 7693a6757cd7..135cfb294ee5 100644
--- a/arch/arm64/kvm/hyp/nvhe/host.S
+++ b/arch/arm64/kvm/hyp/nvhe/host.S
@@ -110,7 +110,7 @@ SYM_FUNC_END(__host_enter)
* u64 elr, u64 par);
*/
SYM_FUNC_START(__hyp_do_panic)
- /* Prepare and exit to the host's panic funciton. */
+ /* Prepare and exit to the host's panic function. */
mov lr, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT | PSR_D_BIT |\
PSR_MODE_EL1h)
msr spsr_el2, lr
diff --git a/arch/arm64/kvm/hyp/nvhe/mm.c b/arch/arm64/kvm/hyp/nvhe/mm.c
index b01a3d1078a8..8850b591d775 100644
--- a/arch/arm64/kvm/hyp/nvhe/mm.c
+++ b/arch/arm64/kvm/hyp/nvhe/mm.c
@@ -155,7 +155,7 @@ int hyp_back_vmemmap(phys_addr_t back)
start = hyp_memory[i].base;
start = ALIGN_DOWN((u64)hyp_phys_to_page(start), PAGE_SIZE);
/*
- * The begining of the hyp_vmemmap region for the current
+ * The beginning of the hyp_vmemmap region for the current
* memblock may already be backed by the page backing the end
* the previous region, so avoid mapping it twice.
*/
@@ -408,7 +408,7 @@ static void *admit_host_page(void *arg)
return pop_hyp_memcache(host_mc, hyp_phys_to_virt);
}
-/* Refill our local memcache by poping pages from the one provided by the host. */
+/* Refill our local memcache by popping pages from the one provided by the host. */
int refill_memcache(struct kvm_hyp_memcache *mc, unsigned long min_pages,
struct kvm_hyp_memcache *host_mc)
{
diff --git a/arch/arm64/kvm/hyp/nvhe/tlb.c b/arch/arm64/kvm/hyp/nvhe/tlb.c
index a60fb13e2192..2fc68da4036d 100644
--- a/arch/arm64/kvm/hyp/nvhe/tlb.c
+++ b/arch/arm64/kvm/hyp/nvhe/tlb.c
@@ -154,7 +154,8 @@ void __kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu,
/* Switch to requested VMID */
__tlb_switch_to_guest(mmu, &cxt, false);
- __flush_s2_tlb_range_op(ipas2e1is, start, pages, stride, 0);
+ __flush_s2_tlb_range_op(ipas2e1is, start, pages, stride,
+ TLBI_TTL_UNKNOWN);
dsb(ish);
__tlbi(vmalle1is);
diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index ab9d05fcf98b..5a59ef88b646 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -528,7 +528,7 @@ static int hyp_unmap_walker(const struct kvm_pgtable_visit_ctx *ctx,
kvm_clear_pte(ctx->ptep);
dsb(ishst);
- __tlbi_level(vae2is, __TLBI_VADDR(ctx->addr, 0), ctx->level);
+ __tlbi_level(vae2is, __TLBI_VADDR(ctx->addr, 0), TLBI_TTL_UNKNOWN);
} else {
if (ctx->end - ctx->addr < granule)
return -EINVAL;
@@ -717,15 +717,29 @@ void kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu,
static int stage2_set_prot_attr(struct kvm_pgtable *pgt, enum kvm_pgtable_prot prot,
kvm_pte_t *ptep)
{
- bool device = prot & KVM_PGTABLE_PROT_DEVICE;
- kvm_pte_t attr = device ? KVM_S2_MEMATTR(pgt, DEVICE_nGnRE) :
- KVM_S2_MEMATTR(pgt, NORMAL);
+ kvm_pte_t attr;
u32 sh = KVM_PTE_LEAF_ATTR_LO_S2_SH_IS;
+ switch (prot & (KVM_PGTABLE_PROT_DEVICE |
+ KVM_PGTABLE_PROT_NORMAL_NC)) {
+ case KVM_PGTABLE_PROT_DEVICE | KVM_PGTABLE_PROT_NORMAL_NC:
+ return -EINVAL;
+ case KVM_PGTABLE_PROT_DEVICE:
+ if (prot & KVM_PGTABLE_PROT_X)
+ return -EINVAL;
+ attr = KVM_S2_MEMATTR(pgt, DEVICE_nGnRE);
+ break;
+ case KVM_PGTABLE_PROT_NORMAL_NC:
+ if (prot & KVM_PGTABLE_PROT_X)
+ return -EINVAL;
+ attr = KVM_S2_MEMATTR(pgt, NORMAL_NC);
+ break;
+ default:
+ attr = KVM_S2_MEMATTR(pgt, NORMAL);
+ }
+
if (!(prot & KVM_PGTABLE_PROT_X))
attr |= KVM_PTE_LEAF_ATTR_HI_S2_XN;
- else if (device)
- return -EINVAL;
if (prot & KVM_PGTABLE_PROT_R)
attr |= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R;
@@ -829,12 +843,15 @@ static bool stage2_try_break_pte(const struct kvm_pgtable_visit_ctx *ctx,
* Perform the appropriate TLB invalidation based on the
* evicted pte value (if any).
*/
- if (kvm_pte_table(ctx->old, ctx->level))
- kvm_tlb_flush_vmid_range(mmu, ctx->addr,
- kvm_granule_size(ctx->level));
- else if (kvm_pte_valid(ctx->old))
+ if (kvm_pte_table(ctx->old, ctx->level)) {
+ u64 size = kvm_granule_size(ctx->level);
+ u64 addr = ALIGN_DOWN(ctx->addr, size);
+
+ kvm_tlb_flush_vmid_range(mmu, addr, size);
+ } else if (kvm_pte_valid(ctx->old)) {
kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, mmu,
ctx->addr, ctx->level);
+ }
}
if (stage2_pte_is_counted(ctx->old))
@@ -882,9 +899,13 @@ static void stage2_unmap_put_pte(const struct kvm_pgtable_visit_ctx *ctx,
if (kvm_pte_valid(ctx->old)) {
kvm_clear_pte(ctx->ptep);
- if (!stage2_unmap_defer_tlb_flush(pgt))
- kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, mmu,
- ctx->addr, ctx->level);
+ if (kvm_pte_table(ctx->old, ctx->level)) {
+ kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, mmu, ctx->addr,
+ TLBI_TTL_UNKNOWN);
+ } else if (!stage2_unmap_defer_tlb_flush(pgt)) {
+ kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, mmu, ctx->addr,
+ ctx->level);
+ }
}
mm_ops->put_page(ctx->ptep);
diff --git a/arch/arm64/kvm/hyp/vhe/sysreg-sr.c b/arch/arm64/kvm/hyp/vhe/sysreg-sr.c
index 8e1e0d5033b6..a8b9ea496706 100644
--- a/arch/arm64/kvm/hyp/vhe/sysreg-sr.c
+++ b/arch/arm64/kvm/hyp/vhe/sysreg-sr.c
@@ -95,7 +95,7 @@ void __vcpu_load_switch_sysregs(struct kvm_vcpu *vcpu)
}
/**
- * __vcpu_put_switch_syregs - Restore host system registers to the physical CPU
+ * __vcpu_put_switch_sysregs - Restore host system registers to the physical CPU
*
* @vcpu: The VCPU pointer
*
diff --git a/arch/arm64/kvm/hyp/vhe/tlb.c b/arch/arm64/kvm/hyp/vhe/tlb.c
index b32e2940df7d..1a60b95381e8 100644
--- a/arch/arm64/kvm/hyp/vhe/tlb.c
+++ b/arch/arm64/kvm/hyp/vhe/tlb.c
@@ -171,7 +171,8 @@ void __kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu,
/* Switch to requested VMID */
__tlb_switch_to_guest(mmu, &cxt);
- __flush_s2_tlb_range_op(ipas2e1is, start, pages, stride, 0);
+ __flush_s2_tlb_range_op(ipas2e1is, start, pages, stride,
+ TLBI_TTL_UNKNOWN);
dsb(ish);
__tlbi(vmalle1is);
diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
index 0bd93a5f21ce..a640e839848e 100644
--- a/arch/arm64/kvm/inject_fault.c
+++ b/arch/arm64/kvm/inject_fault.c
@@ -134,7 +134,7 @@ static void inject_abt32(struct kvm_vcpu *vcpu, bool is_pabt, u32 addr)
if (vcpu_read_sys_reg(vcpu, TCR_EL1) & TTBCR_EAE) {
fsr = DFSR_LPAE | DFSR_FSC_EXTABT_LPAE;
} else {
- /* no need to shuffle FS[4] into DFSR[10] as its 0 */
+ /* no need to shuffle FS[4] into DFSR[10] as it's 0 */
fsr = DFSR_FSC_EXTABT_nLPAE;
}
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index d14504821b79..dc04bc767865 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -305,7 +305,7 @@ static void invalidate_icache_guest_page(void *va, size_t size)
* does.
*/
/**
- * unmap_stage2_range -- Clear stage2 page table entries to unmap a range
+ * __unmap_stage2_range -- Clear stage2 page table entries to unmap a range
* @mmu: The KVM stage-2 MMU pointer
* @start: The intermediate physical base address of the range to unmap
* @size: The size of the area to unmap
@@ -805,7 +805,7 @@ static int get_user_mapping_size(struct kvm *kvm, u64 addr)
.pgd = (kvm_pteref_t)kvm->mm->pgd,
.ia_bits = vabits_actual,
.start_level = (KVM_PGTABLE_LAST_LEVEL -
- CONFIG_PGTABLE_LEVELS + 1),
+ ARM64_HW_PGTABLE_LEVELS(pgt.ia_bits) + 1),
.mm_ops = &kvm_user_mm_ops,
};
unsigned long flags;
@@ -1381,7 +1381,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
int ret = 0;
bool write_fault, writable, force_pte = false;
bool exec_fault, mte_allowed;
- bool device = false;
+ bool device = false, vfio_allow_any_uc = false;
unsigned long mmu_seq;
struct kvm *kvm = vcpu->kvm;
struct kvm_mmu_memory_cache *memcache = &vcpu->arch.mmu_page_cache;
@@ -1472,6 +1472,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
gfn = fault_ipa >> PAGE_SHIFT;
mte_allowed = kvm_vma_mte_allowed(vma);
+ vfio_allow_any_uc = vma->vm_flags & VM_ALLOW_ANY_UNCACHED;
+
/* Don't use the VMA after the unlock -- it may have vanished */
vma = NULL;
@@ -1557,10 +1559,14 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
if (exec_fault)
prot |= KVM_PGTABLE_PROT_X;
- if (device)
- prot |= KVM_PGTABLE_PROT_DEVICE;
- else if (cpus_have_final_cap(ARM64_HAS_CACHE_DIC))
+ if (device) {
+ if (vfio_allow_any_uc)
+ prot |= KVM_PGTABLE_PROT_NORMAL_NC;
+ else
+ prot |= KVM_PGTABLE_PROT_DEVICE;
+ } else if (cpus_have_final_cap(ARM64_HAS_CACHE_DIC)) {
prot |= KVM_PGTABLE_PROT_X;
+ }
/*
* Under the premise of getting a FSC_PERM fault, we just need to relax
@@ -1631,7 +1637,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
fault_ipa = kvm_vcpu_get_fault_ipa(vcpu);
is_iabt = kvm_vcpu_trap_is_iabt(vcpu);
- if (esr_fsc_is_permission_fault(esr)) {
+ if (esr_fsc_is_translation_fault(esr)) {
/* Beyond sanitised PARange (which is the IPA limit) */
if (fault_ipa >= BIT_ULL(get_kvm_ipa_limit())) {
kvm_inject_size_fault(vcpu);
@@ -1874,16 +1880,9 @@ int __init kvm_mmu_init(u32 *hyp_va_bits)
BUG_ON((hyp_idmap_start ^ (hyp_idmap_end - 1)) & PAGE_MASK);
/*
- * The ID map may be configured to use an extended virtual address
- * range. This is only the case if system RAM is out of range for the
- * currently configured page size and VA_BITS_MIN, in which case we will
- * also need the extended virtual range for the HYP ID map, or we won't
- * be able to enable the EL2 MMU.
- *
- * However, in some cases the ID map may be configured for fewer than
- * the number of VA bits used by the regular kernel stage 1. This
- * happens when VA_BITS=52 and the kernel image is placed in PA space
- * below 48 bits.
+ * The ID map is always configured for 48 bits of translation, which
+ * may be fewer than the number of VA bits used by the regular kernel
+ * stage 1, when VA_BITS=52.
*
* At EL2, there is only one TTBR register, and we can't switch between
* translation tables *and* update TCR_EL2.T0SZ at the same time. Bottom
@@ -1894,7 +1893,7 @@ int __init kvm_mmu_init(u32 *hyp_va_bits)
* 1 VA bits to assure that the hypervisor can both ID map its code page
* and map any kernel memory.
*/
- idmap_bits = 64 - ((idmap_t0sz & TCR_T0SZ_MASK) >> TCR_T0SZ_OFFSET);
+ idmap_bits = IDMAP_VA_BITS;
kernel_bits = vabits_actual;
*hyp_va_bits = max(idmap_bits, kernel_bits);
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index ba95d044bc98..ced30c90521a 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -133,6 +133,13 @@ static u64 limit_nv_id_reg(u32 id, u64 val)
val |= FIELD_PREP(NV_FTR(MMFR2, TTL), 0b0001);
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);
+ break;
+
case SYS_ID_AA64DFR0_EL1:
/* Only limited support for PMU, Debug, BPs and WPs */
val &= (NV_FTR(DFR0, PMUVer) |
@@ -156,15 +163,280 @@ static u64 limit_nv_id_reg(u32 id, u64 val)
return val;
}
+
+u64 kvm_vcpu_sanitise_vncr_reg(const struct kvm_vcpu *vcpu, enum vcpu_sysreg sr)
+{
+ u64 v = ctxt_sys_reg(&vcpu->arch.ctxt, sr);
+ struct kvm_sysreg_masks *masks;
+
+ masks = vcpu->kvm->arch.sysreg_masks;
+
+ if (masks) {
+ sr -= __VNCR_START__;
+
+ v &= ~masks->mask[sr].res0;
+ v |= masks->mask[sr].res1;
+ }
+
+ return v;
+}
+
+static void set_sysreg_masks(struct kvm *kvm, int sr, u64 res0, u64 res1)
+{
+ int i = sr - __VNCR_START__;
+
+ kvm->arch.sysreg_masks->mask[i].res0 = res0;
+ kvm->arch.sysreg_masks->mask[i].res1 = res1;
+}
+
int kvm_init_nv_sysregs(struct kvm *kvm)
{
+ u64 res0, res1;
+ int ret = 0;
+
mutex_lock(&kvm->arch.config_lock);
+ if (kvm->arch.sysreg_masks)
+ goto out;
+
+ kvm->arch.sysreg_masks = kzalloc(sizeof(*(kvm->arch.sysreg_masks)),
+ GFP_KERNEL);
+ 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]);
+ /* VTTBR_EL2 */
+ res0 = res1 = 0;
+ if (!kvm_has_feat_enum(kvm, ID_AA64MMFR1_EL1, VMIDBits, 16))
+ res0 |= GENMASK(63, 56);
+ if (!kvm_has_feat(kvm, ID_AA64MMFR2_EL1, CnP, IMP))
+ res0 |= VTTBR_CNP_BIT;
+ set_sysreg_masks(kvm, VTTBR_EL2, res0, res1);
+
+ /* VTCR_EL2 */
+ res0 = GENMASK(63, 32) | GENMASK(30, 20);
+ res1 = BIT(31);
+ set_sysreg_masks(kvm, VTCR_EL2, res0, res1);
+
+ /* VMPIDR_EL2 */
+ res0 = GENMASK(63, 40) | GENMASK(30, 24);
+ res1 = BIT(31);
+ set_sysreg_masks(kvm, VMPIDR_EL2, res0, res1);
+
+ /* HCR_EL2 */
+ res0 = BIT(48);
+ res1 = HCR_RW;
+ if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, TWED, IMP))
+ res0 |= GENMASK(63, 59);
+ if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, MTE, MTE2))
+ res0 |= (HCR_TID5 | HCR_DCT | HCR_ATA);
+ if (!kvm_has_feat(kvm, ID_AA64MMFR2_EL1, EVT, TTLBxS))
+ res0 |= (HCR_TTLBIS | HCR_TTLBOS);
+ if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, CSV2, CSV2_2) &&
+ !kvm_has_feat(kvm, ID_AA64PFR1_EL1, CSV2_frac, CSV2_1p2))
+ res0 |= HCR_ENSCXT;
+ if (!kvm_has_feat(kvm, ID_AA64MMFR2_EL1, EVT, IMP))
+ res0 |= (HCR_TOCU | HCR_TICAB | HCR_TID4);
+ if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, AMU, V1P1))
+ res0 |= HCR_AMVOFFEN;
+ if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, V1P1))
+ res0 |= HCR_FIEN;
+ if (!kvm_has_feat(kvm, ID_AA64MMFR2_EL1, FWB, IMP))
+ res0 |= HCR_FWB;
+ if (!kvm_has_feat(kvm, ID_AA64MMFR2_EL1, NV, NV2))
+ res0 |= HCR_NV2;
+ if (!kvm_has_feat(kvm, ID_AA64MMFR2_EL1, NV, IMP))
+ res0 |= (HCR_AT | HCR_NV1 | HCR_NV);
+ if (!(__vcpu_has_feature(&kvm->arch, KVM_ARM_VCPU_PTRAUTH_ADDRESS) &&
+ __vcpu_has_feature(&kvm->arch, KVM_ARM_VCPU_PTRAUTH_GENERIC)))
+ res0 |= (HCR_API | HCR_APK);
+ if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TME, IMP))
+ res0 |= BIT(39);
+ if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, IMP))
+ res0 |= (HCR_TEA | HCR_TERR);
+ if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, LO, IMP))
+ res0 |= HCR_TLOR;
+ if (!kvm_has_feat(kvm, ID_AA64MMFR4_EL1, E2H0, IMP))
+ res1 |= HCR_E2H;
+ set_sysreg_masks(kvm, HCR_EL2, res0, res1);
+
+ /* HCRX_EL2 */
+ res0 = HCRX_EL2_RES0;
+ res1 = HCRX_EL2_RES1;
+ if (!kvm_has_feat(kvm, ID_AA64ISAR3_EL1, PACM, TRIVIAL_IMP))
+ res0 |= HCRX_EL2_PACMEn;
+ if (!kvm_has_feat(kvm, ID_AA64PFR2_EL1, FPMR, IMP))
+ res0 |= HCRX_EL2_EnFPM;
+ if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, GCS, IMP))
+ res0 |= HCRX_EL2_GCSEn;
+ if (!kvm_has_feat(kvm, ID_AA64ISAR2_EL1, SYSREG_128, IMP))
+ res0 |= HCRX_EL2_EnIDCP128;
+ if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, ADERR, DEV_ASYNC))
+ res0 |= (HCRX_EL2_EnSDERR | HCRX_EL2_EnSNERR);
+ if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, DF2, IMP))
+ res0 |= HCRX_EL2_TMEA;
+ if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, D128, IMP))
+ res0 |= HCRX_EL2_D128En;
+ if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, THE, IMP))
+ res0 |= HCRX_EL2_PTTWI;
+ if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, SCTLRX, IMP))
+ res0 |= HCRX_EL2_SCTLR2En;
+ if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, TCRX, IMP))
+ res0 |= HCRX_EL2_TCR2En;
+ if (!kvm_has_feat(kvm, ID_AA64ISAR2_EL1, MOPS, IMP))
+ res0 |= (HCRX_EL2_MSCEn | HCRX_EL2_MCE2);
+ if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, CMOW, IMP))
+ res0 |= HCRX_EL2_CMOW;
+ if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, NMI, IMP))
+ res0 |= (HCRX_EL2_VFNMI | HCRX_EL2_VINMI | HCRX_EL2_TALLINT);
+ if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, SME, IMP) ||
+ !(read_sysreg_s(SYS_SMIDR_EL1) & SMIDR_EL1_SMPS))
+ res0 |= HCRX_EL2_SMPME;
+ if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, XS, IMP))
+ res0 |= (HCRX_EL2_FGTnXS | HCRX_EL2_FnXS);
+ if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, LS64, LS64_V))
+ res0 |= HCRX_EL2_EnASR;
+ if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, LS64, LS64))
+ res0 |= HCRX_EL2_EnALS;
+ if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, LS64, LS64_ACCDATA))
+ res0 |= HCRX_EL2_EnAS0;
+ set_sysreg_masks(kvm, HCRX_EL2, res0, res1);
+
+ /* HFG[RW]TR_EL2 */
+ res0 = res1 = 0;
+ if (!(__vcpu_has_feature(&kvm->arch, KVM_ARM_VCPU_PTRAUTH_ADDRESS) &&
+ __vcpu_has_feature(&kvm->arch, KVM_ARM_VCPU_PTRAUTH_GENERIC)))
+ res0 |= (HFGxTR_EL2_APDAKey | HFGxTR_EL2_APDBKey |
+ HFGxTR_EL2_APGAKey | HFGxTR_EL2_APIAKey |
+ HFGxTR_EL2_APIBKey);
+ if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, LO, IMP))
+ res0 |= (HFGxTR_EL2_LORC_EL1 | HFGxTR_EL2_LOREA_EL1 |
+ HFGxTR_EL2_LORID_EL1 | HFGxTR_EL2_LORN_EL1 |
+ HFGxTR_EL2_LORSA_EL1);
+ if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, CSV2, CSV2_2) &&
+ !kvm_has_feat(kvm, ID_AA64PFR1_EL1, CSV2_frac, CSV2_1p2))
+ res0 |= (HFGxTR_EL2_SCXTNUM_EL1 | HFGxTR_EL2_SCXTNUM_EL0);
+ if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, GIC, IMP))
+ res0 |= HFGxTR_EL2_ICC_IGRPENn_EL1;
+ if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, IMP))
+ res0 |= (HFGxTR_EL2_ERRIDR_EL1 | HFGxTR_EL2_ERRSELR_EL1 |
+ HFGxTR_EL2_ERXFR_EL1 | HFGxTR_EL2_ERXCTLR_EL1 |
+ HFGxTR_EL2_ERXSTATUS_EL1 | HFGxTR_EL2_ERXMISCn_EL1 |
+ HFGxTR_EL2_ERXPFGF_EL1 | HFGxTR_EL2_ERXPFGCTL_EL1 |
+ HFGxTR_EL2_ERXPFGCDN_EL1 | HFGxTR_EL2_ERXADDR_EL1);
+ if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, LS64, LS64_ACCDATA))
+ res0 |= HFGxTR_EL2_nACCDATA_EL1;
+ if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, GCS, IMP))
+ res0 |= (HFGxTR_EL2_nGCS_EL0 | HFGxTR_EL2_nGCS_EL1);
+ if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, SME, IMP))
+ res0 |= (HFGxTR_EL2_nSMPRI_EL1 | HFGxTR_EL2_nTPIDR2_EL0);
+ if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, THE, IMP))
+ res0 |= HFGxTR_EL2_nRCWMASK_EL1;
+ if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, S1PIE, IMP))
+ res0 |= (HFGxTR_EL2_nPIRE0_EL1 | HFGxTR_EL2_nPIR_EL1);
+ if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, S1POE, IMP))
+ res0 |= (HFGxTR_EL2_nPOR_EL0 | HFGxTR_EL2_nPOR_EL1);
+ if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, S2POE, IMP))
+ res0 |= HFGxTR_EL2_nS2POR_EL1;
+ if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, AIE, IMP))
+ res0 |= (HFGxTR_EL2_nMAIR2_EL1 | HFGxTR_EL2_nAMAIR2_EL1);
+ set_sysreg_masks(kvm, HFGRTR_EL2, res0 | __HFGRTR_EL2_RES0, res1);
+ set_sysreg_masks(kvm, HFGWTR_EL2, res0 | __HFGWTR_EL2_RES0, res1);
+
+ /* HDFG[RW]TR_EL2 */
+ res0 = res1 = 0;
+ if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, DoubleLock, IMP))
+ res0 |= HDFGRTR_EL2_OSDLR_EL1;
+ if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMUVer, IMP))
+ res0 |= (HDFGRTR_EL2_PMEVCNTRn_EL0 | HDFGRTR_EL2_PMEVTYPERn_EL0 |
+ HDFGRTR_EL2_PMCCFILTR_EL0 | HDFGRTR_EL2_PMCCNTR_EL0 |
+ HDFGRTR_EL2_PMCNTEN | HDFGRTR_EL2_PMINTEN |
+ HDFGRTR_EL2_PMOVS | HDFGRTR_EL2_PMSELR_EL0 |
+ HDFGRTR_EL2_PMMIR_EL1 | HDFGRTR_EL2_PMUSERENR_EL0 |
+ HDFGRTR_EL2_PMCEIDn_EL0);
+ if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMSVer, IMP))
+ res0 |= (HDFGRTR_EL2_PMBLIMITR_EL1 | HDFGRTR_EL2_PMBPTR_EL1 |
+ HDFGRTR_EL2_PMBSR_EL1 | HDFGRTR_EL2_PMSCR_EL1 |
+ HDFGRTR_EL2_PMSEVFR_EL1 | HDFGRTR_EL2_PMSFCR_EL1 |
+ HDFGRTR_EL2_PMSICR_EL1 | HDFGRTR_EL2_PMSIDR_EL1 |
+ HDFGRTR_EL2_PMSIRR_EL1 | HDFGRTR_EL2_PMSLATFR_EL1 |
+ HDFGRTR_EL2_PMBIDR_EL1);
+ if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceVer, IMP))
+ res0 |= (HDFGRTR_EL2_TRC | HDFGRTR_EL2_TRCAUTHSTATUS |
+ HDFGRTR_EL2_TRCAUXCTLR | HDFGRTR_EL2_TRCCLAIM |
+ HDFGRTR_EL2_TRCCNTVRn | HDFGRTR_EL2_TRCID |
+ HDFGRTR_EL2_TRCIMSPECn | HDFGRTR_EL2_TRCOSLSR |
+ HDFGRTR_EL2_TRCPRGCTLR | HDFGRTR_EL2_TRCSEQSTR |
+ HDFGRTR_EL2_TRCSSCSRn | HDFGRTR_EL2_TRCSTATR |
+ HDFGRTR_EL2_TRCVICTLR);
+ if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceBuffer, IMP))
+ res0 |= (HDFGRTR_EL2_TRBBASER_EL1 | HDFGRTR_EL2_TRBIDR_EL1 |
+ HDFGRTR_EL2_TRBLIMITR_EL1 | HDFGRTR_EL2_TRBMAR_EL1 |
+ HDFGRTR_EL2_TRBPTR_EL1 | HDFGRTR_EL2_TRBSR_EL1 |
+ HDFGRTR_EL2_TRBTRG_EL1);
+ if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, BRBE, IMP))
+ res0 |= (HDFGRTR_EL2_nBRBIDR | HDFGRTR_EL2_nBRBCTL |
+ HDFGRTR_EL2_nBRBDATA);
+ if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMSVer, V1P2))
+ res0 |= HDFGRTR_EL2_nPMSNEVFR_EL1;
+ set_sysreg_masks(kvm, HDFGRTR_EL2, res0 | HDFGRTR_EL2_RES0, res1);
+
+ /* Reuse the bits from the read-side and add the write-specific stuff */
+ if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, PMUVer, IMP))
+ res0 |= (HDFGWTR_EL2_PMCR_EL0 | HDFGWTR_EL2_PMSWINC_EL0);
+ if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceVer, IMP))
+ res0 |= HDFGWTR_EL2_TRCOSLAR;
+ if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceFilt, IMP))
+ res0 |= HDFGWTR_EL2_TRFCR_EL1;
+ set_sysreg_masks(kvm, HFGWTR_EL2, res0 | HDFGWTR_EL2_RES0, res1);
+
+ /* HFGITR_EL2 */
+ res0 = HFGITR_EL2_RES0;
+ res1 = HFGITR_EL2_RES1;
+ if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, DPB, DPB2))
+ res0 |= HFGITR_EL2_DCCVADP;
+ if (!kvm_has_feat(kvm, ID_AA64MMFR1_EL1, PAN, PAN2))
+ res0 |= (HFGITR_EL2_ATS1E1RP | HFGITR_EL2_ATS1E1WP);
+ if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, OS))
+ res0 |= (HFGITR_EL2_TLBIRVAALE1OS | HFGITR_EL2_TLBIRVALE1OS |
+ HFGITR_EL2_TLBIRVAAE1OS | HFGITR_EL2_TLBIRVAE1OS |
+ HFGITR_EL2_TLBIVAALE1OS | HFGITR_EL2_TLBIVALE1OS |
+ HFGITR_EL2_TLBIVAAE1OS | HFGITR_EL2_TLBIASIDE1OS |
+ HFGITR_EL2_TLBIVAE1OS | HFGITR_EL2_TLBIVMALLE1OS);
+ if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, RANGE))
+ res0 |= (HFGITR_EL2_TLBIRVAALE1 | HFGITR_EL2_TLBIRVALE1 |
+ HFGITR_EL2_TLBIRVAAE1 | HFGITR_EL2_TLBIRVAE1 |
+ HFGITR_EL2_TLBIRVAALE1IS | HFGITR_EL2_TLBIRVALE1IS |
+ HFGITR_EL2_TLBIRVAAE1IS | HFGITR_EL2_TLBIRVAE1IS |
+ HFGITR_EL2_TLBIRVAALE1OS | HFGITR_EL2_TLBIRVALE1OS |
+ HFGITR_EL2_TLBIRVAAE1OS | HFGITR_EL2_TLBIRVAE1OS);
+ if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, SPECRES, IMP))
+ res0 |= (HFGITR_EL2_CFPRCTX | HFGITR_EL2_DVPRCTX |
+ HFGITR_EL2_CPPRCTX);
+ if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, BRBE, IMP))
+ res0 |= (HFGITR_EL2_nBRBINJ | HFGITR_EL2_nBRBIALL);
+ if (!kvm_has_feat(kvm, ID_AA64PFR1_EL1, GCS, IMP))
+ res0 |= (HFGITR_EL2_nGCSPUSHM_EL1 | HFGITR_EL2_nGCSSTR_EL1 |
+ HFGITR_EL2_nGCSEPP);
+ if (!kvm_has_feat(kvm, ID_AA64ISAR1_EL1, SPECRES, COSP_RCTX))
+ res0 |= HFGITR_EL2_COSPRCTX;
+ if (!kvm_has_feat(kvm, ID_AA64ISAR2_EL1, ATS1A, IMP))
+ res0 |= HFGITR_EL2_ATS1E1A;
+ set_sysreg_masks(kvm, HFGITR_EL2, res0, res1);
+
+ /* HAFGRTR_EL2 - not a lot to see here */
+ res0 = HAFGRTR_EL2_RES0;
+ res1 = HAFGRTR_EL2_RES1;
+ if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, AMU, V1P1))
+ res0 |= ~(res0 | res1);
+ set_sysreg_masks(kvm, HAFGRTR_EL2, res0, res1);
+out:
mutex_unlock(&kvm->arch.config_lock);
- return 0;
+ return ret;
}
diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index 3d9467ff73bc..a35ce10e0a9f 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -64,12 +64,11 @@ u64 kvm_pmu_evtyper_mask(struct kvm *kvm)
{
u64 mask = ARMV8_PMU_EXCLUDE_EL1 | ARMV8_PMU_EXCLUDE_EL0 |
kvm_pmu_event_mask(kvm);
- u64 pfr0 = IDREG(kvm, SYS_ID_AA64PFR0_EL1);
- if (SYS_FIELD_GET(ID_AA64PFR0_EL1, EL2, pfr0))
+ if (kvm_has_feat(kvm, ID_AA64PFR0_EL1, EL2, IMP))
mask |= ARMV8_PMU_INCLUDE_EL2;
- if (SYS_FIELD_GET(ID_AA64PFR0_EL1, EL3, pfr0))
+ if (kvm_has_feat(kvm, ID_AA64PFR0_EL1, EL3, IMP))
mask |= ARMV8_PMU_EXCLUDE_NS_EL0 |
ARMV8_PMU_EXCLUDE_NS_EL1 |
ARMV8_PMU_EXCLUDE_EL3;
@@ -83,8 +82,10 @@ u64 kvm_pmu_evtyper_mask(struct kvm *kvm)
*/
static bool kvm_pmc_is_64bit(struct kvm_pmc *pmc)
{
+ struct kvm_vcpu *vcpu = kvm_pmc_to_vcpu(pmc);
+
return (pmc->idx == ARMV8_PMU_CYCLE_IDX ||
- kvm_pmu_is_3p5(kvm_pmc_to_vcpu(pmc)));
+ kvm_has_feat(vcpu->kvm, ID_AA64DFR0_EL1, PMUVer, V3P5));
}
static bool kvm_pmc_has_64bit_overflow(struct kvm_pmc *pmc)
@@ -419,7 +420,7 @@ void kvm_pmu_sync_hwstate(struct kvm_vcpu *vcpu)
kvm_pmu_update_state(vcpu);
}
-/**
+/*
* When perf interrupt is an NMI, we cannot safely notify the vcpu corresponding
* to the event.
* This is why we need a callback to do it once outside of the NMI context.
@@ -490,7 +491,7 @@ static u64 compute_period(struct kvm_pmc *pmc, u64 counter)
return val;
}
-/**
+/*
* When the perf event overflows, set the overflow status and inform the vcpu.
*/
static void kvm_pmu_perf_overflow(struct perf_event *perf_event,
@@ -556,7 +557,7 @@ void kvm_pmu_handle_pmcr(struct kvm_vcpu *vcpu, u64 val)
return;
/* Fixup PMCR_EL0 to reconcile the PMU version and the LP bit */
- if (!kvm_pmu_is_3p5(vcpu))
+ if (!kvm_has_feat(vcpu->kvm, ID_AA64DFR0_EL1, PMUVer, V3P5))
val &= ~ARMV8_PMU_PMCR_LP;
/* The reset bits don't indicate any state, and shouldn't be saved. */
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 30253bd19917..c9f4f387155f 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -12,6 +12,7 @@
#include <linux/bitfield.h>
#include <linux/bsearch.h>
#include <linux/cacheinfo.h>
+#include <linux/debugfs.h>
#include <linux/kvm_host.h>
#include <linux/mm.h>
#include <linux/printk.h>
@@ -505,10 +506,9 @@ static bool trap_loregion(struct kvm_vcpu *vcpu,
struct sys_reg_params *p,
const struct sys_reg_desc *r)
{
- u64 val = IDREG(vcpu->kvm, SYS_ID_AA64MMFR1_EL1);
u32 sr = reg_to_encoding(r);
- if (!(val & (0xfUL << ID_AA64MMFR1_EL1_LO_SHIFT))) {
+ if (!kvm_has_feat(vcpu->kvm, ID_AA64MMFR1_EL1, LO, IMP)) {
kvm_inject_undefined(vcpu);
return false;
}
@@ -1685,7 +1685,8 @@ static u64 read_sanitised_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
u64 __f_val = FIELD_GET(reg##_##field##_MASK, val); \
(val) &= ~reg##_##field##_MASK; \
(val) |= FIELD_PREP(reg##_##field##_MASK, \
- min(__f_val, (u64)reg##_##field##_##limit)); \
+ min(__f_val, \
+ (u64)SYS_FIELD_VALUE(reg, field, limit))); \
(val); \
})
@@ -2174,6 +2175,16 @@ static bool access_spsr(struct kvm_vcpu *vcpu,
return true;
}
+static u64 reset_hcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
+{
+ u64 val = r->val;
+
+ if (!cpus_have_final_cap(ARM64_HAS_HCR_NV1))
+ val |= HCR_E2H;
+
+ return __vcpu_sys_reg(vcpu, r->reg) = val;
+}
+
/*
* Architected system registers.
* Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2
@@ -2186,16 +2197,6 @@ static bool access_spsr(struct kvm_vcpu *vcpu,
* guest...
*/
static const struct sys_reg_desc sys_reg_descs[] = {
- { SYS_DESC(SYS_DC_ISW), access_dcsw },
- { SYS_DESC(SYS_DC_IGSW), access_dcgsw },
- { SYS_DESC(SYS_DC_IGDSW), access_dcgsw },
- { SYS_DESC(SYS_DC_CSW), access_dcsw },
- { SYS_DESC(SYS_DC_CGSW), access_dcgsw },
- { SYS_DESC(SYS_DC_CGDSW), access_dcgsw },
- { SYS_DESC(SYS_DC_CISW), access_dcsw },
- { SYS_DESC(SYS_DC_CIGSW), access_dcgsw },
- { SYS_DESC(SYS_DC_CIGDSW), access_dcgsw },
-
DBG_BCR_BVR_WCR_WVR_EL1(0),
DBG_BCR_BVR_WCR_WVR_EL1(1),
{ SYS_DESC(SYS_MDCCINT_EL1), trap_debug_regs, reset_val, MDCCINT_EL1, 0 },
@@ -2349,7 +2350,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
ID_AA64MMFR2_EL1_NV |
ID_AA64MMFR2_EL1_CCIDX)),
ID_SANITISED(ID_AA64MMFR3_EL1),
- ID_UNALLOCATED(7,4),
+ ID_SANITISED(ID_AA64MMFR4_EL1),
ID_UNALLOCATED(7,5),
ID_UNALLOCATED(7,6),
ID_UNALLOCATED(7,7),
@@ -2665,7 +2666,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
EL2_REG_VNCR(VMPIDR_EL2, reset_unknown, 0),
EL2_REG(SCTLR_EL2, access_rw, reset_val, SCTLR_EL2_RES1),
EL2_REG(ACTLR_EL2, access_rw, reset_val, 0),
- EL2_REG_VNCR(HCR_EL2, reset_val, 0),
+ EL2_REG_VNCR(HCR_EL2, reset_hcr, 0),
EL2_REG(MDCR_EL2, access_rw, reset_val, 0),
EL2_REG(CPTR_EL2, access_rw, reset_val, CPTR_NVHE_EL2_RES1),
EL2_REG_VNCR(HSTR_EL2, reset_val, 0),
@@ -2727,6 +2728,18 @@ static const struct sys_reg_desc sys_reg_descs[] = {
EL2_REG(SP_EL2, NULL, reset_unknown, 0),
};
+static struct sys_reg_desc sys_insn_descs[] = {
+ { SYS_DESC(SYS_DC_ISW), access_dcsw },
+ { SYS_DESC(SYS_DC_IGSW), access_dcgsw },
+ { SYS_DESC(SYS_DC_IGDSW), access_dcgsw },
+ { SYS_DESC(SYS_DC_CSW), access_dcsw },
+ { SYS_DESC(SYS_DC_CGSW), access_dcgsw },
+ { SYS_DESC(SYS_DC_CGDSW), access_dcgsw },
+ { 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;
static bool trap_dbgdidr(struct kvm_vcpu *vcpu,
@@ -2737,8 +2750,7 @@ static bool trap_dbgdidr(struct kvm_vcpu *vcpu,
return ignore_write(vcpu, p);
} else {
u64 dfr = IDREG(vcpu->kvm, SYS_ID_AA64DFR0_EL1);
- u64 pfr = IDREG(vcpu->kvm, SYS_ID_AA64PFR0_EL1);
- u32 el3 = !!SYS_FIELD_GET(ID_AA64PFR0_EL1, EL3, pfr);
+ u32 el3 = kvm_has_feat(vcpu->kvm, ID_AA64PFR0_EL1, EL3, IMP);
p->regval = ((SYS_FIELD_GET(ID_AA64DFR0_EL1, WRPs, dfr) << 28) |
(SYS_FIELD_GET(ID_AA64DFR0_EL1, BRPs, dfr) << 24) |
@@ -3159,7 +3171,8 @@ static void unhandled_cp_access(struct kvm_vcpu *vcpu,
/**
* kvm_handle_cp_64 -- handles a mrrc/mcrr trap on a guest CP14/CP15 access
* @vcpu: The VCPU pointer
- * @run: The kvm_run struct
+ * @global: &struct sys_reg_desc
+ * @nr_global: size of the @global array
*/
static int kvm_handle_cp_64(struct kvm_vcpu *vcpu,
const struct sys_reg_desc *global,
@@ -3326,7 +3339,9 @@ static int kvm_emulate_cp15_id_reg(struct kvm_vcpu *vcpu,
/**
* kvm_handle_cp_32 -- handles a mrc/mcr trap on a guest CP14/CP15 access
* @vcpu: The VCPU pointer
- * @run: The kvm_run struct
+ * @params: &struct sys_reg_params
+ * @global: &struct sys_reg_desc
+ * @nr_global: size of the @global array
*/
static int kvm_handle_cp_32(struct kvm_vcpu *vcpu,
struct sys_reg_params *params,
@@ -3384,12 +3399,6 @@ int kvm_handle_cp14_32(struct kvm_vcpu *vcpu)
return kvm_handle_cp_32(vcpu, &params, cp14_regs, ARRAY_SIZE(cp14_regs));
}
-static bool is_imp_def_sys_reg(struct sys_reg_params *params)
-{
- // See ARM DDI 0487E.a, section D12.3.2
- return params->Op0 == 3 && (params->CRn & 0b1011) == 0b1011;
-}
-
/**
* emulate_sys_reg - Emulate a guest access to an AArch64 system register
* @vcpu: The VCPU pointer
@@ -3398,26 +3407,106 @@ static bool is_imp_def_sys_reg(struct sys_reg_params *params)
* Return: true if the system register access was successful, false otherwise.
*/
static bool emulate_sys_reg(struct kvm_vcpu *vcpu,
- struct sys_reg_params *params)
+ struct sys_reg_params *params)
{
const struct sys_reg_desc *r;
r = find_reg(params, sys_reg_descs, ARRAY_SIZE(sys_reg_descs));
-
if (likely(r)) {
perform_access(vcpu, params, r);
return true;
}
- if (is_imp_def_sys_reg(params)) {
- kvm_inject_undefined(vcpu);
+ print_sys_reg_msg(params,
+ "Unsupported guest sys_reg access at: %lx [%08lx]\n",
+ *vcpu_pc(vcpu), *vcpu_cpsr(vcpu));
+ kvm_inject_undefined(vcpu);
+
+ return false;
+}
+
+static void *idregs_debug_start(struct seq_file *s, loff_t *pos)
+{
+ struct kvm *kvm = s->private;
+ u8 *iter;
+
+ mutex_lock(&kvm->arch.config_lock);
+
+ iter = &kvm->arch.idreg_debugfs_iter;
+ if (test_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &kvm->arch.flags) &&
+ *iter == (u8)~0) {
+ *iter = *pos;
+ if (*iter >= KVM_ARM_ID_REG_NUM)
+ iter = NULL;
} else {
- print_sys_reg_msg(params,
- "Unsupported guest sys_reg access at: %lx [%08lx]\n",
- *vcpu_pc(vcpu), *vcpu_cpsr(vcpu));
- kvm_inject_undefined(vcpu);
+ iter = ERR_PTR(-EBUSY);
}
- return false;
+
+ mutex_unlock(&kvm->arch.config_lock);
+
+ return iter;
+}
+
+static void *idregs_debug_next(struct seq_file *s, void *v, loff_t *pos)
+{
+ struct kvm *kvm = s->private;
+
+ (*pos)++;
+
+ if ((kvm->arch.idreg_debugfs_iter + 1) < KVM_ARM_ID_REG_NUM) {
+ kvm->arch.idreg_debugfs_iter++;
+
+ return &kvm->arch.idreg_debugfs_iter;
+ }
+
+ return NULL;
+}
+
+static void idregs_debug_stop(struct seq_file *s, void *v)
+{
+ struct kvm *kvm = s->private;
+
+ if (IS_ERR(v))
+ return;
+
+ mutex_lock(&kvm->arch.config_lock);
+
+ kvm->arch.idreg_debugfs_iter = ~0;
+
+ mutex_unlock(&kvm->arch.config_lock);
+}
+
+static int idregs_debug_show(struct seq_file *s, void *v)
+{
+ struct kvm *kvm = s->private;
+ const struct sys_reg_desc *desc;
+
+ desc = first_idreg + 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)));
+
+ return 0;
+}
+
+static const struct seq_operations idregs_debug_sops = {
+ .start = idregs_debug_start,
+ .next = idregs_debug_next,
+ .stop = idregs_debug_stop,
+ .show = idregs_debug_show,
+};
+
+DEFINE_SEQ_ATTRIBUTE(idregs_debug);
+
+void kvm_sys_regs_create_debugfs(struct kvm *kvm)
+{
+ kvm->arch.idreg_debugfs_iter = ~0;
+
+ debugfs_create_file("idregs", 0444, kvm->debugfs_dentry, kvm,
+ &idregs_debug_fops);
}
static void kvm_reset_id_regs(struct kvm_vcpu *vcpu)
@@ -3467,28 +3556,39 @@ void kvm_reset_sys_regs(struct kvm_vcpu *vcpu)
}
/**
- * kvm_handle_sys_reg -- handles a mrs/msr trap on a guest sys_reg access
+ * kvm_handle_sys_reg -- handles a system instruction or mrs/msr instruction
+ * trap on a guest execution
* @vcpu: The VCPU pointer
*/
int kvm_handle_sys_reg(struct kvm_vcpu *vcpu)
{
+ const struct sys_reg_desc *desc = NULL;
struct sys_reg_params params;
unsigned long esr = kvm_vcpu_get_esr(vcpu);
int Rt = kvm_vcpu_sys_get_rt(vcpu);
+ int sr_idx;
trace_kvm_handle_sys_reg(esr);
- if (__check_nv_sr_forward(vcpu))
+ if (triage_sysreg_trap(vcpu, &sr_idx))
return 1;
params = esr_sys64_to_params(esr);
params.regval = vcpu_get_reg(vcpu, Rt);
- if (!emulate_sys_reg(vcpu, &params))
- return 1;
+ /* System registers have Op0=={2,3}, as per DDI487 J.a C5.1.2 */
+ if (params.Op0 == 2 || params.Op0 == 3)
+ desc = &sys_reg_descs[sr_idx];
+ else
+ desc = &sys_insn_descs[sr_idx];
+
+ perform_access(vcpu, &params, desc);
- if (!params.is_write)
+ /* Read from system register? */
+ if (!params.is_write &&
+ (params.Op0 == 2 || params.Op0 == 3))
vcpu_set_reg(vcpu, Rt, params.regval);
+
return 1;
}
@@ -3930,11 +4030,84 @@ 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)
+{
+ struct kvm *kvm = vcpu->kvm;
+
+ mutex_lock(&kvm->arch.config_lock);
+
+ /*
+ * In the absence of FGT, we cannot independently trap TLBI
+ * Range instructions. This isn't great, but trapping all
+ * TLBIs would be far worse. Live with it...
+ */
+ if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, OS))
+ vcpu->arch.hcr_el2 |= HCR_TTLBOS;
+
+ if (cpus_have_final_cap(ARM64_HAS_HCX)) {
+ vcpu->arch.hcrx_el2 = HCRX_GUEST_FLAGS;
+
+ if (kvm_has_feat(kvm, ID_AA64ISAR2_EL1, MOPS, IMP))
+ vcpu->arch.hcrx_el2 |= (HCRX_EL2_MSCEn | HCRX_EL2_MCE2);
+ }
+
+ if (test_bit(KVM_ARCH_FLAG_FGU_INITIALIZED, &kvm->arch.flags))
+ goto out;
+
+ kvm->arch.fgu[HFGxTR_GROUP] = (HFGxTR_EL2_nAMAIR2_EL1 |
+ HFGxTR_EL2_nMAIR2_EL1 |
+ HFGxTR_EL2_nS2POR_EL1 |
+ HFGxTR_EL2_nPOR_EL1 |
+ HFGxTR_EL2_nPOR_EL0 |
+ HFGxTR_EL2_nACCDATA_EL1 |
+ HFGxTR_EL2_nSMPRI_EL1_MASK |
+ HFGxTR_EL2_nTPIDR2_EL0_MASK);
+
+ if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, OS))
+ kvm->arch.fgu[HFGITR_GROUP] |= (HFGITR_EL2_TLBIRVAALE1OS|
+ HFGITR_EL2_TLBIRVALE1OS |
+ HFGITR_EL2_TLBIRVAAE1OS |
+ HFGITR_EL2_TLBIRVAE1OS |
+ HFGITR_EL2_TLBIVAALE1OS |
+ HFGITR_EL2_TLBIVALE1OS |
+ HFGITR_EL2_TLBIVAAE1OS |
+ HFGITR_EL2_TLBIASIDE1OS |
+ HFGITR_EL2_TLBIVAE1OS |
+ HFGITR_EL2_TLBIVMALLE1OS);
+
+ if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, RANGE))
+ kvm->arch.fgu[HFGITR_GROUP] |= (HFGITR_EL2_TLBIRVAALE1 |
+ HFGITR_EL2_TLBIRVALE1 |
+ HFGITR_EL2_TLBIRVAAE1 |
+ HFGITR_EL2_TLBIRVAE1 |
+ HFGITR_EL2_TLBIRVAALE1IS|
+ HFGITR_EL2_TLBIRVALE1IS |
+ HFGITR_EL2_TLBIRVAAE1IS |
+ HFGITR_EL2_TLBIRVAE1IS |
+ HFGITR_EL2_TLBIRVAALE1OS|
+ HFGITR_EL2_TLBIRVALE1OS |
+ HFGITR_EL2_TLBIRVAAE1OS |
+ HFGITR_EL2_TLBIRVAE1OS);
+
+ if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, S1PIE, IMP))
+ kvm->arch.fgu[HFGxTR_GROUP] |= (HFGxTR_EL2_nPIRE0_EL1 |
+ HFGxTR_EL2_nPIR_EL1);
+
+ if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, AMU, IMP))
+ kvm->arch.fgu[HAFGRTR_GROUP] |= ~(HAFGRTR_EL2_RES0 |
+ HAFGRTR_EL2_RES1);
+
+ set_bit(KVM_ARCH_FLAG_FGU_INITIALIZED, &kvm->arch.flags);
+out:
+ mutex_unlock(&kvm->arch.config_lock);
+}
+
int __init kvm_sys_reg_table_init(void)
{
struct sys_reg_params params;
bool valid = true;
unsigned int i;
+ int ret = 0;
/* Make sure tables are unique and in order. */
valid &= check_sysreg_table(sys_reg_descs, ARRAY_SIZE(sys_reg_descs), false);
@@ -3943,6 +4116,7 @@ int __init kvm_sys_reg_table_init(void)
valid &= check_sysreg_table(cp15_regs, ARRAY_SIZE(cp15_regs), true);
valid &= check_sysreg_table(cp15_64_regs, ARRAY_SIZE(cp15_64_regs), true);
valid &= check_sysreg_table(invariant_sys_regs, ARRAY_SIZE(invariant_sys_regs), false);
+ valid &= check_sysreg_table(sys_insn_descs, ARRAY_SIZE(sys_insn_descs), false);
if (!valid)
return -EINVAL;
@@ -3957,8 +4131,13 @@ int __init kvm_sys_reg_table_init(void)
if (!first_idreg)
return -EINVAL;
- if (kvm_get_mode() == KVM_MODE_NV)
- return populate_nv_trap_config();
+ ret = populate_nv_trap_config();
- return 0;
+ for (i = 0; !ret && i < ARRAY_SIZE(sys_reg_descs); i++)
+ ret = populate_sysreg_config(sys_reg_descs + i, i);
+
+ for (i = 0; !ret && i < ARRAY_SIZE(sys_insn_descs); i++)
+ ret = populate_sysreg_config(sys_insn_descs + i, i);
+
+ return ret;
}
diff --git a/arch/arm64/kvm/sys_regs.h b/arch/arm64/kvm/sys_regs.h
index c65c129b3500..997eea21ba2a 100644
--- a/arch/arm64/kvm/sys_regs.h
+++ b/arch/arm64/kvm/sys_regs.h
@@ -233,6 +233,8 @@ int kvm_sys_reg_get_user(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg,
int kvm_sys_reg_set_user(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg,
const struct sys_reg_desc table[], unsigned int num);
+bool triage_sysreg_trap(struct kvm_vcpu *vcpu, int *sr_index);
+
#define AA32(_x) .aarch32_map = AA32_##_x
#define Op0(_x) .Op0 = _x
#define Op1(_x) .Op1 = _x
diff --git a/arch/arm64/kvm/vgic/vgic-debug.c b/arch/arm64/kvm/vgic/vgic-debug.c
index 85606a531dc3..389025ce7749 100644
--- a/arch/arm64/kvm/vgic/vgic-debug.c
+++ b/arch/arm64/kvm/vgic/vgic-debug.c
@@ -149,7 +149,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", dist->lpi_list_count);
+ seq_printf(s, "nr_lpis:\t%d\n", atomic_read(&dist->lpi_count));
seq_printf(s, "enabled:\t%d\n", dist->enabled);
seq_printf(s, "\n");
diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c
index e949e1d0fd9f..f20941f83a07 100644
--- a/arch/arm64/kvm/vgic/vgic-init.c
+++ b/arch/arm64/kvm/vgic/vgic-init.c
@@ -53,9 +53,9 @@ void kvm_vgic_early_init(struct kvm *kvm)
{
struct vgic_dist *dist = &kvm->arch.vgic;
- INIT_LIST_HEAD(&dist->lpi_list_head);
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);
}
/* CREATION */
@@ -309,7 +309,7 @@ int vgic_init(struct kvm *kvm)
vgic_lpi_translation_cache_init(kvm);
/*
- * If we have GICv4.1 enabled, unconditionnaly request enable the
+ * If we have GICv4.1 enabled, unconditionally request enable the
* v4 support so that we get HW-accelerated vSGIs. Otherwise, only
* enable it if we present a virtual ITS to the guest.
*/
@@ -366,6 +366,8 @@ static void kvm_vgic_dist_destroy(struct kvm *kvm)
if (vgic_supports_direct_msis(kvm))
vgic_v4_teardown(kvm);
+
+ xa_destroy(&dist->lpi_xa);
}
static void __kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
@@ -445,13 +447,15 @@ int vgic_lazy_init(struct kvm *kvm)
/* RESOURCE MAPPING */
/**
+ * kvm_vgic_map_resources - map the MMIO regions
+ * @kvm: kvm struct pointer
+ *
* Map the MMIO regions depending on the VGIC model exposed to the guest
* called on the first VCPU run.
* Also map the virtual CPU interface into the VM.
* v2 calls vgic_init() if not already done.
* v3 and derivatives return an error if the VGIC is not initialized.
* vgic_ready() returns true if this function has succeeded.
- * @kvm: kvm struct pointer
*/
int kvm_vgic_map_resources(struct kvm *kvm)
{
diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c
index 28a93074eca1..e85a495ada9c 100644
--- a/arch/arm64/kvm/vgic/vgic-its.c
+++ b/arch/arm64/kvm/vgic/vgic-its.c
@@ -52,7 +52,12 @@ static struct vgic_irq *vgic_add_lpi(struct kvm *kvm, u32 intid,
if (!irq)
return ERR_PTR(-ENOMEM);
- INIT_LIST_HEAD(&irq->lpi_list);
+ ret = xa_reserve_irq(&dist->lpi_xa, intid, GFP_KERNEL_ACCOUNT);
+ if (ret) {
+ kfree(irq);
+ return ERR_PTR(ret);
+ }
+
INIT_LIST_HEAD(&irq->ap_list);
raw_spin_lock_init(&irq->irq_lock);
@@ -68,30 +73,30 @@ static struct vgic_irq *vgic_add_lpi(struct kvm *kvm, u32 intid,
* There could be a race with another vgic_add_lpi(), so we need to
* check that we don't add a second list entry with the same LPI.
*/
- list_for_each_entry(oldirq, &dist->lpi_list_head, lpi_list) {
- if (oldirq->intid != intid)
- continue;
-
+ oldirq = xa_load(&dist->lpi_xa, intid);
+ if (vgic_try_get_irq_kref(oldirq)) {
/* Someone was faster with adding this LPI, lets use that. */
kfree(irq);
irq = oldirq;
- /*
- * This increases the refcount, the caller is expected to
- * call vgic_put_irq() on the returned pointer once it's
- * finished with the IRQ.
- */
- vgic_get_irq_kref(irq);
+ goto out_unlock;
+ }
+ ret = xa_err(xa_store(&dist->lpi_xa, intid, irq, 0));
+ if (ret) {
+ xa_release(&dist->lpi_xa, intid);
+ kfree(irq);
goto out_unlock;
}
- list_add_tail(&irq->lpi_list, &dist->lpi_list_head);
- dist->lpi_list_count++;
+ atomic_inc(&dist->lpi_count);
out_unlock:
raw_spin_unlock_irqrestore(&dist->lpi_list_lock, flags);
+ if (ret)
+ return ERR_PTR(ret);
+
/*
* We "cache" the configuration table entries in our struct vgic_irq's.
* However we only have those structs for mapped IRQs, so we read in
@@ -158,7 +163,7 @@ struct vgic_translation_cache_entry {
* @cte_esz: collection table entry size
* @dte_esz: device table entry size
* @ite_esz: interrupt translation table entry size
- * @save tables: save the ITS tables into guest RAM
+ * @save_tables: save the ITS tables into guest RAM
* @restore_tables: restore the ITS internal structs from tables
* stored in guest RAM
* @commit: initialize the registers which expose the ABI settings,
@@ -311,6 +316,8 @@ 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.
@@ -319,6 +326,7 @@ static int update_lpi_config(struct kvm *kvm, struct vgic_irq *irq,
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;
@@ -331,13 +339,15 @@ int vgic_copy_lpi_list(struct kvm *kvm, struct kvm_vcpu *vcpu, u32 **intid_ptr)
* command). If coming from another path (such as enabling LPIs),
* we must be careful not to overrun the array.
*/
- irq_count = READ_ONCE(dist->lpi_list_count);
+ 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);
- list_for_each_entry(irq, &dist->lpi_list_head, lpi_list) {
+ 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. */
@@ -345,6 +355,8 @@ int vgic_copy_lpi_list(struct kvm *kvm, struct kvm_vcpu *vcpu, u32 **intid_ptr)
continue;
intids[i++] = irq->intid;
}
+
+ rcu_read_unlock();
raw_spin_unlock_irqrestore(&dist->lpi_list_lock, flags);
*intid_ptr = intids;
@@ -595,8 +607,8 @@ static struct vgic_irq *vgic_its_check_cache(struct kvm *kvm, phys_addr_t db,
raw_spin_lock_irqsave(&dist->lpi_list_lock, flags);
irq = __vgic_its_check_cache(dist, db, devid, eventid);
- if (irq)
- vgic_get_irq_kref(irq);
+ if (!vgic_try_get_irq_kref(irq))
+ irq = NULL;
raw_spin_unlock_irqrestore(&dist->lpi_list_lock, flags);
@@ -640,8 +652,13 @@ static void vgic_its_cache_translation(struct kvm *kvm, struct vgic_its *its,
* was in the cache, and increment it on the new interrupt.
*/
if (cte->irq)
- __vgic_put_lpi_locked(kvm, 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.
+ */
+ lockdep_assert_held(&its->its_lock);
vgic_get_irq_kref(irq);
cte->db = db;
@@ -672,7 +689,7 @@ void vgic_its_invalidate_cache(struct kvm *kvm)
if (!cte->irq)
break;
- __vgic_put_lpi_locked(kvm, cte->irq);
+ vgic_put_irq(kvm, cte->irq);
cte->irq = NULL;
}
@@ -1345,8 +1362,8 @@ static int vgic_its_cmd_handle_inv(struct kvm *kvm, struct vgic_its *its,
}
/**
- * vgic_its_invall - invalidate all LPIs targetting a given vcpu
- * @vcpu: the vcpu for which the RD is targetted by an invalidation
+ * vgic_its_invall - invalidate all LPIs targeting a given vcpu
+ * @vcpu: the vcpu for which the RD is targeted by an invalidation
*
* Contrary to the INVALL command, this targets a RD instead of a
* collection, and we don't need to hold the its_lock, since no ITS is
@@ -2144,7 +2161,7 @@ static u32 compute_next_eventid_offset(struct list_head *h, struct its_ite *ite)
}
/**
- * entry_fn_t - Callback called on a table entry restore path
+ * typedef entry_fn_t - Callback called on a table entry restore path
* @its: its handle
* @id: id of the entry
* @entry: pointer to the entry
diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c
index 9465d3706ab9..4ea3340786b9 100644
--- a/arch/arm64/kvm/vgic/vgic-v3.c
+++ b/arch/arm64/kvm/vgic/vgic-v3.c
@@ -380,6 +380,7 @@ int vgic_v3_save_pending_tables(struct kvm *kvm)
struct vgic_irq *irq;
gpa_t last_ptr = ~(gpa_t)0;
bool vlpi_avail = false;
+ unsigned long index;
int ret = 0;
u8 val;
@@ -396,7 +397,7 @@ int vgic_v3_save_pending_tables(struct kvm *kvm)
vlpi_avail = true;
}
- list_for_each_entry(irq, &dist->lpi_list_head, lpi_list) {
+ xa_for_each(&dist->lpi_xa, index, irq) {
int byte_offset, bit_nr;
struct kvm_vcpu *vcpu;
gpa_t pendbase, ptr;
diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c
index db2a95762b1b..4ec93587c8cd 100644
--- a/arch/arm64/kvm/vgic/vgic.c
+++ b/arch/arm64/kvm/vgic/vgic.c
@@ -30,7 +30,8 @@ struct vgic_global kvm_vgic_global_state __ro_after_init = {
* 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_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
@@ -54,32 +55,22 @@ struct vgic_global kvm_vgic_global_state __ro_after_init = {
*/
/*
- * Iterate over the VM's list of mapped LPIs to find the one with a
- * matching interrupt ID and return a reference to the IRQ structure.
+ * Index the VM's xarray of mapped LPIs and return a reference to the IRQ
+ * structure. The caller is expected to call vgic_put_irq() later once it's
+ * finished with the IRQ.
*/
static struct vgic_irq *vgic_get_lpi(struct kvm *kvm, u32 intid)
{
struct vgic_dist *dist = &kvm->arch.vgic;
struct vgic_irq *irq = NULL;
- unsigned long flags;
-
- raw_spin_lock_irqsave(&dist->lpi_list_lock, flags);
- list_for_each_entry(irq, &dist->lpi_list_head, lpi_list) {
- if (irq->intid != intid)
- continue;
+ rcu_read_lock();
- /*
- * This increases the refcount, the caller is expected to
- * call vgic_put_irq() later once it's finished with the IRQ.
- */
- vgic_get_irq_kref(irq);
- goto out_unlock;
- }
- irq = NULL;
+ irq = xa_load(&dist->lpi_xa, intid);
+ if (!vgic_try_get_irq_kref(irq))
+ irq = NULL;
-out_unlock:
- raw_spin_unlock_irqrestore(&dist->lpi_list_lock, flags);
+ rcu_read_unlock();
return irq;
}
@@ -120,22 +111,6 @@ static void vgic_irq_release(struct kref *ref)
{
}
-/*
- * Drop the refcount on the LPI. Must be called with lpi_list_lock held.
- */
-void __vgic_put_lpi_locked(struct kvm *kvm, struct vgic_irq *irq)
-{
- struct vgic_dist *dist = &kvm->arch.vgic;
-
- if (!kref_put(&irq->refcount, vgic_irq_release))
- return;
-
- list_del(&irq->lpi_list);
- dist->lpi_list_count--;
-
- kfree(irq);
-}
-
void vgic_put_irq(struct kvm *kvm, struct vgic_irq *irq)
{
struct vgic_dist *dist = &kvm->arch.vgic;
@@ -144,9 +119,15 @@ void vgic_put_irq(struct kvm *kvm, struct vgic_irq *irq)
if (irq->intid < VGIC_MIN_LPI)
return;
- raw_spin_lock_irqsave(&dist->lpi_list_lock, flags);
- __vgic_put_lpi_locked(kvm, irq);
- raw_spin_unlock_irqrestore(&dist->lpi_list_lock, flags);
+ if (!kref_put(&irq->refcount, vgic_irq_release))
+ return;
+
+ xa_lock_irqsave(&dist->lpi_xa, flags);
+ __xa_erase(&dist->lpi_xa, irq->intid);
+ xa_unlock_irqrestore(&dist->lpi_xa, flags);
+
+ atomic_dec(&dist->lpi_count);
+ kfree_rcu(irq, rcu);
}
void vgic_flush_pending_lpis(struct kvm_vcpu *vcpu)
@@ -203,7 +184,7 @@ void vgic_irq_set_phys_active(struct vgic_irq *irq, bool active)
}
/**
- * kvm_vgic_target_oracle - compute the target vcpu for an irq
+ * vgic_target_oracle - compute the target vcpu for an irq
*
* @irq: The irq to route. Must be already locked.
*
@@ -404,7 +385,8 @@ retry:
/*
* Grab a reference to the irq to reflect the fact that it is
- * now in the ap_list.
+ * now in the ap_list. This is safe as the caller must already hold a
+ * reference on the irq.
*/
vgic_get_irq_kref(irq);
list_add_tail(&irq->ap_list, &vcpu->arch.vgic_cpu.ap_list_head);
diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h
index 8d134569d0a1..0c2b82de8fa3 100644
--- a/arch/arm64/kvm/vgic/vgic.h
+++ b/arch/arm64/kvm/vgic/vgic.h
@@ -180,7 +180,6 @@ vgic_get_mmio_region(struct kvm_vcpu *vcpu, struct vgic_io_device *iodev,
gpa_t addr, int len);
struct vgic_irq *vgic_get_irq(struct kvm *kvm, struct kvm_vcpu *vcpu,
u32 intid);
-void __vgic_put_lpi_locked(struct kvm *kvm, struct vgic_irq *irq);
void vgic_put_irq(struct kvm *kvm, struct vgic_irq *irq);
bool vgic_get_phys_line_level(struct vgic_irq *irq);
void vgic_irq_set_phys_pending(struct vgic_irq *irq, bool pending);
@@ -220,12 +219,20 @@ 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);
-static inline void vgic_get_irq_kref(struct vgic_irq *irq)
+static inline bool vgic_try_get_irq_kref(struct vgic_irq *irq)
{
+ if (!irq)
+ return false;
+
if (irq->intid < VGIC_MIN_LPI)
- return;
+ return true;
- kref_get(&irq->refcount);
+ return kref_get_unless_zero(&irq->refcount);
+}
+
+static inline void vgic_get_irq_kref(struct vgic_irq *irq)
+{
+ WARN_ON_ONCE(!vgic_try_get_irq_kref(irq));
}
void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu);
diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile
index dbd1bc95967d..60454256945b 100644
--- a/arch/arm64/mm/Makefile
+++ b/arch/arm64/mm/Makefile
@@ -3,6 +3,7 @@ obj-y := dma-mapping.o extable.o fault.o init.o \
cache.o copypage.o flush.o \
ioremap.o mmap.o pgd.o mmu.o \
context.o proc.o pageattr.o fixmap.o
+obj-$(CONFIG_ARM64_CONTPTE) += contpte.o
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
obj-$(CONFIG_PTDUMP_CORE) += ptdump.o
obj-$(CONFIG_PTDUMP_DEBUGFS) += ptdump_debugfs.o
diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
new file mode 100644
index 000000000000..1b64b4c3f8bf
--- /dev/null
+++ b/arch/arm64/mm/contpte.c
@@ -0,0 +1,408 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023 ARM Ltd.
+ */
+
+#include <linux/mm.h>
+#include <linux/efi.h>
+#include <linux/export.h>
+#include <asm/tlbflush.h>
+
+static inline bool mm_is_user(struct mm_struct *mm)
+{
+ /*
+ * Don't attempt to apply the contig bit to kernel mappings, because
+ * dynamically adding/removing the contig bit can cause page faults.
+ * These racing faults are ok for user space, since they get serialized
+ * on the PTL. But kernel mappings can't tolerate faults.
+ */
+ if (unlikely(mm_is_efi(mm)))
+ return false;
+ return mm != &init_mm;
+}
+
+static inline pte_t *contpte_align_down(pte_t *ptep)
+{
+ return PTR_ALIGN_DOWN(ptep, sizeof(*ptep) * CONT_PTES);
+}
+
+static void contpte_try_unfold_partial(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, unsigned int nr)
+{
+ /*
+ * Unfold any partially covered contpte block at the beginning and end
+ * of the range.
+ */
+
+ if (ptep != contpte_align_down(ptep) || nr < CONT_PTES)
+ contpte_try_unfold(mm, addr, ptep, __ptep_get(ptep));
+
+ if (ptep + nr != contpte_align_down(ptep + nr)) {
+ unsigned long last_addr = addr + PAGE_SIZE * (nr - 1);
+ pte_t *last_ptep = ptep + nr - 1;
+
+ contpte_try_unfold(mm, last_addr, last_ptep,
+ __ptep_get(last_ptep));
+ }
+}
+
+static void contpte_convert(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pte)
+{
+ struct vm_area_struct vma = TLB_FLUSH_VMA(mm, 0);
+ unsigned long start_addr;
+ pte_t *start_ptep;
+ int i;
+
+ start_ptep = ptep = contpte_align_down(ptep);
+ start_addr = addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
+ pte = pfn_pte(ALIGN_DOWN(pte_pfn(pte), CONT_PTES), pte_pgprot(pte));
+
+ for (i = 0; i < CONT_PTES; i++, ptep++, addr += PAGE_SIZE) {
+ pte_t ptent = __ptep_get_and_clear(mm, addr, ptep);
+
+ if (pte_dirty(ptent))
+ pte = pte_mkdirty(pte);
+
+ if (pte_young(ptent))
+ pte = pte_mkyoung(pte);
+ }
+
+ __flush_tlb_range(&vma, start_addr, addr, PAGE_SIZE, true, 3);
+
+ __set_ptes(mm, start_addr, start_ptep, pte, CONT_PTES);
+}
+
+void __contpte_try_fold(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pte)
+{
+ /*
+ * We have already checked that the virtual and pysical addresses are
+ * correctly aligned for a contpte mapping in contpte_try_fold() so the
+ * remaining checks are to ensure that the contpte range is fully
+ * covered by a single folio, and ensure that all the ptes are valid
+ * with contiguous PFNs and matching prots. We ignore the state of the
+ * access and dirty bits for the purpose of deciding if its a contiguous
+ * range; the folding process will generate a single contpte entry which
+ * has a single access and dirty bit. Those 2 bits are the logical OR of
+ * their respective bits in the constituent pte entries. In order to
+ * ensure the contpte range is covered by a single folio, we must
+ * recover the folio from the pfn, but special mappings don't have a
+ * folio backing them. Fortunately contpte_try_fold() already checked
+ * that the pte is not special - we never try to fold special mappings.
+ * Note we can't use vm_normal_page() for this since we don't have the
+ * vma.
+ */
+
+ unsigned long folio_start, folio_end;
+ unsigned long cont_start, cont_end;
+ pte_t expected_pte, subpte;
+ struct folio *folio;
+ struct page *page;
+ unsigned long pfn;
+ pte_t *orig_ptep;
+ pgprot_t prot;
+
+ int i;
+
+ if (!mm_is_user(mm))
+ return;
+
+ page = pte_page(pte);
+ folio = page_folio(page);
+ folio_start = addr - (page - &folio->page) * PAGE_SIZE;
+ folio_end = folio_start + folio_nr_pages(folio) * PAGE_SIZE;
+ cont_start = ALIGN_DOWN(addr, CONT_PTE_SIZE);
+ cont_end = cont_start + CONT_PTE_SIZE;
+
+ if (folio_start > cont_start || folio_end < cont_end)
+ return;
+
+ pfn = ALIGN_DOWN(pte_pfn(pte), CONT_PTES);
+ prot = pte_pgprot(pte_mkold(pte_mkclean(pte)));
+ expected_pte = pfn_pte(pfn, prot);
+ orig_ptep = ptep;
+ ptep = contpte_align_down(ptep);
+
+ for (i = 0; i < CONT_PTES; i++) {
+ subpte = pte_mkold(pte_mkclean(__ptep_get(ptep)));
+ if (!pte_same(subpte, expected_pte))
+ return;
+ expected_pte = pte_advance_pfn(expected_pte, 1);
+ ptep++;
+ }
+
+ pte = pte_mkcont(pte);
+ contpte_convert(mm, addr, orig_ptep, pte);
+}
+EXPORT_SYMBOL_GPL(__contpte_try_fold);
+
+void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pte)
+{
+ /*
+ * We have already checked that the ptes are contiguous in
+ * contpte_try_unfold(), so just check that the mm is user space.
+ */
+ if (!mm_is_user(mm))
+ return;
+
+ pte = pte_mknoncont(pte);
+ contpte_convert(mm, addr, ptep, pte);
+}
+EXPORT_SYMBOL_GPL(__contpte_try_unfold);
+
+pte_t contpte_ptep_get(pte_t *ptep, pte_t orig_pte)
+{
+ /*
+ * Gather access/dirty bits, which may be populated in any of the ptes
+ * of the contig range. We are guaranteed to be holding the PTL, so any
+ * contiguous range cannot be unfolded or otherwise modified under our
+ * feet.
+ */
+
+ pte_t pte;
+ int i;
+
+ ptep = contpte_align_down(ptep);
+
+ for (i = 0; i < CONT_PTES; i++, ptep++) {
+ pte = __ptep_get(ptep);
+
+ if (pte_dirty(pte))
+ orig_pte = pte_mkdirty(orig_pte);
+
+ if (pte_young(pte))
+ orig_pte = pte_mkyoung(orig_pte);
+ }
+
+ return orig_pte;
+}
+EXPORT_SYMBOL_GPL(contpte_ptep_get);
+
+pte_t contpte_ptep_get_lockless(pte_t *orig_ptep)
+{
+ /*
+ * The ptep_get_lockless() API requires us to read and return *orig_ptep
+ * so that it is self-consistent, without the PTL held, so we may be
+ * racing with other threads modifying the pte. Usually a READ_ONCE()
+ * would suffice, but for the contpte case, we also need to gather the
+ * access and dirty bits from across all ptes in the contiguous block,
+ * and we can't read all of those neighbouring ptes atomically, so any
+ * contiguous range may be unfolded/modified/refolded under our feet.
+ * Therefore we ensure we read a _consistent_ contpte range by checking
+ * that all ptes in the range are valid and have CONT_PTE set, that all
+ * pfns are contiguous and that all pgprots are the same (ignoring
+ * access/dirty). If we find a pte that is not consistent, then we must
+ * be racing with an update so start again. If the target pte does not
+ * have CONT_PTE set then that is considered consistent on its own
+ * because it is not part of a contpte range.
+ */
+
+ pgprot_t orig_prot;
+ unsigned long pfn;
+ pte_t orig_pte;
+ pgprot_t prot;
+ pte_t *ptep;
+ pte_t pte;
+ int i;
+
+retry:
+ orig_pte = __ptep_get(orig_ptep);
+
+ if (!pte_valid_cont(orig_pte))
+ return orig_pte;
+
+ orig_prot = pte_pgprot(pte_mkold(pte_mkclean(orig_pte)));
+ ptep = contpte_align_down(orig_ptep);
+ pfn = pte_pfn(orig_pte) - (orig_ptep - ptep);
+
+ for (i = 0; i < CONT_PTES; i++, ptep++, pfn++) {
+ pte = __ptep_get(ptep);
+ prot = pte_pgprot(pte_mkold(pte_mkclean(pte)));
+
+ if (!pte_valid_cont(pte) ||
+ pte_pfn(pte) != pfn ||
+ pgprot_val(prot) != pgprot_val(orig_prot))
+ goto retry;
+
+ if (pte_dirty(pte))
+ orig_pte = pte_mkdirty(orig_pte);
+
+ if (pte_young(pte))
+ orig_pte = pte_mkyoung(orig_pte);
+ }
+
+ return orig_pte;
+}
+EXPORT_SYMBOL_GPL(contpte_ptep_get_lockless);
+
+void contpte_set_ptes(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pte, unsigned int nr)
+{
+ unsigned long next;
+ unsigned long end;
+ unsigned long pfn;
+ pgprot_t prot;
+
+ /*
+ * The set_ptes() spec guarantees that when nr > 1, the initial state of
+ * all ptes is not-present. Therefore we never need to unfold or
+ * otherwise invalidate a range before we set the new ptes.
+ * contpte_set_ptes() should never be called for nr < 2.
+ */
+ VM_WARN_ON(nr == 1);
+
+ if (!mm_is_user(mm))
+ return __set_ptes(mm, addr, ptep, pte, nr);
+
+ end = addr + (nr << PAGE_SHIFT);
+ pfn = pte_pfn(pte);
+ prot = pte_pgprot(pte);
+
+ do {
+ next = pte_cont_addr_end(addr, end);
+ nr = (next - addr) >> PAGE_SHIFT;
+ pte = pfn_pte(pfn, prot);
+
+ if (((addr | next | (pfn << PAGE_SHIFT)) & ~CONT_PTE_MASK) == 0)
+ pte = pte_mkcont(pte);
+ else
+ pte = pte_mknoncont(pte);
+
+ __set_ptes(mm, addr, ptep, pte, nr);
+
+ addr = next;
+ ptep += nr;
+ pfn += nr;
+
+ } while (addr != end);
+}
+EXPORT_SYMBOL_GPL(contpte_set_ptes);
+
+void contpte_clear_full_ptes(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, unsigned int nr, int full)
+{
+ contpte_try_unfold_partial(mm, addr, ptep, nr);
+ __clear_full_ptes(mm, addr, ptep, nr, full);
+}
+EXPORT_SYMBOL_GPL(contpte_clear_full_ptes);
+
+pte_t contpte_get_and_clear_full_ptes(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep,
+ unsigned int nr, int full)
+{
+ contpte_try_unfold_partial(mm, addr, ptep, nr);
+ return __get_and_clear_full_ptes(mm, addr, ptep, nr, full);
+}
+EXPORT_SYMBOL_GPL(contpte_get_and_clear_full_ptes);
+
+int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep)
+{
+ /*
+ * ptep_clear_flush_young() technically requires us to clear the access
+ * flag for a _single_ pte. However, the core-mm code actually tracks
+ * access/dirty per folio, not per page. And since we only create a
+ * contig range when the range is covered by a single folio, we can get
+ * away with clearing young for the whole contig range here, so we avoid
+ * having to unfold.
+ */
+
+ int young = 0;
+ int i;
+
+ ptep = contpte_align_down(ptep);
+ addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
+
+ for (i = 0; i < CONT_PTES; i++, ptep++, addr += PAGE_SIZE)
+ young |= __ptep_test_and_clear_young(vma, addr, ptep);
+
+ return young;
+}
+EXPORT_SYMBOL_GPL(contpte_ptep_test_and_clear_young);
+
+int contpte_ptep_clear_flush_young(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep)
+{
+ int young;
+
+ young = contpte_ptep_test_and_clear_young(vma, addr, ptep);
+
+ if (young) {
+ /*
+ * See comment in __ptep_clear_flush_young(); same rationale for
+ * eliding the trailing DSB applies here.
+ */
+ addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
+ __flush_tlb_range_nosync(vma, addr, addr + CONT_PTE_SIZE,
+ PAGE_SIZE, true, 3);
+ }
+
+ return young;
+}
+EXPORT_SYMBOL_GPL(contpte_ptep_clear_flush_young);
+
+void contpte_wrprotect_ptes(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, unsigned int nr)
+{
+ /*
+ * If wrprotecting an entire contig range, we can avoid unfolding. Just
+ * set wrprotect and wait for the later mmu_gather flush to invalidate
+ * the tlb. Until the flush, the page may or may not be wrprotected.
+ * After the flush, it is guaranteed wrprotected. If it's a partial
+ * range though, we must unfold, because we can't have a case where
+ * CONT_PTE is set but wrprotect applies to a subset of the PTEs; this
+ * would cause it to continue to be unpredictable after the flush.
+ */
+
+ contpte_try_unfold_partial(mm, addr, ptep, nr);
+ __wrprotect_ptes(mm, addr, ptep, nr);
+}
+EXPORT_SYMBOL_GPL(contpte_wrprotect_ptes);
+
+int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep,
+ pte_t entry, int dirty)
+{
+ unsigned long start_addr;
+ pte_t orig_pte;
+ int i;
+
+ /*
+ * Gather the access/dirty bits for the contiguous range. If nothing has
+ * changed, its a noop.
+ */
+ orig_pte = pte_mknoncont(ptep_get(ptep));
+ if (pte_val(orig_pte) == pte_val(entry))
+ return 0;
+
+ /*
+ * We can fix up access/dirty bits without having to unfold the contig
+ * range. But if the write bit is changing, we must unfold.
+ */
+ if (pte_write(orig_pte) == pte_write(entry)) {
+ /*
+ * For HW access management, we technically only need to update
+ * the flag on a single pte in the range. But for SW access
+ * management, we need to update all the ptes to prevent extra
+ * faults. Avoid per-page tlb flush in __ptep_set_access_flags()
+ * and instead flush the whole range at the end.
+ */
+ ptep = contpte_align_down(ptep);
+ start_addr = addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);
+
+ for (i = 0; i < CONT_PTES; i++, ptep++, addr += PAGE_SIZE)
+ __ptep_set_access_flags(vma, addr, ptep, entry, 0);
+
+ if (dirty)
+ __flush_tlb_range(vma, start_addr, addr,
+ PAGE_SIZE, true, 3);
+ } else {
+ __contpte_try_unfold(vma->vm_mm, addr, ptep, orig_pte);
+ __ptep_set_access_flags(vma, addr, ptep, entry, dirty);
+ }
+
+ return 1;
+}
+EXPORT_SYMBOL_GPL(contpte_ptep_set_access_flags);
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 55f6455a8284..8251e2fea9c7 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -191,7 +191,7 @@ static void show_pte(unsigned long addr)
if (!ptep)
break;
- pte = READ_ONCE(*ptep);
+ pte = __ptep_get(ptep);
pr_cont(", pte=%016llx", pte_val(pte));
pte_unmap(ptep);
} while(0);
@@ -205,16 +205,16 @@ static void show_pte(unsigned long addr)
*
* It needs to cope with hardware update of the accessed/dirty state by other
* agents in the system and can safely skip the __sync_icache_dcache() call as,
- * like set_pte_at(), the PTE is never changed from no-exec to exec here.
+ * like __set_ptes(), the PTE is never changed from no-exec to exec here.
*
* Returns whether or not the PTE actually changed.
*/
-int ptep_set_access_flags(struct vm_area_struct *vma,
- unsigned long address, pte_t *ptep,
- pte_t entry, int dirty)
+int __ptep_set_access_flags(struct vm_area_struct *vma,
+ unsigned long address, pte_t *ptep,
+ pte_t entry, int dirty)
{
pteval_t old_pteval, pteval;
- pte_t pte = READ_ONCE(*ptep);
+ pte_t pte = __ptep_get(ptep);
if (pte_same(pte, entry))
return 0;
@@ -257,16 +257,14 @@ static bool is_el1_data_abort(unsigned long esr)
static inline bool is_el1_permission_fault(unsigned long addr, unsigned long esr,
struct pt_regs *regs)
{
- unsigned long fsc_type = esr & ESR_ELx_FSC_TYPE;
-
if (!is_el1_data_abort(esr) && !is_el1_instruction_abort(esr))
return false;
- if (fsc_type == ESR_ELx_FSC_PERM)
+ if (esr_fsc_is_permission_fault(esr))
return true;
if (is_ttbr0_addr(addr) && system_uses_ttbr0_pan())
- return fsc_type == ESR_ELx_FSC_FAULT &&
+ return esr_fsc_is_translation_fault(esr) &&
(regs->pstate & PSR_PAN_BIT);
return false;
@@ -279,8 +277,7 @@ static bool __kprobes is_spurious_el1_translation_fault(unsigned long addr,
unsigned long flags;
u64 par, dfsc;
- if (!is_el1_data_abort(esr) ||
- (esr & ESR_ELx_FSC_TYPE) != ESR_ELx_FSC_FAULT)
+ if (!is_el1_data_abort(esr) || !esr_fsc_is_translation_fault(esr))
return false;
local_irq_save(flags);
@@ -301,7 +298,7 @@ static bool __kprobes is_spurious_el1_translation_fault(unsigned long addr,
* treat the translation fault as spurious.
*/
dfsc = FIELD_GET(SYS_PAR_EL1_FST, par);
- return (dfsc & ESR_ELx_FSC_TYPE) != ESR_ELx_FSC_FAULT;
+ return !esr_fsc_is_translation_fault(dfsc);
}
static void die_kernel_fault(const char *msg, unsigned long addr,
@@ -368,11 +365,6 @@ static bool is_el1_mte_sync_tag_check_fault(unsigned long esr)
return false;
}
-static bool is_translation_fault(unsigned long esr)
-{
- return (esr & ESR_ELx_FSC_TYPE) == ESR_ELx_FSC_FAULT;
-}
-
static void __do_kernel_fault(unsigned long addr, unsigned long esr,
struct pt_regs *regs)
{
@@ -405,7 +397,7 @@ static void __do_kernel_fault(unsigned long addr, unsigned long esr,
} else if (addr < PAGE_SIZE) {
msg = "NULL pointer dereference";
} else {
- if (is_translation_fault(esr) &&
+ if (esr_fsc_is_translation_fault(esr) &&
kfence_handle_page_fault(addr, esr & ESR_ELx_WNR, regs))
return;
@@ -782,18 +774,18 @@ static const struct fault_info fault_info[] = {
{ do_translation_fault, SIGSEGV, SEGV_MAPERR, "level 1 translation fault" },
{ do_translation_fault, SIGSEGV, SEGV_MAPERR, "level 2 translation fault" },
{ do_translation_fault, SIGSEGV, SEGV_MAPERR, "level 3 translation fault" },
- { do_bad, SIGKILL, SI_KERNEL, "unknown 8" },
+ { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 0 access flag fault" },
{ do_page_fault, SIGSEGV, SEGV_ACCERR, "level 1 access flag fault" },
{ do_page_fault, SIGSEGV, SEGV_ACCERR, "level 2 access flag fault" },
{ do_page_fault, SIGSEGV, SEGV_ACCERR, "level 3 access flag fault" },
- { do_bad, SIGKILL, SI_KERNEL, "unknown 12" },
+ { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 0 permission fault" },
{ do_page_fault, SIGSEGV, SEGV_ACCERR, "level 1 permission fault" },
{ do_page_fault, SIGSEGV, SEGV_ACCERR, "level 2 permission fault" },
{ do_page_fault, SIGSEGV, SEGV_ACCERR, "level 3 permission fault" },
{ do_sea, SIGBUS, BUS_OBJERR, "synchronous external abort" },
{ do_tag_check_fault, SIGSEGV, SEGV_MTESERR, "synchronous tag check fault" },
{ do_bad, SIGKILL, SI_KERNEL, "unknown 18" },
- { do_bad, SIGKILL, SI_KERNEL, "unknown 19" },
+ { do_sea, SIGKILL, SI_KERNEL, "level -1 (translation table walk)" },
{ do_sea, SIGKILL, SI_KERNEL, "level 0 (translation table walk)" },
{ do_sea, SIGKILL, SI_KERNEL, "level 1 (translation table walk)" },
{ do_sea, SIGKILL, SI_KERNEL, "level 2 (translation table walk)" },
@@ -801,7 +793,7 @@ static const struct fault_info fault_info[] = {
{ do_sea, SIGBUS, BUS_OBJERR, "synchronous parity or ECC error" }, // Reserved when RAS is implemented
{ do_bad, SIGKILL, SI_KERNEL, "unknown 25" },
{ do_bad, SIGKILL, SI_KERNEL, "unknown 26" },
- { do_bad, SIGKILL, SI_KERNEL, "unknown 27" },
+ { do_sea, SIGKILL, SI_KERNEL, "level -1 synchronous parity error (translation table walk)" }, // Reserved when RAS is implemented
{ do_sea, SIGKILL, SI_KERNEL, "level 0 synchronous parity error (translation table walk)" }, // Reserved when RAS is implemented
{ do_sea, SIGKILL, SI_KERNEL, "level 1 synchronous parity error (translation table walk)" }, // Reserved when RAS is implemented
{ do_sea, SIGKILL, SI_KERNEL, "level 2 synchronous parity error (translation table walk)" }, // Reserved when RAS is implemented
@@ -815,9 +807,9 @@ static const struct fault_info fault_info[] = {
{ do_bad, SIGKILL, SI_KERNEL, "unknown 38" },
{ do_bad, SIGKILL, SI_KERNEL, "unknown 39" },
{ do_bad, SIGKILL, SI_KERNEL, "unknown 40" },
- { do_bad, SIGKILL, SI_KERNEL, "unknown 41" },
+ { do_bad, SIGKILL, SI_KERNEL, "level -1 address size fault" },
{ do_bad, SIGKILL, SI_KERNEL, "unknown 42" },
- { do_bad, SIGKILL, SI_KERNEL, "unknown 43" },
+ { do_translation_fault, SIGSEGV, SEGV_MAPERR, "level -1 translation fault" },
{ do_bad, SIGKILL, SI_KERNEL, "unknown 44" },
{ do_bad, SIGKILL, SI_KERNEL, "unknown 45" },
{ do_bad, SIGKILL, SI_KERNEL, "unknown 46" },
diff --git a/arch/arm64/mm/fixmap.c b/arch/arm64/mm/fixmap.c
index c0a3301203bd..de1e09d986ad 100644
--- a/arch/arm64/mm/fixmap.c
+++ b/arch/arm64/mm/fixmap.c
@@ -16,6 +16,9 @@
#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
+/* ensure that the fixmap region does not grow down into the PCI I/O region */
+static_assert(FIXADDR_TOT_START > PCI_IO_END);
+
#define NR_BM_PTE_TABLES \
SPAN_NR_ENTRIES(FIXADDR_TOT_START, FIXADDR_TOP, PMD_SHIFT)
#define NR_BM_PMD_TABLES \
@@ -101,7 +104,7 @@ void __init early_fixmap_init(void)
unsigned long end = FIXADDR_TOP;
pgd_t *pgdp = pgd_offset_k(addr);
- p4d_t *p4dp = p4d_offset(pgdp, addr);
+ p4d_t *p4dp = p4d_offset_kimg(pgdp, addr);
early_fixmap_init_pud(p4dp, addr, end);
}
@@ -121,9 +124,9 @@ void __set_fixmap(enum fixed_addresses idx,
ptep = fixmap_pte(addr);
if (pgprot_val(flags)) {
- set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, flags));
+ __set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, flags));
} else {
- pte_clear(&init_mm, addr, ptep);
+ __pte_clear(&init_mm, addr, ptep);
flush_tlb_kernel_range(addr, addr+PAGE_SIZE);
}
}
@@ -167,37 +170,3 @@ void *__init fixmap_remap_fdt(phys_addr_t dt_phys, int *size, pgprot_t prot)
return dt_virt;
}
-
-/*
- * Copy the fixmap region into a new pgdir.
- */
-void __init fixmap_copy(pgd_t *pgdir)
-{
- if (!READ_ONCE(pgd_val(*pgd_offset_pgd(pgdir, FIXADDR_TOT_START)))) {
- /*
- * The fixmap falls in a separate pgd to the kernel, and doesn't
- * live in the carveout for the swapper_pg_dir. We can simply
- * re-use the existing dir for the fixmap.
- */
- set_pgd(pgd_offset_pgd(pgdir, FIXADDR_TOT_START),
- READ_ONCE(*pgd_offset_k(FIXADDR_TOT_START)));
- } else if (CONFIG_PGTABLE_LEVELS > 3) {
- pgd_t *bm_pgdp;
- p4d_t *bm_p4dp;
- pud_t *bm_pudp;
- /*
- * The fixmap shares its top level pgd entry with the kernel
- * mapping. This can really only occur when we are running
- * with 16k/4 levels, so we can simply reuse the pud level
- * entry instead.
- */
- BUG_ON(!IS_ENABLED(CONFIG_ARM64_16K_PAGES));
- bm_pgdp = pgd_offset_pgd(pgdir, FIXADDR_TOT_START);
- bm_p4dp = p4d_offset(bm_pgdp, FIXADDR_TOT_START);
- bm_pudp = pud_set_fixmap_offset(bm_p4dp, FIXADDR_TOT_START);
- pud_populate(&init_mm, bm_pudp, lm_alias(bm_pmd));
- pud_clear_fixmap();
- } else {
- BUG();
- }
-}
diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index 8116ac599f80..0f0e10bb0a95 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -45,13 +45,6 @@ void __init arm64_hugetlb_cma_reserve(void)
else
order = CONT_PMD_SHIFT - PAGE_SHIFT;
- /*
- * HugeTLB CMA reservation is required for gigantic
- * huge pages which could not be allocated via the
- * page allocator. Just warn if there is any change
- * breaking this assumption.
- */
- WARN_ON(order <= MAX_PAGE_ORDER);
hugetlb_cma_reserve(order);
}
#endif /* CONFIG_CMA */
@@ -152,14 +145,14 @@ pte_t huge_ptep_get(pte_t *ptep)
{
int ncontig, i;
size_t pgsize;
- pte_t orig_pte = ptep_get(ptep);
+ pte_t orig_pte = __ptep_get(ptep);
if (!pte_present(orig_pte) || !pte_cont(orig_pte))
return orig_pte;
ncontig = num_contig_ptes(page_size(pte_page(orig_pte)), &pgsize);
for (i = 0; i < ncontig; i++, ptep++) {
- pte_t pte = ptep_get(ptep);
+ pte_t pte = __ptep_get(ptep);
if (pte_dirty(pte))
orig_pte = pte_mkdirty(orig_pte);
@@ -184,11 +177,11 @@ static pte_t get_clear_contig(struct mm_struct *mm,
unsigned long pgsize,
unsigned long ncontig)
{
- pte_t orig_pte = ptep_get(ptep);
+ pte_t orig_pte = __ptep_get(ptep);
unsigned long i;
for (i = 0; i < ncontig; i++, addr += pgsize, ptep++) {
- pte_t pte = ptep_get_and_clear(mm, addr, ptep);
+ pte_t pte = __ptep_get_and_clear(mm, addr, ptep);
/*
* If HW_AFDBM is enabled, then the HW could turn on
@@ -236,7 +229,7 @@ static void clear_flush(struct mm_struct *mm,
unsigned long i, saddr = addr;
for (i = 0; i < ncontig; i++, addr += pgsize, ptep++)
- ptep_clear(mm, addr, ptep);
+ __ptep_get_and_clear(mm, addr, ptep);
flush_tlb_range(&vma, saddr, addr);
}
@@ -254,12 +247,12 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
if (!pte_present(pte)) {
for (i = 0; i < ncontig; i++, ptep++, addr += pgsize)
- set_pte_at(mm, addr, ptep, pte);
+ __set_ptes(mm, addr, ptep, pte, 1);
return;
}
if (!pte_cont(pte)) {
- set_pte_at(mm, addr, ptep, pte);
+ __set_ptes(mm, addr, ptep, pte, 1);
return;
}
@@ -270,7 +263,7 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
clear_flush(mm, addr, ptep, pgsize, ncontig);
for (i = 0; i < ncontig; i++, ptep++, addr += pgsize, pfn += dpfn)
- set_pte_at(mm, addr, ptep, pfn_pte(pfn, hugeprot));
+ __set_ptes(mm, addr, ptep, pfn_pte(pfn, hugeprot), 1);
}
pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
@@ -400,7 +393,7 @@ void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
ncontig = num_contig_ptes(sz, &pgsize);
for (i = 0; i < ncontig; i++, addr += pgsize, ptep++)
- pte_clear(mm, addr, ptep);
+ __pte_clear(mm, addr, ptep);
}
pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
@@ -408,10 +401,10 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
{
int ncontig;
size_t pgsize;
- pte_t orig_pte = ptep_get(ptep);
+ pte_t orig_pte = __ptep_get(ptep);
if (!pte_cont(orig_pte))
- return ptep_get_and_clear(mm, addr, ptep);
+ return __ptep_get_and_clear(mm, addr, ptep);
ncontig = find_num_contig(mm, addr, ptep, &pgsize);
@@ -431,11 +424,11 @@ static int __cont_access_flags_changed(pte_t *ptep, pte_t pte, int ncontig)
{
int i;
- if (pte_write(pte) != pte_write(ptep_get(ptep)))
+ if (pte_write(pte) != pte_write(__ptep_get(ptep)))
return 1;
for (i = 0; i < ncontig; i++) {
- pte_t orig_pte = ptep_get(ptep + i);
+ pte_t orig_pte = __ptep_get(ptep + i);
if (pte_dirty(pte) != pte_dirty(orig_pte))
return 1;
@@ -459,7 +452,7 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma,
pte_t orig_pte;
if (!pte_cont(pte))
- return ptep_set_access_flags(vma, addr, ptep, pte, dirty);
+ return __ptep_set_access_flags(vma, addr, ptep, pte, dirty);
ncontig = find_num_contig(mm, addr, ptep, &pgsize);
dpfn = pgsize >> PAGE_SHIFT;
@@ -478,7 +471,7 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma,
hugeprot = pte_pgprot(pte);
for (i = 0; i < ncontig; i++, ptep++, addr += pgsize, pfn += dpfn)
- set_pte_at(mm, addr, ptep, pfn_pte(pfn, hugeprot));
+ __set_ptes(mm, addr, ptep, pfn_pte(pfn, hugeprot), 1);
return 1;
}
@@ -492,8 +485,8 @@ void huge_ptep_set_wrprotect(struct mm_struct *mm,
size_t pgsize;
pte_t pte;
- if (!pte_cont(READ_ONCE(*ptep))) {
- ptep_set_wrprotect(mm, addr, ptep);
+ if (!pte_cont(__ptep_get(ptep))) {
+ __ptep_set_wrprotect(mm, addr, ptep);
return;
}
@@ -507,7 +500,7 @@ void huge_ptep_set_wrprotect(struct mm_struct *mm,
pfn = pte_pfn(pte);
for (i = 0; i < ncontig; i++, ptep++, addr += pgsize, pfn += dpfn)
- set_pte_at(mm, addr, ptep, pfn_pte(pfn, hugeprot));
+ __set_ptes(mm, addr, ptep, pfn_pte(pfn, hugeprot), 1);
}
pte_t huge_ptep_clear_flush(struct vm_area_struct *vma,
@@ -517,7 +510,7 @@ pte_t huge_ptep_clear_flush(struct vm_area_struct *vma,
size_t pgsize;
int ncontig;
- if (!pte_cont(READ_ONCE(*ptep)))
+ if (!pte_cont(__ptep_get(ptep)))
return ptep_clear_flush(vma, addr, ptep);
ncontig = find_num_contig(mm, addr, ptep, &pgsize);
@@ -550,7 +543,7 @@ pte_t huge_ptep_modify_prot_start(struct vm_area_struct *vma, unsigned long addr
* when the permission changes from executable to non-executable
* in cases where cpu is affected with errata #2645198.
*/
- if (pte_user_exec(READ_ONCE(*ptep)))
+ if (pte_user_exec(__ptep_get(ptep)))
return huge_ptep_clear_flush(vma, addr, ptep);
}
return huge_ptep_get_and_clear(vma->vm_mm, addr, ptep);
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 74c1db8ce271..03efd86dce0a 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -100,7 +100,7 @@ static void __init arch_reserve_crashkernel(void)
bool high = false;
int ret;
- if (!IS_ENABLED(CONFIG_KEXEC_CORE))
+ if (!IS_ENABLED(CONFIG_CRASH_RESERVE))
return;
ret = parse_crashkernel(cmdline, memblock_phys_mem_size(),
@@ -238,7 +238,7 @@ void __init arm64_memblock_init(void)
* physical address of PAGE_OFFSET, we have to *subtract* from it.
*/
if (IS_ENABLED(CONFIG_ARM64_VA_BITS_52) && (vabits_actual != 52))
- memstart_addr -= _PAGE_OFFSET(48) - _PAGE_OFFSET(52);
+ memstart_addr -= _PAGE_OFFSET(vabits_actual) - _PAGE_OFFSET(52);
/*
* Apply the memory limit if it was set. Since the kernel may be loaded
diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c
index 4c7ad574b946..b65a29440a0c 100644
--- a/arch/arm64/mm/kasan_init.c
+++ b/arch/arm64/mm/kasan_init.c
@@ -23,7 +23,7 @@
#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
-static pgd_t tmp_pg_dir[PTRS_PER_PGD] __initdata __aligned(PGD_SIZE);
+static pgd_t tmp_pg_dir[PTRS_PER_PTE] __initdata __aligned(PAGE_SIZE);
/*
* The p*d_populate functions call virt_to_phys implicitly so they can't be used
@@ -99,6 +99,19 @@ static pud_t *__init kasan_pud_offset(p4d_t *p4dp, unsigned long addr, int node,
return early ? pud_offset_kimg(p4dp, addr) : pud_offset(p4dp, addr);
}
+static p4d_t *__init kasan_p4d_offset(pgd_t *pgdp, unsigned long addr, int node,
+ bool early)
+{
+ if (pgd_none(READ_ONCE(*pgdp))) {
+ phys_addr_t p4d_phys = early ?
+ __pa_symbol(kasan_early_shadow_p4d)
+ : kasan_alloc_zeroed_page(node);
+ __pgd_populate(pgdp, p4d_phys, PGD_TYPE_TABLE);
+ }
+
+ return early ? p4d_offset_kimg(pgdp, addr) : p4d_offset(pgdp, addr);
+}
+
static void __init kasan_pte_populate(pmd_t *pmdp, unsigned long addr,
unsigned long end, int node, bool early)
{
@@ -112,8 +125,8 @@ static void __init kasan_pte_populate(pmd_t *pmdp, unsigned long addr,
if (!early)
memset(__va(page_phys), KASAN_SHADOW_INIT, PAGE_SIZE);
next = addr + PAGE_SIZE;
- set_pte(ptep, pfn_pte(__phys_to_pfn(page_phys), PAGE_KERNEL));
- } while (ptep++, addr = next, addr != end && pte_none(READ_ONCE(*ptep)));
+ __set_pte(ptep, pfn_pte(__phys_to_pfn(page_phys), PAGE_KERNEL));
+ } while (ptep++, addr = next, addr != end && pte_none(__ptep_get(ptep)));
}
static void __init kasan_pmd_populate(pud_t *pudp, unsigned long addr,
@@ -144,12 +157,12 @@ static void __init kasan_p4d_populate(pgd_t *pgdp, unsigned long addr,
unsigned long end, int node, bool early)
{
unsigned long next;
- p4d_t *p4dp = p4d_offset(pgdp, addr);
+ p4d_t *p4dp = kasan_p4d_offset(pgdp, addr, node, early);
do {
next = p4d_addr_end(addr, end);
kasan_pud_populate(p4dp, addr, next, node, early);
- } while (p4dp++, addr = next, addr != end);
+ } while (p4dp++, addr = next, addr != end && p4d_none(READ_ONCE(*p4dp)));
}
static void __init kasan_pgd_populate(unsigned long addr, unsigned long end,
@@ -165,19 +178,48 @@ static void __init kasan_pgd_populate(unsigned long addr, unsigned long end,
} while (pgdp++, addr = next, addr != end);
}
+#if defined(CONFIG_ARM64_64K_PAGES) || CONFIG_PGTABLE_LEVELS > 4
+#define SHADOW_ALIGN P4D_SIZE
+#else
+#define SHADOW_ALIGN PUD_SIZE
+#endif
+
+/*
+ * Return whether 'addr' is aligned to the size covered by a root level
+ * descriptor.
+ */
+static bool __init root_level_aligned(u64 addr)
+{
+ int shift = (ARM64_HW_PGTABLE_LEVELS(vabits_actual) - 1) * (PAGE_SHIFT - 3);
+
+ return (addr % (PAGE_SIZE << shift)) == 0;
+}
+
/* The early shadow maps everything to a single page of zeroes */
asmlinkage void __init kasan_early_init(void)
{
BUILD_BUG_ON(KASAN_SHADOW_OFFSET !=
KASAN_SHADOW_END - (1UL << (64 - KASAN_SHADOW_SCALE_SHIFT)));
- /*
- * We cannot check the actual value of KASAN_SHADOW_START during build,
- * as it depends on vabits_actual. As a best-effort approach, check
- * potential values calculated based on VA_BITS and VA_BITS_MIN.
- */
- BUILD_BUG_ON(!IS_ALIGNED(_KASAN_SHADOW_START(VA_BITS), PGDIR_SIZE));
- BUILD_BUG_ON(!IS_ALIGNED(_KASAN_SHADOW_START(VA_BITS_MIN), PGDIR_SIZE));
- BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END, PGDIR_SIZE));
+ BUILD_BUG_ON(!IS_ALIGNED(_KASAN_SHADOW_START(VA_BITS), SHADOW_ALIGN));
+ BUILD_BUG_ON(!IS_ALIGNED(_KASAN_SHADOW_START(VA_BITS_MIN), SHADOW_ALIGN));
+ BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END, SHADOW_ALIGN));
+
+ if (!root_level_aligned(KASAN_SHADOW_START)) {
+ /*
+ * The start address is misaligned, and so the next level table
+ * will be shared with the linear region. This can happen with
+ * 4 or 5 level paging, so install a generic pte_t[] as the
+ * next level. This prevents the kasan_pgd_populate call below
+ * from inserting an entry that refers to the shared KASAN zero
+ * shadow pud_t[]/p4d_t[], which could end up getting corrupted
+ * when the linear region is mapped.
+ */
+ static pte_t tbl[PTRS_PER_PTE] __page_aligned_bss;
+ pgd_t *pgdp = pgd_offset_k(KASAN_SHADOW_START);
+
+ set_pgd(pgdp, __pgd(__pa_symbol(tbl) | PGD_TYPE_TABLE));
+ }
+
kasan_pgd_populate(KASAN_SHADOW_START, KASAN_SHADOW_END, NUMA_NO_NODE,
true);
}
@@ -190,34 +232,74 @@ static void __init kasan_map_populate(unsigned long start, unsigned long end,
}
/*
- * Copy the current shadow region into a new pgdir.
+ * Return the descriptor index of 'addr' in the root level table
*/
-void __init kasan_copy_shadow(pgd_t *pgdir)
+static int __init root_level_idx(u64 addr)
{
- pgd_t *pgdp, *pgdp_new, *pgdp_end;
+ /*
+ * On 64k pages, the TTBR1 range root tables are extended for 52-bit
+ * virtual addressing, and TTBR1 will simply point to the pgd_t entry
+ * that covers the start of the 48-bit addressable VA space if LVA is
+ * not implemented. This means we need to index the table as usual,
+ * instead of masking off bits based on vabits_actual.
+ */
+ u64 vabits = IS_ENABLED(CONFIG_ARM64_64K_PAGES) ? VA_BITS
+ : vabits_actual;
+ int shift = (ARM64_HW_PGTABLE_LEVELS(vabits) - 1) * (PAGE_SHIFT - 3);
- pgdp = pgd_offset_k(KASAN_SHADOW_START);
- pgdp_end = pgd_offset_k(KASAN_SHADOW_END);
- pgdp_new = pgd_offset_pgd(pgdir, KASAN_SHADOW_START);
- do {
- set_pgd(pgdp_new, READ_ONCE(*pgdp));
- } while (pgdp++, pgdp_new++, pgdp != pgdp_end);
+ return (addr & ~_PAGE_OFFSET(vabits)) >> (shift + PAGE_SHIFT);
+}
+
+/*
+ * Clone a next level table from swapper_pg_dir into tmp_pg_dir
+ */
+static void __init clone_next_level(u64 addr, pgd_t *tmp_pg_dir, pud_t *pud)
+{
+ int idx = root_level_idx(addr);
+ pgd_t pgd = READ_ONCE(swapper_pg_dir[idx]);
+ pud_t *pudp = (pud_t *)__phys_to_kimg(__pgd_to_phys(pgd));
+
+ memcpy(pud, pudp, PAGE_SIZE);
+ tmp_pg_dir[idx] = __pgd(__phys_to_pgd_val(__pa_symbol(pud)) |
+ PUD_TYPE_TABLE);
}
-static void __init clear_pgds(unsigned long start,
- unsigned long end)
+/*
+ * Return the descriptor index of 'addr' in the next level table
+ */
+static int __init next_level_idx(u64 addr)
{
- /*
- * Remove references to kasan page tables from
- * swapper_pg_dir. pgd_clear() can't be used
- * here because it's nop on 2,3-level pagetable setups
- */
- for (; start < end; start += PGDIR_SIZE)
- set_pgd(pgd_offset_k(start), __pgd(0));
+ int shift = (ARM64_HW_PGTABLE_LEVELS(vabits_actual) - 2) * (PAGE_SHIFT - 3);
+
+ return (addr >> (shift + PAGE_SHIFT)) % PTRS_PER_PTE;
+}
+
+/*
+ * Dereference the table descriptor at 'pgd_idx' and clear the entries from
+ * 'start' to 'end' (exclusive) from the table.
+ */
+static void __init clear_next_level(int pgd_idx, int start, int end)
+{
+ pgd_t pgd = READ_ONCE(swapper_pg_dir[pgd_idx]);
+ pud_t *pudp = (pud_t *)__phys_to_kimg(__pgd_to_phys(pgd));
+
+ memset(&pudp[start], 0, (end - start) * sizeof(pud_t));
+}
+
+static void __init clear_shadow(u64 start, u64 end)
+{
+ int l = root_level_idx(start), m = root_level_idx(end);
+
+ if (!root_level_aligned(start))
+ clear_next_level(l++, next_level_idx(start), PTRS_PER_PTE);
+ if (!root_level_aligned(end))
+ clear_next_level(m, 0, next_level_idx(end));
+ memset(&swapper_pg_dir[l], 0, (m - l) * sizeof(pgd_t));
}
static void __init kasan_init_shadow(void)
{
+ static pud_t pud[2][PTRS_PER_PUD] __initdata __aligned(PAGE_SIZE);
u64 kimg_shadow_start, kimg_shadow_end;
u64 mod_shadow_start;
u64 vmalloc_shadow_end;
@@ -239,10 +321,23 @@ static void __init kasan_init_shadow(void)
* setup will be finished.
*/
memcpy(tmp_pg_dir, swapper_pg_dir, sizeof(tmp_pg_dir));
+
+ /*
+ * If the start or end address of the shadow region is not aligned to
+ * the root level size, we have to allocate a temporary next-level table
+ * in each case, clone the next level of descriptors, and install the
+ * table into tmp_pg_dir. Note that with 5 levels of paging, the next
+ * level will in fact be p4d_t, but that makes no difference in this
+ * case.
+ */
+ if (!root_level_aligned(KASAN_SHADOW_START))
+ clone_next_level(KASAN_SHADOW_START, tmp_pg_dir, pud[0]);
+ if (!root_level_aligned(KASAN_SHADOW_END))
+ clone_next_level(KASAN_SHADOW_END, tmp_pg_dir, pud[1]);
dsb(ishst);
- cpu_replace_ttbr1(lm_alias(tmp_pg_dir), idmap_pg_dir);
+ cpu_replace_ttbr1(lm_alias(tmp_pg_dir));
- clear_pgds(KASAN_SHADOW_START, KASAN_SHADOW_END);
+ clear_shadow(KASAN_SHADOW_START, KASAN_SHADOW_END);
kasan_map_populate(kimg_shadow_start, kimg_shadow_end,
early_pfn_to_nid(virt_to_pfn(lm_alias(KERNEL_START))));
@@ -271,12 +366,12 @@ static void __init kasan_init_shadow(void)
* so we should make sure that it maps the zero page read-only.
*/
for (i = 0; i < PTRS_PER_PTE; i++)
- set_pte(&kasan_early_shadow_pte[i],
+ __set_pte(&kasan_early_shadow_pte[i],
pfn_pte(sym_to_pfn(kasan_early_shadow_page),
PAGE_KERNEL_RO));
memset(kasan_early_shadow_page, KASAN_SHADOW_INIT, PAGE_SIZE);
- cpu_replace_ttbr1(lm_alias(swapper_pg_dir), idmap_pg_dir);
+ cpu_replace_ttbr1(lm_alias(swapper_pg_dir));
}
static void __init kasan_init_depth(void)
diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c
index 645fe60d000f..642bdf908b22 100644
--- a/arch/arm64/mm/mmap.c
+++ b/arch/arm64/mm/mmap.c
@@ -73,6 +73,10 @@ static int __init adjust_protection_map(void)
protection_map[VM_EXEC | VM_SHARED] = PAGE_EXECONLY;
}
+ if (lpa2_is_enabled())
+ for (int i = 0; i < ARRAY_SIZE(protection_map); i++)
+ pgprot_val(protection_map[i]) &= ~PTE_SHARED;
+
return 0;
}
arch_initcall(adjust_protection_map);
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 1ac7467d34c9..495b732d5af3 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -45,18 +45,13 @@
#define NO_CONT_MAPPINGS BIT(1)
#define NO_EXEC_MAPPINGS BIT(2) /* assumes FEAT_HPDS is not used */
-int idmap_t0sz __ro_after_init;
-
-#if VA_BITS > 48
-u64 vabits_actual __ro_after_init = VA_BITS_MIN;
-EXPORT_SYMBOL(vabits_actual);
-#endif
-
u64 kimage_voffset __ro_after_init;
EXPORT_SYMBOL(kimage_voffset);
u32 __boot_cpu_mode[] = { BOOT_CPU_MODE_EL2, BOOT_CPU_MODE_EL1 };
+static bool rodata_is_rw __ro_after_init = true;
+
/*
* The booting CPU updates the failed status @__early_cpu_boot_status,
* with MMU turned off.
@@ -73,10 +68,21 @@ EXPORT_SYMBOL(empty_zero_page);
static DEFINE_SPINLOCK(swapper_pgdir_lock);
static DEFINE_MUTEX(fixmap_lock);
-void set_swapper_pgd(pgd_t *pgdp, pgd_t pgd)
+void noinstr set_swapper_pgd(pgd_t *pgdp, pgd_t pgd)
{
pgd_t *fixmap_pgdp;
+ /*
+ * Don't bother with the fixmap if swapper_pg_dir is still mapped
+ * writable in the kernel mapping.
+ */
+ if (rodata_is_rw) {
+ WRITE_ONCE(*pgdp, pgd);
+ dsb(ishst);
+ isb();
+ return;
+ }
+
spin_lock(&swapper_pgdir_lock);
fixmap_pgdp = pgd_set_fixmap(__pa_symbol(pgdp));
WRITE_ONCE(*fixmap_pgdp, pgd);
@@ -173,16 +179,16 @@ static void init_pte(pmd_t *pmdp, unsigned long addr, unsigned long end,
ptep = pte_set_fixmap_offset(pmdp, addr);
do {
- pte_t old_pte = READ_ONCE(*ptep);
+ pte_t old_pte = __ptep_get(ptep);
- set_pte(ptep, pfn_pte(__phys_to_pfn(phys), prot));
+ __set_pte(ptep, pfn_pte(__phys_to_pfn(phys), prot));
/*
* After the PTE entry has been populated once, we
* only allow updates to the permission attributes.
*/
BUG_ON(!pgattr_change_is_safe(pte_val(old_pte),
- READ_ONCE(pte_val(*ptep))));
+ pte_val(__ptep_get(ptep))));
phys += PAGE_SIZE;
} while (ptep++, addr += PAGE_SIZE, addr != end);
@@ -307,15 +313,14 @@ static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
} while (addr = next, addr != end);
}
-static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
+static void alloc_init_pud(p4d_t *p4dp, unsigned long addr, unsigned long end,
phys_addr_t phys, pgprot_t prot,
phys_addr_t (*pgtable_alloc)(int),
int flags)
{
unsigned long next;
- pud_t *pudp;
- p4d_t *p4dp = p4d_offset(pgdp, addr);
p4d_t p4d = READ_ONCE(*p4dp);
+ pud_t *pudp;
if (p4d_none(p4d)) {
p4dval_t p4dval = P4D_TYPE_TABLE | P4D_TABLE_UXN;
@@ -363,6 +368,46 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
pud_clear_fixmap();
}
+static void alloc_init_p4d(pgd_t *pgdp, unsigned long addr, unsigned long end,
+ phys_addr_t phys, pgprot_t prot,
+ phys_addr_t (*pgtable_alloc)(int),
+ int flags)
+{
+ unsigned long next;
+ pgd_t pgd = READ_ONCE(*pgdp);
+ p4d_t *p4dp;
+
+ if (pgd_none(pgd)) {
+ pgdval_t pgdval = PGD_TYPE_TABLE | PGD_TABLE_UXN;
+ phys_addr_t p4d_phys;
+
+ if (flags & NO_EXEC_MAPPINGS)
+ pgdval |= PGD_TABLE_PXN;
+ BUG_ON(!pgtable_alloc);
+ p4d_phys = pgtable_alloc(P4D_SHIFT);
+ __pgd_populate(pgdp, p4d_phys, pgdval);
+ pgd = READ_ONCE(*pgdp);
+ }
+ BUG_ON(pgd_bad(pgd));
+
+ p4dp = p4d_set_fixmap_offset(pgdp, addr);
+ do {
+ p4d_t old_p4d = READ_ONCE(*p4dp);
+
+ next = p4d_addr_end(addr, end);
+
+ alloc_init_pud(p4dp, addr, next, phys, prot,
+ pgtable_alloc, flags);
+
+ BUG_ON(p4d_val(old_p4d) != 0 &&
+ p4d_val(old_p4d) != READ_ONCE(p4d_val(*p4dp)));
+
+ phys += next - addr;
+ } while (p4dp++, addr = next, addr != end);
+
+ p4d_clear_fixmap();
+}
+
static void __create_pgd_mapping_locked(pgd_t *pgdir, phys_addr_t phys,
unsigned long virt, phys_addr_t size,
pgprot_t prot,
@@ -385,7 +430,7 @@ static void __create_pgd_mapping_locked(pgd_t *pgdir, phys_addr_t phys,
do {
next = pgd_addr_end(addr, end);
- alloc_init_pud(pgdp, addr, next, phys, prot, pgtable_alloc,
+ alloc_init_p4d(pgdp, addr, next, phys, prot, pgtable_alloc,
flags);
phys += next - addr;
} while (pgdp++, addr = next, addr != end);
@@ -576,8 +621,12 @@ static void __init map_mem(pgd_t *pgdp)
* entries at any level are being shared between the linear region and
* the vmalloc region. Check whether this is true for the PGD level, in
* which case it is guaranteed to be true for all other levels as well.
+ * (Unless we are running with support for LPA2, in which case the
+ * entire reduced VA space is covered by a single pgd_t which will have
+ * been populated without the PXNTable attribute by the time we get here.)
*/
- BUILD_BUG_ON(pgd_index(direct_map_end - 1) == pgd_index(direct_map_end));
+ BUILD_BUG_ON(pgd_index(direct_map_end - 1) == pgd_index(direct_map_end) &&
+ pgd_index(_PAGE_OFFSET(VA_BITS_MIN)) != PTRS_PER_PGD - 1);
early_kfence_pool = arm64_kfence_alloc_pool();
@@ -630,15 +679,14 @@ void mark_rodata_ro(void)
* to cover NOTES and EXCEPTION_TABLE.
*/
section_size = (unsigned long)__init_begin - (unsigned long)__start_rodata;
+ WRITE_ONCE(rodata_is_rw, false);
update_mapping_prot(__pa_symbol(__start_rodata), (unsigned long)__start_rodata,
section_size, PAGE_KERNEL_RO);
-
- debug_checkwx();
}
-static void __init map_kernel_segment(pgd_t *pgdp, void *va_start, void *va_end,
- pgprot_t prot, struct vm_struct *vma,
- int flags, unsigned long vm_flags)
+static void __init declare_vma(struct vm_struct *vma,
+ void *va_start, void *va_end,
+ unsigned long vm_flags)
{
phys_addr_t pa_start = __pa_symbol(va_start);
unsigned long size = va_end - va_start;
@@ -646,9 +694,6 @@ static void __init map_kernel_segment(pgd_t *pgdp, void *va_start, void *va_end,
BUG_ON(!PAGE_ALIGNED(pa_start));
BUG_ON(!PAGE_ALIGNED(size));
- __create_pgd_mapping(pgdp, pa_start, (unsigned long)va_start, size, prot,
- early_pgtable_alloc, flags);
-
if (!(vm_flags & VM_NO_GUARD))
size += PAGE_SIZE;
@@ -661,12 +706,12 @@ static void __init map_kernel_segment(pgd_t *pgdp, void *va_start, void *va_end,
vm_area_add_early(vma);
}
+#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
static pgprot_t kernel_exec_prot(void)
{
return rodata_enabled ? PAGE_KERNEL_ROX : PAGE_KERNEL_EXEC;
}
-#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
static int __init map_entry_trampoline(void)
{
int i;
@@ -701,80 +746,36 @@ core_initcall(map_entry_trampoline);
#endif
/*
- * Open coded check for BTI, only for use to determine configuration
- * for early mappings for before the cpufeature code has run.
+ * Declare the VMA areas for the kernel
*/
-static bool arm64_early_this_cpu_has_bti(void)
+static void __init declare_kernel_vmas(void)
{
- u64 pfr1;
-
- if (!IS_ENABLED(CONFIG_ARM64_BTI_KERNEL))
- return false;
+ static struct vm_struct vmlinux_seg[KERNEL_SEGMENT_COUNT];
- pfr1 = __read_sysreg_by_encoding(SYS_ID_AA64PFR1_EL1);
- return cpuid_feature_extract_unsigned_field(pfr1,
- ID_AA64PFR1_EL1_BT_SHIFT);
+ declare_vma(&vmlinux_seg[0], _stext, _etext, VM_NO_GUARD);
+ declare_vma(&vmlinux_seg[1], __start_rodata, __inittext_begin, VM_NO_GUARD);
+ declare_vma(&vmlinux_seg[2], __inittext_begin, __inittext_end, VM_NO_GUARD);
+ declare_vma(&vmlinux_seg[3], __initdata_begin, __initdata_end, VM_NO_GUARD);
+ declare_vma(&vmlinux_seg[4], _data, _end, 0);
}
-/*
- * Create fine-grained mappings for the kernel.
- */
-static void __init map_kernel(pgd_t *pgdp)
-{
- static struct vm_struct vmlinux_text, vmlinux_rodata, vmlinux_inittext,
- vmlinux_initdata, vmlinux_data;
-
- /*
- * External debuggers may need to write directly to the text
- * mapping to install SW breakpoints. Allow this (only) when
- * explicitly requested with rodata=off.
- */
- pgprot_t text_prot = kernel_exec_prot();
-
- /*
- * If we have a CPU that supports BTI and a kernel built for
- * BTI then mark the kernel executable text as guarded pages
- * now so we don't have to rewrite the page tables later.
- */
- if (arm64_early_this_cpu_has_bti())
- text_prot = __pgprot_modify(text_prot, PTE_GP, PTE_GP);
-
- /*
- * Only rodata will be remapped with different permissions later on,
- * all other segments are allowed to use contiguous mappings.
- */
- map_kernel_segment(pgdp, _stext, _etext, text_prot, &vmlinux_text, 0,
- VM_NO_GUARD);
- map_kernel_segment(pgdp, __start_rodata, __inittext_begin, PAGE_KERNEL,
- &vmlinux_rodata, NO_CONT_MAPPINGS, VM_NO_GUARD);
- map_kernel_segment(pgdp, __inittext_begin, __inittext_end, text_prot,
- &vmlinux_inittext, 0, VM_NO_GUARD);
- map_kernel_segment(pgdp, __initdata_begin, __initdata_end, PAGE_KERNEL,
- &vmlinux_initdata, 0, VM_NO_GUARD);
- map_kernel_segment(pgdp, _data, _end, PAGE_KERNEL, &vmlinux_data, 0, 0);
+void __pi_map_range(u64 *pgd, u64 start, u64 end, u64 pa, pgprot_t prot,
+ int level, pte_t *tbl, bool may_use_cont, u64 va_offset);
- fixmap_copy(pgdp);
- kasan_copy_shadow(pgdp);
-}
+static u8 idmap_ptes[IDMAP_LEVELS - 1][PAGE_SIZE] __aligned(PAGE_SIZE) __ro_after_init,
+ kpti_ptes[IDMAP_LEVELS - 1][PAGE_SIZE] __aligned(PAGE_SIZE) __ro_after_init;
static void __init create_idmap(void)
{
u64 start = __pa_symbol(__idmap_text_start);
- u64 size = __pa_symbol(__idmap_text_end) - start;
- pgd_t *pgd = idmap_pg_dir;
- u64 pgd_phys;
-
- /* check if we need an additional level of translation */
- if (VA_BITS < 48 && idmap_t0sz < (64 - VA_BITS_MIN)) {
- pgd_phys = early_pgtable_alloc(PAGE_SHIFT);
- set_pgd(&idmap_pg_dir[start >> VA_BITS],
- __pgd(pgd_phys | P4D_TYPE_TABLE));
- pgd = __va(pgd_phys);
- }
- __create_pgd_mapping(pgd, start, start, size, PAGE_KERNEL_ROX,
- early_pgtable_alloc, 0);
+ u64 end = __pa_symbol(__idmap_text_end);
+ u64 ptep = __pa_symbol(idmap_ptes);
- if (IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0)) {
+ __pi_map_range(&ptep, start, end, start, PAGE_KERNEL_ROX,
+ IDMAP_ROOT_LEVEL, (pte_t *)idmap_pg_dir, false,
+ __phys_to_virt(ptep) - ptep);
+
+ if (IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0) && !arm64_use_ng_mappings) {
extern u32 __idmap_kpti_flag;
u64 pa = __pa_symbol(&__idmap_kpti_flag);
@@ -782,32 +783,21 @@ static void __init create_idmap(void)
* The KPTI G-to-nG conversion code needs a read-write mapping
* of its synchronization flag in the ID map.
*/
- __create_pgd_mapping(pgd, pa, pa, sizeof(u32), PAGE_KERNEL,
- early_pgtable_alloc, 0);
+ ptep = __pa_symbol(kpti_ptes);
+ __pi_map_range(&ptep, pa, pa + sizeof(u32), pa, PAGE_KERNEL,
+ IDMAP_ROOT_LEVEL, (pte_t *)idmap_pg_dir, false,
+ __phys_to_virt(ptep) - ptep);
}
}
void __init paging_init(void)
{
- pgd_t *pgdp = pgd_set_fixmap(__pa_symbol(swapper_pg_dir));
- extern pgd_t init_idmap_pg_dir[];
-
- idmap_t0sz = 63UL - __fls(__pa_symbol(_end) | GENMASK(VA_BITS_MIN - 1, 0));
-
- map_kernel(pgdp);
- map_mem(pgdp);
-
- pgd_clear_fixmap();
-
- cpu_replace_ttbr1(lm_alias(swapper_pg_dir), init_idmap_pg_dir);
- init_mm.pgd = swapper_pg_dir;
-
- memblock_phys_free(__pa_symbol(init_pg_dir),
- __pa_symbol(init_pg_end) - __pa_symbol(init_pg_dir));
+ map_mem(swapper_pg_dir);
memblock_allow_resize();
create_idmap();
+ declare_kernel_vmas();
}
#ifdef CONFIG_MEMORY_HOTPLUG
@@ -854,12 +844,12 @@ static void unmap_hotplug_pte_range(pmd_t *pmdp, unsigned long addr,
do {
ptep = pte_offset_kernel(pmdp, addr);
- pte = READ_ONCE(*ptep);
+ pte = __ptep_get(ptep);
if (pte_none(pte))
continue;
WARN_ON(!pte_present(pte));
- pte_clear(&init_mm, addr, ptep);
+ __pte_clear(&init_mm, addr, ptep);
flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
if (free_mapped)
free_hotplug_page_range(pte_page(pte),
@@ -987,7 +977,7 @@ static void free_empty_pte_table(pmd_t *pmdp, unsigned long addr,
do {
ptep = pte_offset_kernel(pmdp, addr);
- pte = READ_ONCE(*ptep);
+ pte = __ptep_get(ptep);
/*
* This is just a sanity check here which verifies that
@@ -1006,7 +996,7 @@ static void free_empty_pte_table(pmd_t *pmdp, unsigned long addr,
*/
ptep = pte_offset_kernel(pmdp, 0UL);
for (i = 0; i < PTRS_PER_PTE; i++) {
- if (!pte_none(READ_ONCE(ptep[i])))
+ if (!pte_none(__ptep_get(&ptep[i])))
return;
}
@@ -1073,10 +1063,10 @@ static void free_empty_pud_table(p4d_t *p4dp, unsigned long addr,
free_empty_pmd_table(pudp, addr, next, floor, ceiling);
} while (addr = next, addr < end);
- if (CONFIG_PGTABLE_LEVELS <= 3)
+ if (!pgtable_l4_enabled())
return;
- if (!pgtable_range_aligned(start, end, floor, ceiling, PGDIR_MASK))
+ if (!pgtable_range_aligned(start, end, floor, ceiling, P4D_MASK))
return;
/*
@@ -1099,8 +1089,8 @@ static void free_empty_p4d_table(pgd_t *pgdp, unsigned long addr,
unsigned long end, unsigned long floor,
unsigned long ceiling)
{
- unsigned long next;
p4d_t *p4dp, p4d;
+ unsigned long i, next, start = addr;
do {
next = p4d_addr_end(addr, end);
@@ -1112,6 +1102,27 @@ static void free_empty_p4d_table(pgd_t *pgdp, unsigned long addr,
WARN_ON(!p4d_present(p4d));
free_empty_pud_table(p4dp, addr, next, floor, ceiling);
} while (addr = next, addr < end);
+
+ if (!pgtable_l5_enabled())
+ return;
+
+ if (!pgtable_range_aligned(start, end, floor, ceiling, PGDIR_MASK))
+ return;
+
+ /*
+ * Check whether we can free the p4d page if the rest of the
+ * entries are empty. Overlap with other regions have been
+ * handled by the floor/ceiling check.
+ */
+ p4dp = p4d_offset(pgdp, 0UL);
+ for (i = 0; i < PTRS_PER_P4D; i++) {
+ if (!p4d_none(READ_ONCE(p4dp[i])))
+ return;
+ }
+
+ pgd_clear(pgdp);
+ __flush_tlb_kernel_pgtable(start);
+ free_hotplug_pgtable_page(virt_to_page(p4dp));
}
static void free_empty_tables(unsigned long addr, unsigned long end,
@@ -1196,6 +1207,12 @@ int pmd_set_huge(pmd_t *pmdp, phys_addr_t phys, pgprot_t prot)
return 1;
}
+#ifndef __PAGETABLE_P4D_FOLDED
+void p4d_clear_huge(p4d_t *p4dp)
+{
+}
+#endif
+
int pud_clear_huge(pud_t *pudp)
{
if (!pud_sect(READ_ONCE(*pudp)))
@@ -1475,7 +1492,7 @@ pte_t ptep_modify_prot_start(struct vm_area_struct *vma, unsigned long addr, pte
* when the permission changes from executable to non-executable
* in cases where cpu is affected with errata #2645198.
*/
- if (pte_user_exec(READ_ONCE(*ptep)))
+ if (pte_user_exec(ptep_get(ptep)))
return ptep_clear_flush(vma, addr, ptep);
}
return ptep_get_and_clear(vma->vm_mm, addr, ptep);
@@ -1486,3 +1503,35 @@ void ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr, pte
{
set_pte_at(vma->vm_mm, addr, ptep, pte);
}
+
+/*
+ * Atomically replaces the active TTBR1_EL1 PGD with a new VA-compatible PGD,
+ * avoiding the possibility of conflicting TLB entries being allocated.
+ */
+void __cpu_replace_ttbr1(pgd_t *pgdp, bool cnp)
+{
+ typedef void (ttbr_replace_func)(phys_addr_t);
+ extern ttbr_replace_func idmap_cpu_replace_ttbr1;
+ ttbr_replace_func *replace_phys;
+ unsigned long daif;
+
+ /* phys_to_ttbr() zeros lower 2 bits of ttbr with 52-bit PA */
+ phys_addr_t ttbr1 = phys_to_ttbr(virt_to_phys(pgdp));
+
+ if (cnp)
+ ttbr1 |= TTBR_CNP_BIT;
+
+ replace_phys = (void *)__pa_symbol(idmap_cpu_replace_ttbr1);
+
+ cpu_install_idmap();
+
+ /*
+ * We really don't want to take *any* exceptions while TTBR1 is
+ * in the process of being replaced so mask everything.
+ */
+ daif = local_daif_save();
+ replace_phys(ttbr1);
+ local_daif_restore(daif);
+
+ cpu_uninstall_idmap();
+}
diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
index 924843f1f661..0c4e3ecf989d 100644
--- a/arch/arm64/mm/pageattr.c
+++ b/arch/arm64/mm/pageattr.c
@@ -36,12 +36,12 @@ bool can_set_direct_map(void)
static int change_page_range(pte_t *ptep, unsigned long addr, void *data)
{
struct page_change_data *cdata = data;
- pte_t pte = READ_ONCE(*ptep);
+ pte_t pte = __ptep_get(ptep);
pte = clear_pte_bit(pte, cdata->clear_mask);
pte = set_pte_bit(pte, cdata->set_mask);
- set_pte(ptep, pte);
+ __set_pte(ptep, pte);
return 0;
}
@@ -245,5 +245,5 @@ bool kernel_page_present(struct page *page)
return true;
ptep = pte_offset_kernel(pmdp, addr);
- return pte_valid(READ_ONCE(*ptep));
+ return pte_valid(__ptep_get(ptep));
}
diff --git a/arch/arm64/mm/pgd.c b/arch/arm64/mm/pgd.c
index 4a64089e5771..0c501cabc238 100644
--- a/arch/arm64/mm/pgd.c
+++ b/arch/arm64/mm/pgd.c
@@ -17,11 +17,22 @@
static struct kmem_cache *pgd_cache __ro_after_init;
+static bool pgdir_is_page_size(void)
+{
+ if (PGD_SIZE == PAGE_SIZE)
+ return true;
+ if (CONFIG_PGTABLE_LEVELS == 4)
+ return !pgtable_l4_enabled();
+ if (CONFIG_PGTABLE_LEVELS == 5)
+ return !pgtable_l5_enabled();
+ return false;
+}
+
pgd_t *pgd_alloc(struct mm_struct *mm)
{
gfp_t gfp = GFP_PGTABLE_USER;
- if (PGD_SIZE == PAGE_SIZE)
+ if (pgdir_is_page_size())
return (pgd_t *)__get_free_page(gfp);
else
return kmem_cache_alloc(pgd_cache, gfp);
@@ -29,7 +40,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
void pgd_free(struct mm_struct *mm, pgd_t *pgd)
{
- if (PGD_SIZE == PAGE_SIZE)
+ if (pgdir_is_page_size())
free_page((unsigned long)pgd);
else
kmem_cache_free(pgd_cache, pgd);
@@ -37,7 +48,7 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd)
void __init pgtable_cache_init(void)
{
- if (PGD_SIZE == PAGE_SIZE)
+ if (pgdir_is_page_size())
return;
#ifdef CONFIG_ARM64_PA_BITS_52
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index f66c37a1610e..9d40f3ffd8d2 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -195,27 +195,36 @@ SYM_TYPED_FUNC_START(idmap_cpu_replace_ttbr1)
ret
SYM_FUNC_END(idmap_cpu_replace_ttbr1)
+SYM_FUNC_ALIAS(__pi_idmap_cpu_replace_ttbr1, idmap_cpu_replace_ttbr1)
.popsection
#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
-#define KPTI_NG_PTE_FLAGS (PTE_ATTRINDX(MT_NORMAL) | SWAPPER_PTE_FLAGS | PTE_WRITE)
+#define KPTI_NG_PTE_FLAGS (PTE_ATTRINDX(MT_NORMAL) | PTE_TYPE_PAGE | \
+ PTE_AF | PTE_SHARED | PTE_UXN | PTE_WRITE)
.pushsection ".idmap.text", "a"
+ .macro pte_to_phys, phys, pte
+ and \phys, \pte, #PTE_ADDR_LOW
+#ifdef CONFIG_ARM64_PA_BITS_52
+ and \pte, \pte, #PTE_ADDR_HIGH
+ orr \phys, \phys, \pte, lsl #PTE_ADDR_HIGH_SHIFT
+#endif
+ .endm
+
.macro kpti_mk_tbl_ng, type, num_entries
add end_\type\()p, cur_\type\()p, #\num_entries * 8
.Ldo_\type:
- ldr \type, [cur_\type\()p] // Load the entry
+ ldr \type, [cur_\type\()p], #8 // Load the entry and advance
tbz \type, #0, .Lnext_\type // Skip invalid and
tbnz \type, #11, .Lnext_\type // non-global entries
orr \type, \type, #PTE_NG // Same bit for blocks and pages
- str \type, [cur_\type\()p] // Update the entry
+ str \type, [cur_\type\()p, #-8] // Update the entry
.ifnc \type, pte
tbnz \type, #1, .Lderef_\type
.endif
.Lnext_\type:
- add cur_\type\()p, cur_\type\()p, #8
cmp cur_\type\()p, end_\type\()p
b.ne .Ldo_\type
.endm
@@ -225,18 +234,18 @@ SYM_FUNC_END(idmap_cpu_replace_ttbr1)
* fixmap slot associated with the current level.
*/
.macro kpti_map_pgtbl, type, level
- str xzr, [temp_pte, #8 * (\level + 1)] // break before make
+ str xzr, [temp_pte, #8 * (\level + 2)] // break before make
dsb nshst
- add pte, temp_pte, #PAGE_SIZE * (\level + 1)
+ add pte, temp_pte, #PAGE_SIZE * (\level + 2)
lsr pte, pte, #12
tlbi vaae1, pte
dsb nsh
isb
phys_to_pte pte, cur_\type\()p
- add cur_\type\()p, temp_pte, #PAGE_SIZE * (\level + 1)
+ add cur_\type\()p, temp_pte, #PAGE_SIZE * (\level + 2)
orr pte, pte, pte_flags
- str pte, [temp_pte, #8 * (\level + 1)]
+ str pte, [temp_pte, #8 * (\level + 2)]
dsb nshst
.endm
@@ -269,6 +278,8 @@ SYM_TYPED_FUNC_START(idmap_kpti_install_ng_mappings)
end_ptep .req x15
pte .req x16
valid .req x17
+ cur_p4dp .req x19
+ end_p4dp .req x20
mov x5, x3 // preserve temp_pte arg
mrs swapper_ttb, ttbr1_el1
@@ -276,6 +287,12 @@ SYM_TYPED_FUNC_START(idmap_kpti_install_ng_mappings)
cbnz cpu, __idmap_kpti_secondary
+#if CONFIG_PGTABLE_LEVELS > 4
+ stp x29, x30, [sp, #-32]!
+ mov x29, sp
+ stp x19, x20, [sp, #16]
+#endif
+
/* We're the boot CPU. Wait for the others to catch up */
sevl
1: wfe
@@ -293,9 +310,32 @@ SYM_TYPED_FUNC_START(idmap_kpti_install_ng_mappings)
mov_q pte_flags, KPTI_NG_PTE_FLAGS
/* Everybody is enjoying the idmap, so we can rewrite swapper. */
+
+#ifdef CONFIG_ARM64_LPA2
+ /*
+ * If LPA2 support is configured, but 52-bit virtual addressing is not
+ * enabled at runtime, we will fall back to one level of paging less,
+ * and so we have to walk swapper_pg_dir as if we dereferenced its
+ * address from a PGD level entry, and terminate the PGD level loop
+ * right after.
+ */
+ adrp pgd, swapper_pg_dir // walk &swapper_pg_dir at the next level
+ mov cur_pgdp, end_pgdp // must be equal to terminate the PGD loop
+alternative_if_not ARM64_HAS_VA52
+ b .Lderef_pgd // skip to the next level
+alternative_else_nop_endif
+ /*
+ * LPA2 based 52-bit virtual addressing requires 52-bit physical
+ * addressing to be enabled as well. In this case, the shareability
+ * bits are repurposed as physical address bits, and should not be
+ * set in pte_flags.
+ */
+ bic pte_flags, pte_flags, #PTE_SHARED
+#endif
+
/* PGD */
adrp cur_pgdp, swapper_pg_dir
- kpti_map_pgtbl pgd, 0
+ kpti_map_pgtbl pgd, -1
kpti_mk_tbl_ng pgd, PTRS_PER_PGD
/* Ensure all the updated entries are visible to secondary CPUs */
@@ -308,16 +348,33 @@ SYM_TYPED_FUNC_START(idmap_kpti_install_ng_mappings)
/* Set the flag to zero to indicate that we're all done */
str wzr, [flag_ptr]
+#if CONFIG_PGTABLE_LEVELS > 4
+ ldp x19, x20, [sp, #16]
+ ldp x29, x30, [sp], #32
+#endif
ret
.Lderef_pgd:
+ /* P4D */
+ .if CONFIG_PGTABLE_LEVELS > 4
+ p4d .req x30
+ pte_to_phys cur_p4dp, pgd
+ kpti_map_pgtbl p4d, 0
+ kpti_mk_tbl_ng p4d, PTRS_PER_P4D
+ b .Lnext_pgd
+ .else /* CONFIG_PGTABLE_LEVELS <= 4 */
+ p4d .req pgd
+ .set .Lnext_p4d, .Lnext_pgd
+ .endif
+
+.Lderef_p4d:
/* PUD */
.if CONFIG_PGTABLE_LEVELS > 3
pud .req x10
- pte_to_phys cur_pudp, pgd
+ pte_to_phys cur_pudp, p4d
kpti_map_pgtbl pud, 1
kpti_mk_tbl_ng pud, PTRS_PER_PUD
- b .Lnext_pgd
+ b .Lnext_p4d
.else /* CONFIG_PGTABLE_LEVELS <= 3 */
pud .req pgd
.set .Lnext_pud, .Lnext_pgd
@@ -361,6 +418,9 @@ SYM_TYPED_FUNC_START(idmap_kpti_install_ng_mappings)
.unreq end_ptep
.unreq pte
.unreq valid
+ .unreq cur_p4dp
+ .unreq end_p4dp
+ .unreq p4d
/* Secondary CPUs end up here */
__idmap_kpti_secondary:
@@ -395,8 +455,6 @@ SYM_FUNC_END(idmap_kpti_install_ng_mappings)
*
* Initialise the processor for turning the MMU on.
*
- * Input:
- * x0 - actual number of VA bits (ignored unless VA_BITS > 48)
* Output:
* Return in x0 the value of the SCTLR_EL1 register.
*/
@@ -420,20 +478,21 @@ SYM_FUNC_START(__cpu_setup)
mair .req x17
tcr .req x16
mov_q mair, MAIR_EL1_SET
- mov_q tcr, TCR_TxSZ(VA_BITS) | TCR_CACHE_FLAGS | TCR_SMP_FLAGS | \
- TCR_TG_FLAGS | TCR_KASLR_FLAGS | TCR_ASID16 | \
- TCR_TBI0 | TCR_A1 | TCR_KASAN_SW_FLAGS | TCR_MTE_FLAGS
+ mov_q tcr, TCR_T0SZ(IDMAP_VA_BITS) | TCR_T1SZ(VA_BITS_MIN) | TCR_CACHE_FLAGS | \
+ TCR_SMP_FLAGS | TCR_TG_FLAGS | TCR_KASLR_FLAGS | TCR_ASID16 | \
+ TCR_TBI0 | TCR_A1 | TCR_KASAN_SW_FLAGS | TCR_MTE_FLAGS
tcr_clear_errata_bits tcr, x9, x5
#ifdef CONFIG_ARM64_VA_BITS_52
- sub x9, xzr, x0
- add x9, x9, #64
+ mov x9, #64 - VA_BITS
+alternative_if ARM64_HAS_VA52
tcr_set_t1sz tcr, x9
-#else
- idmap_get_t0sz x9
+#ifdef CONFIG_ARM64_LPA2
+ orr tcr, tcr, #TCR_DS
+#endif
+alternative_else_nop_endif
#endif
- tcr_set_t0sz tcr, x9
/*
* Set the IPS bits in TCR_EL1.
@@ -458,11 +517,26 @@ SYM_FUNC_START(__cpu_setup)
ubfx x1, x1, #ID_AA64MMFR3_EL1_S1PIE_SHIFT, #4
cbz x1, .Lskip_indirection
+ /*
+ * The PROT_* macros describing the various memory types may resolve to
+ * C expressions if they include the PTE_MAYBE_* macros, and so they
+ * can only be used from C code. The PIE_E* constants below are also
+ * defined in terms of those macros, but will mask out those
+ * PTE_MAYBE_* constants, whether they are set or not. So #define them
+ * as 0x0 here so we can evaluate the PIE_E* constants in asm context.
+ */
+
+#define PTE_MAYBE_NG 0
+#define PTE_MAYBE_SHARED 0
+
mov_q x0, PIE_E0
msr REG_PIRE0_EL1, x0
mov_q x0, PIE_E1
msr REG_PIR_EL1, x0
+#undef PTE_MAYBE_NG
+#undef PTE_MAYBE_SHARED
+
mov x0, TCR2_EL1x_PIE
msr REG_TCR2_EL1, x0
diff --git a/arch/arm64/mm/ptdump.c b/arch/arm64/mm/ptdump.c
index e305b6593c4e..6986827e0d64 100644
--- a/arch/arm64/mm/ptdump.c
+++ b/arch/arm64/mm/ptdump.c
@@ -26,34 +26,6 @@
#include <asm/ptdump.h>
-enum address_markers_idx {
- PAGE_OFFSET_NR = 0,
- PAGE_END_NR,
-#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
- KASAN_START_NR,
-#endif
-};
-
-static struct addr_marker address_markers[] = {
- { PAGE_OFFSET, "Linear Mapping start" },
- { 0 /* PAGE_END */, "Linear Mapping end" },
-#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
- { 0 /* KASAN_SHADOW_START */, "Kasan shadow start" },
- { KASAN_SHADOW_END, "Kasan shadow end" },
-#endif
- { MODULES_VADDR, "Modules start" },
- { MODULES_END, "Modules end" },
- { VMALLOC_START, "vmalloc() area" },
- { VMALLOC_END, "vmalloc() end" },
- { FIXADDR_TOT_START, "Fixmap start" },
- { FIXADDR_TOP, "Fixmap end" },
- { PCI_IO_START, "PCI I/O start" },
- { PCI_IO_END, "PCI I/O end" },
- { VMEMMAP_START, "vmemmap start" },
- { VMEMMAP_START + VMEMMAP_SIZE, "vmemmap end" },
- { -1, NULL },
-};
-
#define pt_dump_seq_printf(m, fmt, args...) \
({ \
if (m) \
@@ -76,6 +48,7 @@ struct pg_state {
struct ptdump_state ptdump;
struct seq_file *seq;
const struct addr_marker *marker;
+ const struct mm_struct *mm;
unsigned long start_address;
int level;
u64 current_prot;
@@ -172,12 +145,12 @@ static const struct prot_bits pte_bits[] = {
struct pg_level {
const struct prot_bits *bits;
- const char *name;
- size_t num;
+ char name[4];
+ int num;
u64 mask;
};
-static struct pg_level pg_level[] = {
+static struct pg_level pg_level[] __ro_after_init = {
{ /* pgd */
.name = "PGD",
.bits = pte_bits,
@@ -187,11 +160,11 @@ static struct pg_level pg_level[] = {
.bits = pte_bits,
.num = ARRAY_SIZE(pte_bits),
}, { /* pud */
- .name = (CONFIG_PGTABLE_LEVELS > 3) ? "PUD" : "PGD",
+ .name = "PUD",
.bits = pte_bits,
.num = ARRAY_SIZE(pte_bits),
}, { /* pmd */
- .name = (CONFIG_PGTABLE_LEVELS > 2) ? "PMD" : "PGD",
+ .name = "PMD",
.bits = pte_bits,
.num = ARRAY_SIZE(pte_bits),
}, { /* pte */
@@ -255,6 +228,11 @@ static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
static const char units[] = "KMGTPE";
u64 prot = 0;
+ /* check if the current level has been folded dynamically */
+ if ((level == 1 && mm_p4d_folded(st->mm)) ||
+ (level == 2 && mm_pud_folded(st->mm)))
+ level = 0;
+
if (level >= 0)
prot = val & pg_level[level].mask;
@@ -316,6 +294,7 @@ void ptdump_walk(struct seq_file *s, struct ptdump_info *info)
st = (struct pg_state){
.seq = s,
.marker = info->markers,
+ .mm = info->mm,
.level = -1,
.ptdump = {
.note_page = note_page,
@@ -339,13 +318,11 @@ static void __init ptdump_initialize(void)
pg_level[i].mask |= pg_level[i].bits[j].mask;
}
-static struct ptdump_info kernel_ptdump_info = {
+static struct ptdump_info kernel_ptdump_info __ro_after_init = {
.mm = &init_mm,
- .markers = address_markers,
- .base_addr = PAGE_OFFSET,
};
-void ptdump_check_wx(void)
+bool ptdump_check_wx(void)
{
struct pg_state st = {
.seq = NULL,
@@ -358,7 +335,7 @@ void ptdump_check_wx(void)
.ptdump = {
.note_page = note_page,
.range = (struct ptdump_range[]) {
- {PAGE_OFFSET, ~0UL},
+ {_PAGE_OFFSET(vabits_actual), ~0UL},
{0, 0}
}
}
@@ -366,19 +343,46 @@ void ptdump_check_wx(void)
ptdump_walk_pgd(&st.ptdump, &init_mm, NULL);
- if (st.wx_pages || st.uxn_pages)
+ if (st.wx_pages || st.uxn_pages) {
pr_warn("Checked W+X mappings: FAILED, %lu W+X pages found, %lu non-UXN pages found\n",
st.wx_pages, st.uxn_pages);
- else
+
+ return false;
+ } else {
pr_info("Checked W+X mappings: passed, no W+X pages found\n");
+
+ return true;
+ }
}
static int __init ptdump_init(void)
{
- address_markers[PAGE_END_NR].start_address = PAGE_END;
+ u64 page_offset = _PAGE_OFFSET(vabits_actual);
+ u64 vmemmap_start = (u64)virt_to_page((void *)page_offset);
+ struct addr_marker m[] = {
+ { PAGE_OFFSET, "Linear Mapping start" },
+ { PAGE_END, "Linear Mapping end" },
#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
- address_markers[KASAN_START_NR].start_address = KASAN_SHADOW_START;
+ { KASAN_SHADOW_START, "Kasan shadow start" },
+ { KASAN_SHADOW_END, "Kasan shadow end" },
#endif
+ { MODULES_VADDR, "Modules start" },
+ { MODULES_END, "Modules end" },
+ { VMALLOC_START, "vmalloc() area" },
+ { VMALLOC_END, "vmalloc() end" },
+ { vmemmap_start, "vmemmap start" },
+ { VMEMMAP_END, "vmemmap end" },
+ { PCI_IO_START, "PCI I/O start" },
+ { PCI_IO_END, "PCI I/O end" },
+ { FIXADDR_TOT_START, "Fixmap start" },
+ { FIXADDR_TOP, "Fixmap end" },
+ { -1, NULL },
+ };
+ static struct addr_marker address_markers[ARRAY_SIZE(m)] __ro_after_init;
+
+ kernel_ptdump_info.markers = memcpy(address_markers, m, sizeof(m));
+ kernel_ptdump_info.base_addr = page_offset;
+
ptdump_initialize();
ptdump_debugfs_register(&kernel_ptdump_info, "kernel_page_tables");
return 0;
diff --git a/arch/arm64/mm/trans_pgd.c b/arch/arm64/mm/trans_pgd.c
index 7b14df3c6477..5139a28130c0 100644
--- a/arch/arm64/mm/trans_pgd.c
+++ b/arch/arm64/mm/trans_pgd.c
@@ -33,7 +33,7 @@ static void *trans_alloc(struct trans_pgd_info *info)
static void _copy_pte(pte_t *dst_ptep, pte_t *src_ptep, unsigned long addr)
{
- pte_t pte = READ_ONCE(*src_ptep);
+ pte_t pte = __ptep_get(src_ptep);
if (pte_valid(pte)) {
/*
@@ -41,7 +41,7 @@ static void _copy_pte(pte_t *dst_ptep, pte_t *src_ptep, unsigned long addr)
* read only (code, rodata). Clear the RDONLY bit from
* the temporary mappings we use during restore.
*/
- set_pte(dst_ptep, pte_mkwrite_novma(pte));
+ __set_pte(dst_ptep, pte_mkwrite_novma(pte));
} else if ((debug_pagealloc_enabled() ||
is_kfence_address((void *)addr)) && !pte_none(pte)) {
/*
@@ -55,7 +55,7 @@ static void _copy_pte(pte_t *dst_ptep, pte_t *src_ptep, unsigned long addr)
*/
BUG_ON(!pfn_valid(pte_pfn(pte)));
- set_pte(dst_ptep, pte_mkpresent(pte_mkwrite_novma(pte)));
+ __set_pte(dst_ptep, pte_mkpresent(pte_mkwrite_novma(pte)));
}
}
diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
index 8955da5c47cf..122021f9bdfc 100644
--- a/arch/arm64/net/bpf_jit_comp.c
+++ b/arch/arm64/net/bpf_jit_comp.c
@@ -76,6 +76,7 @@ struct jit_ctx {
int *offset;
int exentry_idx;
__le32 *image;
+ __le32 *ro_image;
u32 stack_size;
int fpb_offset;
};
@@ -205,6 +206,14 @@ static void jit_fill_hole(void *area, unsigned int size)
*ptr++ = cpu_to_le32(AARCH64_BREAK_FAULT);
}
+int bpf_arch_text_invalidate(void *dst, size_t len)
+{
+ if (!aarch64_insn_set(dst, AARCH64_BREAK_FAULT, len))
+ return -EINVAL;
+
+ return 0;
+}
+
static inline int epilogue_offset(const struct jit_ctx *ctx)
{
int to = ctx->epilogue_offset;
@@ -285,7 +294,8 @@ static bool is_lsi_offset(int offset, int scale)
/* Tail call offset to jump into */
#define PROLOGUE_OFFSET (BTI_INSNS + 2 + PAC_INSNS + 8)
-static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf)
+static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf,
+ bool is_exception_cb)
{
const struct bpf_prog *prog = ctx->prog;
const bool is_main_prog = !bpf_is_subprog(prog);
@@ -333,19 +343,34 @@ static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf)
emit(A64_MOV(1, A64_R(9), A64_LR), ctx);
emit(A64_NOP, ctx);
- /* Sign lr */
- if (IS_ENABLED(CONFIG_ARM64_PTR_AUTH_KERNEL))
- emit(A64_PACIASP, ctx);
-
- /* Save FP and LR registers to stay align with ARM64 AAPCS */
- emit(A64_PUSH(A64_FP, A64_LR, A64_SP), ctx);
- emit(A64_MOV(1, A64_FP, A64_SP), ctx);
-
- /* Save callee-saved registers */
- emit(A64_PUSH(r6, r7, A64_SP), ctx);
- emit(A64_PUSH(r8, r9, A64_SP), ctx);
- emit(A64_PUSH(fp, tcc, A64_SP), ctx);
- emit(A64_PUSH(fpb, A64_R(28), A64_SP), ctx);
+ if (!is_exception_cb) {
+ /* Sign lr */
+ if (IS_ENABLED(CONFIG_ARM64_PTR_AUTH_KERNEL))
+ emit(A64_PACIASP, ctx);
+ /* Save FP and LR registers to stay align with ARM64 AAPCS */
+ emit(A64_PUSH(A64_FP, A64_LR, A64_SP), ctx);
+ emit(A64_MOV(1, A64_FP, A64_SP), ctx);
+
+ /* Save callee-saved registers */
+ emit(A64_PUSH(r6, r7, A64_SP), ctx);
+ emit(A64_PUSH(r8, r9, A64_SP), ctx);
+ emit(A64_PUSH(fp, tcc, A64_SP), ctx);
+ emit(A64_PUSH(fpb, A64_R(28), A64_SP), ctx);
+ } else {
+ /*
+ * Exception callback receives FP of Main Program as third
+ * parameter
+ */
+ emit(A64_MOV(1, A64_FP, A64_R(2)), ctx);
+ /*
+ * Main Program already pushed the frame record and the
+ * callee-saved registers. The exception callback will not push
+ * anything and re-use the main program's stack.
+ *
+ * 10 registers are on the stack
+ */
+ emit(A64_SUB_I(1, A64_SP, A64_FP, 80), ctx);
+ }
/* Set up BPF prog stack base register */
emit(A64_MOV(1, fp, A64_SP), ctx);
@@ -365,6 +390,20 @@ static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf)
emit_bti(A64_BTI_J, ctx);
}
+ /*
+ * Program acting as exception boundary should save all ARM64
+ * Callee-saved registers as the exception callback needs to recover
+ * all ARM64 Callee-saved registers in its epilogue.
+ */
+ if (prog->aux->exception_boundary) {
+ /*
+ * As we are pushing two more registers, BPF_FP should be moved
+ * 16 bytes
+ */
+ emit(A64_SUB_I(1, fp, fp, 16), ctx);
+ emit(A64_PUSH(A64_R(23), A64_R(24), A64_SP), ctx);
+ }
+
emit(A64_SUB_I(1, fpb, fp, ctx->fpb_offset), ctx);
/* Stack must be multiples of 16B */
@@ -653,7 +692,7 @@ static void build_plt(struct jit_ctx *ctx)
plt->target = (u64)&dummy_tramp;
}
-static void build_epilogue(struct jit_ctx *ctx)
+static void build_epilogue(struct jit_ctx *ctx, bool is_exception_cb)
{
const u8 r0 = bpf2a64[BPF_REG_0];
const u8 r6 = bpf2a64[BPF_REG_6];
@@ -666,6 +705,15 @@ static void build_epilogue(struct jit_ctx *ctx)
/* We're done with BPF stack */
emit(A64_ADD_I(1, A64_SP, A64_SP, ctx->stack_size), ctx);
+ /*
+ * Program acting as exception boundary pushes R23 and R24 in addition
+ * to BPF callee-saved registers. Exception callback uses the boundary
+ * program's stack frame, so recover these extra registers in the above
+ * two cases.
+ */
+ if (ctx->prog->aux->exception_boundary || is_exception_cb)
+ emit(A64_POP(A64_R(23), A64_R(24), A64_SP), ctx);
+
/* Restore x27 and x28 */
emit(A64_POP(fpb, A64_R(28), A64_SP), ctx);
/* Restore fs (x25) and x26 */
@@ -707,7 +755,8 @@ static int add_exception_handler(const struct bpf_insn *insn,
struct jit_ctx *ctx,
int dst_reg)
{
- off_t offset;
+ off_t ins_offset;
+ off_t fixup_offset;
unsigned long pc;
struct exception_table_entry *ex;
@@ -724,12 +773,17 @@ static int add_exception_handler(const struct bpf_insn *insn,
return -EINVAL;
ex = &ctx->prog->aux->extable[ctx->exentry_idx];
- pc = (unsigned long)&ctx->image[ctx->idx - 1];
+ pc = (unsigned long)&ctx->ro_image[ctx->idx - 1];
- offset = pc - (long)&ex->insn;
- if (WARN_ON_ONCE(offset >= 0 || offset < INT_MIN))
+ /*
+ * This is the relative offset of the instruction that may fault from
+ * the exception table itself. This will be written to the exception
+ * table and if this instruction faults, the destination register will
+ * be set to '0' and the execution will jump to the next instruction.
+ */
+ ins_offset = pc - (long)&ex->insn;
+ if (WARN_ON_ONCE(ins_offset >= 0 || ins_offset < INT_MIN))
return -ERANGE;
- ex->insn = offset;
/*
* Since the extable follows the program, the fixup offset is always
@@ -738,12 +792,25 @@ static int add_exception_handler(const struct bpf_insn *insn,
* bits. We don't need to worry about buildtime or runtime sort
* modifying the upper bits because the table is already sorted, and
* isn't part of the main exception table.
+ *
+ * The fixup_offset is set to the next instruction from the instruction
+ * that may fault. The execution will jump to this after handling the
+ * fault.
*/
- offset = (long)&ex->fixup - (pc + AARCH64_INSN_SIZE);
- if (!FIELD_FIT(BPF_FIXUP_OFFSET_MASK, offset))
+ fixup_offset = (long)&ex->fixup - (pc + AARCH64_INSN_SIZE);
+ if (!FIELD_FIT(BPF_FIXUP_OFFSET_MASK, fixup_offset))
return -ERANGE;
- ex->fixup = FIELD_PREP(BPF_FIXUP_OFFSET_MASK, offset) |
+ /*
+ * The offsets above have been calculated using the RO buffer but we
+ * need to use the R/W buffer for writes.
+ * switch ex to rw buffer for writing.
+ */
+ ex = (void *)ctx->image + ((void *)ex - (void *)ctx->ro_image);
+
+ ex->insn = ins_offset;
+
+ ex->fixup = FIELD_PREP(BPF_FIXUP_OFFSET_MASK, fixup_offset) |
FIELD_PREP(BPF_FIXUP_REG_MASK, dst_reg);
ex->type = EX_TYPE_BPF;
@@ -876,7 +943,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
emit(A64_UXTH(is64, dst, dst), ctx);
break;
case 32:
- emit(A64_REV32(is64, dst, dst), ctx);
+ emit(A64_REV32(0, dst, dst), ctx);
/* upper 32 bits already cleared */
break;
case 64:
@@ -1189,7 +1256,7 @@ emit_cond_jmp:
} else {
emit_a64_mov_i(1, tmp, off, ctx);
if (sign_extend)
- emit(A64_LDRSW(dst, src_adj, off_adj), ctx);
+ emit(A64_LDRSW(dst, src, tmp), ctx);
else
emit(A64_LDR32(dst, src, tmp), ctx);
}
@@ -1511,7 +1578,8 @@ static inline void bpf_flush_icache(void *start, void *end)
struct arm64_jit_data {
struct bpf_binary_header *header;
- u8 *image;
+ u8 *ro_image;
+ struct bpf_binary_header *ro_header;
struct jit_ctx ctx;
};
@@ -1520,12 +1588,14 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
int image_size, prog_size, extable_size, extable_align, extable_offset;
struct bpf_prog *tmp, *orig_prog = prog;
struct bpf_binary_header *header;
+ struct bpf_binary_header *ro_header;
struct arm64_jit_data *jit_data;
bool was_classic = bpf_prog_was_classic(prog);
bool tmp_blinded = false;
bool extra_pass = false;
struct jit_ctx ctx;
u8 *image_ptr;
+ u8 *ro_image_ptr;
if (!prog->jit_requested)
return orig_prog;
@@ -1552,8 +1622,11 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
}
if (jit_data->ctx.offset) {
ctx = jit_data->ctx;
- image_ptr = jit_data->image;
+ ro_image_ptr = jit_data->ro_image;
+ ro_header = jit_data->ro_header;
header = jit_data->header;
+ image_ptr = (void *)header + ((void *)ro_image_ptr
+ - (void *)ro_header);
extra_pass = true;
prog_size = sizeof(u32) * ctx.idx;
goto skip_init_ctx;
@@ -1575,7 +1648,7 @@ 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)) {
+ if (build_prologue(&ctx, was_classic, prog->aux->exception_cb)) {
prog = orig_prog;
goto out_off;
}
@@ -1586,7 +1659,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
}
ctx.epilogue_offset = ctx.idx;
- build_epilogue(&ctx);
+ build_epilogue(&ctx, prog->aux->exception_cb);
build_plt(&ctx);
extable_align = __alignof__(struct exception_table_entry);
@@ -1598,63 +1671,81 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
/* also allocate space for plt target */
extable_offset = round_up(prog_size + PLT_TARGET_SIZE, extable_align);
image_size = extable_offset + extable_size;
- header = bpf_jit_binary_alloc(image_size, &image_ptr,
- sizeof(u32), jit_fill_hole);
- if (header == NULL) {
+ ro_header = bpf_jit_binary_pack_alloc(image_size, &ro_image_ptr,
+ sizeof(u32), &header, &image_ptr,
+ jit_fill_hole);
+ if (!ro_header) {
prog = orig_prog;
goto out_off;
}
/* 2. Now, the actual pass. */
+ /*
+ * Use the image(RW) for writing the JITed instructions. But also save
+ * the ro_image(RX) for calculating the offsets in the image. The RW
+ * image will be later copied to the RX image from where the program
+ * will run. The bpf_jit_binary_pack_finalize() will do this copy in the
+ * final step.
+ */
ctx.image = (__le32 *)image_ptr;
+ ctx.ro_image = (__le32 *)ro_image_ptr;
if (extable_size)
- prog->aux->extable = (void *)image_ptr + extable_offset;
+ prog->aux->extable = (void *)ro_image_ptr + extable_offset;
skip_init_ctx:
ctx.idx = 0;
ctx.exentry_idx = 0;
- build_prologue(&ctx, was_classic);
+ build_prologue(&ctx, was_classic, prog->aux->exception_cb);
if (build_body(&ctx, extra_pass)) {
- bpf_jit_binary_free(header);
prog = orig_prog;
- goto out_off;
+ goto out_free_hdr;
}
- build_epilogue(&ctx);
+ build_epilogue(&ctx, prog->aux->exception_cb);
build_plt(&ctx);
/* 3. Extra pass to validate JITed code. */
if (validate_ctx(&ctx)) {
- bpf_jit_binary_free(header);
prog = orig_prog;
- goto out_off;
+ goto out_free_hdr;
}
/* And we're done. */
if (bpf_jit_enable > 1)
bpf_jit_dump(prog->len, prog_size, 2, ctx.image);
- bpf_flush_icache(header, ctx.image + ctx.idx);
-
if (!prog->is_func || extra_pass) {
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_free_hdr;
+ }
+ if (WARN_ON(bpf_jit_binary_pack_finalize(prog, ro_header,
+ header))) {
+ /* ro_header has been freed */
+ ro_header = NULL;
+ prog = orig_prog;
goto out_off;
}
- bpf_jit_binary_lock_ro(header);
+ /*
+ * The instructions have now been copied to the ROX region from
+ * where they will execute. Now the data cache has to be cleaned to
+ * the PoU and the I-cache has to be invalidated for the VAs.
+ */
+ bpf_flush_icache(ro_header, ctx.ro_image + ctx.idx);
} else {
jit_data->ctx = ctx;
- jit_data->image = image_ptr;
+ jit_data->ro_image = ro_image_ptr;
jit_data->header = header;
+ jit_data->ro_header = ro_header;
}
- prog->bpf_func = (void *)ctx.image;
+
+ prog->bpf_func = (void *)ctx.ro_image;
prog->jited = 1;
prog->jited_len = prog_size;
@@ -1675,6 +1766,14 @@ out:
bpf_jit_prog_release_other(prog, prog == orig_prog ?
tmp : orig_prog);
return prog;
+
+out_free_hdr:
+ if (header) {
+ bpf_arch_text_copy(&ro_header->size, &header->size,
+ sizeof(header->size));
+ bpf_jit_binary_pack_free(ro_header, header);
+ }
+ goto out_off;
}
bool bpf_jit_supports_kfunc_call(void)
@@ -1682,6 +1781,13 @@ bool bpf_jit_supports_kfunc_call(void)
return true;
}
+void *bpf_arch_text_copy(void *dst, void *src, size_t len)
+{
+ if (!aarch64_insn_copy(dst, src, len))
+ return ERR_PTR(-EINVAL);
+ return dst;
+}
+
u64 bpf_jit_alloc_exec_limit(void)
{
return VMALLOC_END - VMALLOC_START;
@@ -1970,7 +2076,7 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
/* store return value */
emit(A64_STR64I(A64_R(0), A64_SP, retval_off), ctx);
/* reserve a nop for bpf_tramp_image_put */
- im->ip_after_call = ctx->image + ctx->idx;
+ im->ip_after_call = ctx->ro_image + ctx->idx;
emit(A64_NOP, ctx);
}
@@ -1985,7 +2091,7 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
run_ctx_off, false);
if (flags & BPF_TRAMP_F_CALL_ORIG) {
- im->ip_epilogue = ctx->image + ctx->idx;
+ im->ip_epilogue = ctx->ro_image + ctx->idx;
emit_addr_mov_i64(A64_R(0), (const u64)im, ctx);
emit_call((const u64)__bpf_tramp_exit, ctx);
}
@@ -2018,9 +2124,6 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
emit(A64_RET(A64_R(10)), ctx);
}
- if (ctx->image)
- bpf_flush_icache(ctx->image, ctx->image + ctx->idx);
-
kfree(branches);
return ctx->idx;
@@ -2063,14 +2166,43 @@ int arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags,
return ret < 0 ? ret : ret * AARCH64_INSN_SIZE;
}
-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, jit_fill_hole);
+}
+
+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_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, nregs;
+ void *image, *tmp;
+ u32 size = ro_image_end - ro_image;
+
+ /* image doesn't need to be in module memory range, so we can
+ * use kvmalloc.
+ */
+ image = kvmalloc(size, GFP_KERNEL);
+ if (!image)
+ return -ENOMEM;
+
struct jit_ctx ctx = {
.image = image,
+ .ro_image = ro_image,
.idx = 0,
};
@@ -2079,15 +2211,26 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image,
if (nregs > 8)
return -ENOTSUPP;
- jit_fill_hole(image, (unsigned int)(image_end - image));
+ jit_fill_hole(image, (unsigned int)(ro_image_end - ro_image));
ret = prepare_trampoline(&ctx, im, tlinks, func_addr, nregs, flags);
- if (ret > 0 && validate_code(&ctx) < 0)
+ if (ret > 0 && validate_code(&ctx) < 0) {
ret = -EINVAL;
+ goto out;
+ }
if (ret > 0)
ret *= AARCH64_INSN_SIZE;
+ tmp = bpf_arch_text_copy(ro_image, image, size);
+ if (IS_ERR(tmp)) {
+ ret = PTR_ERR(tmp);
+ goto out;
+ }
+
+ bpf_flush_icache(ro_image, ro_image + size);
+out:
+ kvfree(image);
return ret;
}
@@ -2305,3 +2448,42 @@ out:
return ret;
}
+
+bool bpf_jit_supports_ptr_xchg(void)
+{
+ return true;
+}
+
+bool bpf_jit_supports_exceptions(void)
+{
+ /* We unwind through both kernel frames starting from within bpf_throw
+ * call and BPF frames. Therefore we require FP unwinder to be enabled
+ * to walk kernel frames and reach BPF frames in the stack trace.
+ * ARM64 kernel is aways compiled with CONFIG_FRAME_POINTER=y
+ */
+ return true;
+}
+
+void bpf_jit_free(struct bpf_prog *prog)
+{
+ if (prog->jited) {
+ struct arm64_jit_data *jit_data = prog->aux->jit_data;
+ struct bpf_binary_header *hdr;
+
+ /*
+ * If we fail the final pass of JIT (from jit_subprogs),
+ * the program may not be finalized yet. Call finalize here
+ * before freeing it.
+ */
+ if (jit_data) {
+ bpf_arch_text_copy(&jit_data->ro_header->size, &jit_data->header->size,
+ sizeof(jit_data->header->size));
+ kfree(jit_data);
+ }
+ hdr = bpf_jit_binary_pack_hdr(prog);
+ bpf_jit_binary_pack_free(hdr, NULL);
+ WARN_ON_ONCE(!bpf_prog_kallsyms_verify_off(prog));
+ }
+
+ bpf_prog_unlock_free(prog);
+}
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index b912b1409fc0..62b2838a231a 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -26,6 +26,7 @@ HAS_ECV
HAS_ECV_CNTPOFF
HAS_EPAN
HAS_EVT
+HAS_FPMR
HAS_FGT
HAS_FPSIMD
HAS_GENERIC_AUTH
@@ -35,6 +36,7 @@ HAS_GENERIC_AUTH_IMP_DEF
HAS_GIC_CPUIF_SYSREGS
HAS_GIC_PRIO_MASKING
HAS_GIC_PRIO_RELAXED_SYNC
+HAS_HCR_NV1
HAS_HCX
HAS_LDAPR
HAS_LPA2
@@ -50,6 +52,7 @@ HAS_STAGE2_FWB
HAS_TCR2
HAS_TIDCP1
HAS_TLB_RANGE
+HAS_VA52
HAS_VIRT_HOST_EXTN
HAS_WFXT
HW_DBM
diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 4c9b67934367..a4c1dd4741a4 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -200,6 +200,7 @@ UnsignedEnum 27:24 PerfMon
0b0110 PMUv3p5
0b0111 PMUv3p7
0b1000 PMUv3p8
+ 0b1001 PMUv3p9
0b1111 IMPDEF
EndEnum
Enum 23:20 MProfDbg
@@ -231,6 +232,7 @@ Enum 3:0 CopDbg
0b1000 Debugv8p2
0b1001 Debugv8p4
0b1010 Debugv8p8
+ 0b1011 Debugv8p9
EndEnum
EndSysreg
@@ -1221,6 +1223,7 @@ UnsignedEnum 35:32 PMSVer
0b0010 V1P1
0b0011 V1P2
0b0100 V1P3
+ 0b0101 V1P4
EndEnum
Field 31:28 CTX_CMPs
Res0 27:24
@@ -1247,11 +1250,41 @@ UnsignedEnum 3:0 DebugVer
0b1000 V8P2
0b1001 V8P4
0b1010 V8P8
+ 0b1011 V8P9
EndEnum
EndSysreg
Sysreg ID_AA64DFR1_EL1 3 0 0 5 1
-Res0 63:0
+Field 63:56 ABL_CMPs
+UnsignedEnum 55:52 DPFZS
+ 0b0000 IGNR
+ 0b0001 FRZN
+EndEnum
+UnsignedEnum 51:48 EBEP
+ 0b0000 NI
+ 0b0001 IMP
+EndEnum
+UnsignedEnum 47:44 ITE
+ 0b0000 NI
+ 0b0001 IMP
+EndEnum
+UnsignedEnum 43:40 ABLE
+ 0b0000 NI
+ 0b0001 IMP
+EndEnum
+UnsignedEnum 39:36 PMICNTR
+ 0b0000 NI
+ 0b0001 IMP
+EndEnum
+UnsignedEnum 35:32 SPMU
+ 0b0000 NI
+ 0b0001 IMP
+ 0b0010 IMP_SPMZR
+EndEnum
+Field 31:24 CTX_CMPs
+Field 23:16 WRPs
+Field 15:8 BRPs
+Field 7:0 SYSPMUID
EndSysreg
Sysreg ID_AA64AFR0_EL1 3 0 0 5 4
@@ -1366,6 +1399,7 @@ EndEnum
UnsignedEnum 43:40 SPECRES
0b0000 NI
0b0001 IMP
+ 0b0010 COSP_RCTX
EndEnum
UnsignedEnum 39:36 SB
0b0000 NI
@@ -1492,7 +1526,12 @@ EndEnum
EndSysreg
Sysreg ID_AA64ISAR3_EL1 3 0 0 6 3
-Res0 63:12
+Res0 63:16
+UnsignedEnum 15:12 PACM
+ 0b0000 NI
+ 0b0001 TRIVIAL_IMP
+ 0b0010 FULL_IMP
+EndEnum
UnsignedEnum 11:8 TLBIW
0b0000 NI
0b0001 IMP
@@ -1540,16 +1579,16 @@ Enum 35:32 TGRAN16_2
0b0010 IMP
0b0011 52_BIT
EndEnum
-Enum 31:28 TGRAN4
+SignedEnum 31:28 TGRAN4
0b0000 IMP
0b0001 52_BIT
0b1111 NI
EndEnum
-Enum 27:24 TGRAN64
+SignedEnum 27:24 TGRAN64
0b0000 IMP
0b1111 NI
EndEnum
-Enum 23:20 TGRAN16
+UnsignedEnum 23:20 TGRAN16
0b0000 NI
0b0001 IMP
0b0010 52_BIT
@@ -1697,7 +1736,7 @@ Enum 23:20 CCIDX
0b0000 32
0b0001 64
EndEnum
-Enum 19:16 VARange
+UnsignedEnum 19:16 VARange
0b0000 48
0b0001 52
EndEnum
@@ -1791,6 +1830,43 @@ UnsignedEnum 3:0 TCRX
EndEnum
EndSysreg
+Sysreg ID_AA64MMFR4_EL1 3 0 0 7 4
+Res0 63:40
+UnsignedEnum 39:36 E3DSE
+ 0b0000 NI
+ 0b0001 IMP
+EndEnum
+Res0 35:28
+SignedEnum 27:24 E2H0
+ 0b0000 IMP
+ 0b1110 NI_NV1
+ 0b1111 NI
+EndEnum
+UnsignedEnum 23:20 NV_frac
+ 0b0000 NV_NV2
+ 0b0001 NV2_ONLY
+EndEnum
+UnsignedEnum 19:16 FGWTE3
+ 0b0000 NI
+ 0b0001 IMP
+EndEnum
+UnsignedEnum 15:12 HACDBS
+ 0b0000 NI
+ 0b0001 IMP
+EndEnum
+UnsignedEnum 11:8 ASID2
+ 0b0000 NI
+ 0b0001 IMP
+EndEnum
+SignedEnum 7:4 EIESB
+ 0b0000 NI
+ 0b0001 ToEL3
+ 0b0010 ToELx
+ 0b1111 ANY
+EndEnum
+Res0 3:0
+EndSysreg
+
Sysreg SCTLR_EL1 3 0 1 0 0
Field 63 TIDCP
Field 62 SPINTMASK
diff --git a/arch/csky/Kconfig b/arch/csky/Kconfig
index cf2a6fd7dff8..d3ac36751ad1 100644
--- a/arch/csky/Kconfig
+++ b/arch/csky/Kconfig
@@ -2,6 +2,7 @@
config CSKY
def_bool y
select ARCH_32BIT_OFF_T
+ select ARCH_HAS_CPU_CACHE_ALIASING
select ARCH_HAS_DMA_PREP_COHERENT
select ARCH_HAS_GCOV_PROFILE_ALL
select ARCH_HAS_SYNC_DMA_FOR_CPU
@@ -89,6 +90,7 @@ config CSKY
select HAVE_KPROBES if !CPU_CK610
select HAVE_KPROBES_ON_FTRACE if !CPU_CK610
select HAVE_KRETPROBES if !CPU_CK610
+ select HAVE_PAGE_SIZE_4KB
select HAVE_PERF_EVENTS
select HAVE_PERF_REGS
select HAVE_PERF_USER_STACK_DUMP
diff --git a/arch/csky/include/asm/cachetype.h b/arch/csky/include/asm/cachetype.h
new file mode 100644
index 000000000000..98cbe3af662f
--- /dev/null
+++ b/arch/csky/include/asm/cachetype.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_CSKY_CACHETYPE_H
+#define __ASM_CSKY_CACHETYPE_H
+
+#include <linux/types.h>
+
+#define cpu_dcache_is_aliasing() true
+
+#endif
diff --git a/arch/csky/include/asm/page.h b/arch/csky/include/asm/page.h
index 4a0502e324a6..0ca6c408c07f 100644
--- a/arch/csky/include/asm/page.h
+++ b/arch/csky/include/asm/page.h
@@ -10,7 +10,7 @@
/*
* PAGE_SHIFT determines the page size: 4KB
*/
-#define PAGE_SHIFT 12
+#define PAGE_SHIFT CONFIG_PAGE_SHIFT
#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE - 1))
#define THREAD_SIZE (PAGE_SIZE * 2)
@@ -82,11 +82,6 @@ static inline unsigned long virt_to_pfn(const void *kaddr)
return __pa(kaddr) >> PAGE_SHIFT;
}
-static inline void * pfn_to_virt(unsigned long pfn)
-{
- return (void *)((unsigned long)__va(pfn) << PAGE_SHIFT);
-}
-
#define MAP_NR(x) PFN_DOWN((unsigned long)(x) - PAGE_OFFSET - \
PHYS_OFFSET_OFFSET)
#define virt_to_page(x) (mem_map + MAP_NR(x))
diff --git a/arch/csky/include/asm/vdso.h b/arch/csky/include/asm/vdso.h
index bdce581b5fcb..181a15edafe8 100644
--- a/arch/csky/include/asm/vdso.h
+++ b/arch/csky/include/asm/vdso.h
@@ -5,11 +5,6 @@
#include <linux/types.h>
-#ifndef GENERIC_TIME_VSYSCALL
-struct vdso_data {
-};
-#endif
-
/*
* The VDSO symbols are mapped into Linux so we can just use regular symbol
* addressing to get their offsets in userspace. The symbols are mapped at an
diff --git a/arch/csky/kernel/smp.c b/arch/csky/kernel/smp.c
index 8e42352cbf12..92dbbf3e0205 100644
--- a/arch/csky/kernel/smp.c
+++ b/arch/csky/kernel/smp.c
@@ -152,10 +152,6 @@ void arch_irq_work_raise(void)
}
#endif
-void __init smp_prepare_boot_cpu(void)
-{
-}
-
void __init smp_prepare_cpus(unsigned int max_cpus)
{
}
diff --git a/arch/csky/kernel/vdso.c b/arch/csky/kernel/vdso.c
index 16c20d64d165..2ca886e4a458 100644
--- a/arch/csky/kernel/vdso.c
+++ b/arch/csky/kernel/vdso.c
@@ -8,25 +8,15 @@
#include <linux/slab.h>
#include <asm/page.h>
-#ifdef GENERIC_TIME_VSYSCALL
#include <vdso/datapage.h>
-#else
-#include <asm/vdso.h>
-#endif
extern char vdso_start[], vdso_end[];
static unsigned int vdso_pages;
static struct page **vdso_pagelist;
-/*
- * The vDSO data page.
- */
-static union {
- struct vdso_data data;
- u8 page[PAGE_SIZE];
-} vdso_data_store __page_aligned_data;
-struct vdso_data *vdso_data = &vdso_data_store.data;
+static union vdso_data_store vdso_data_store __page_aligned_data;
+struct vdso_data *vdso_data = vdso_data_store.data;
static int __init vdso_init(void)
{
diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig
index a880ee067d2e..e233b5efa276 100644
--- a/arch/hexagon/Kconfig
+++ b/arch/hexagon/Kconfig
@@ -7,7 +7,13 @@ config HEXAGON
select ARCH_32BIT_OFF_T
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
select ARCH_NO_PREEMPT
+ select ARCH_WANT_FRAME_POINTERS
select DMA_GLOBAL_POOL
+ select HAVE_PAGE_SIZE_4KB
+ select HAVE_PAGE_SIZE_16KB
+ select HAVE_PAGE_SIZE_64KB
+ select HAVE_PAGE_SIZE_256KB
+ select FRAME_POINTER
# Other pending projects/to-do items.
# select HAVE_REGS_AND_STACK_ACCESS_API
# select HAVE_HW_BREAKPOINT if PERF_EVENTS
@@ -19,6 +25,7 @@ config HEXAGON
select HAVE_PERF_EVENTS
# GENERIC_ALLOCATOR is used by dma_alloc_coherent()
select GENERIC_ALLOCATOR
+ select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW
select HAVE_ARCH_KGDB
select HAVE_ARCH_TRACEHOOK
@@ -43,9 +50,6 @@ config HEXAGON_PHYS_OFFSET
help
Platforms that don't load the kernel at zero set this.
-config FRAME_POINTER
- def_bool y
-
config LOCKDEP_SUPPORT
def_bool y
@@ -58,12 +62,6 @@ config MMU
config GENERIC_CSUM
def_bool y
-#
-# Use the generic interrupt handling code in kernel/irq/:
-#
-config GENERIC_IRQ_PROBE
- def_bool y
-
config GENERIC_HWEIGHT
def_bool y
@@ -120,26 +118,6 @@ config NR_CPUS
This is purely to save memory - each supported CPU adds
approximately eight kilobytes to the kernel image.
-choice
- prompt "Kernel page size"
- default PAGE_SIZE_4KB
- help
- Changes the default page size; use with caution.
-
-config PAGE_SIZE_4KB
- bool "4KB"
-
-config PAGE_SIZE_16KB
- bool "16KB"
-
-config PAGE_SIZE_64KB
- bool "64KB"
-
-config PAGE_SIZE_256KB
- bool "256KB"
-
-endchoice
-
source "kernel/Kconfig.hz"
endmenu
diff --git a/arch/hexagon/include/asm/page.h b/arch/hexagon/include/asm/page.h
index 10f1bc07423c..8a6af57274c2 100644
--- a/arch/hexagon/include/asm/page.h
+++ b/arch/hexagon/include/asm/page.h
@@ -13,27 +13,22 @@
/* This is probably not the most graceful way to handle this. */
#ifdef CONFIG_PAGE_SIZE_4KB
-#define PAGE_SHIFT 12
#define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_4KB
#endif
#ifdef CONFIG_PAGE_SIZE_16KB
-#define PAGE_SHIFT 14
#define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_16KB
#endif
#ifdef CONFIG_PAGE_SIZE_64KB
-#define PAGE_SHIFT 16
#define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_64KB
#endif
#ifdef CONFIG_PAGE_SIZE_256KB
-#define PAGE_SHIFT 18
#define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_256KB
#endif
#ifdef CONFIG_PAGE_SIZE_1MB
-#define PAGE_SHIFT 20
#define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_1MB
#endif
@@ -50,6 +45,7 @@
#define HVM_HUGEPAGE_SIZE 0x5
#endif
+#define PAGE_SHIFT CONFIG_PAGE_SHIFT
#define PAGE_SIZE (1UL << PAGE_SHIFT)
#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1))
@@ -133,12 +129,6 @@ static inline unsigned long virt_to_pfn(const void *kaddr)
return __pa(kaddr) >> PAGE_SHIFT;
}
-static inline void *pfn_to_virt(unsigned long pfn)
-{
- return (void *)((unsigned long)__va(pfn) << PAGE_SHIFT);
-}
-
-
#define page_to_virt(page) __va(page_to_phys(page))
#include <asm/mem-layout.h>
diff --git a/arch/hexagon/kernel/smp.c b/arch/hexagon/kernel/smp.c
index 608884bc3396..65e1fdf9fdb2 100644
--- a/arch/hexagon/kernel/smp.c
+++ b/arch/hexagon/kernel/smp.c
@@ -114,10 +114,6 @@ void send_ipi(const struct cpumask *cpumask, enum ipi_message_type msg)
local_irq_restore(flags);
}
-void __init smp_prepare_boot_cpu(void)
-{
-}
-
/*
* interrupts should already be disabled from the VM
* SP should already be correct; need to set THREADINFO_REG
diff --git a/arch/hexagon/kernel/vmlinux.lds.S b/arch/hexagon/kernel/vmlinux.lds.S
index 1140051a0c45..1150b77fa281 100644
--- a/arch/hexagon/kernel/vmlinux.lds.S
+++ b/arch/hexagon/kernel/vmlinux.lds.S
@@ -63,6 +63,7 @@ SECTIONS
STABS_DEBUG
DWARF_DEBUG
ELF_DETAILS
+ .hexagon.attributes 0 : { *(.hexagon.attributes) }
DISCARDS
}
diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
index 929f68926b34..a5f300ec6f28 100644
--- a/arch/loongarch/Kconfig
+++ b/arch/loongarch/Kconfig
@@ -15,6 +15,7 @@ config LOONGARCH
select ARCH_ENABLE_THP_MIGRATION if TRANSPARENT_HUGEPAGE
select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI
select ARCH_HAS_CPU_FINALIZE_INIT
+ select ARCH_HAS_CURRENT_STACK_POINTER
select ARCH_HAS_FORTIFY_SOURCE
select ARCH_HAS_KCOV
select ARCH_HAS_NMI_SAFE_THIS_CPU_OPS
@@ -104,6 +105,7 @@ config LOONGARCH
select HAVE_ARCH_SECCOMP_FILTER
select HAVE_ARCH_TRACEHOOK
select HAVE_ARCH_TRANSPARENT_HUGEPAGE
+ select HAVE_ARCH_USERFAULTFD_MINOR if USERFAULTFD
select HAVE_ASM_MODVERSIONS
select HAVE_CONTEXT_TRACKING_USER
select HAVE_C_RECORDMCOUNT
@@ -133,21 +135,24 @@ config LOONGARCH
select HAVE_KPROBES
select HAVE_KPROBES_ON_FTRACE
select HAVE_KRETPROBES
- select HAVE_KVM
+ select HAVE_LIVEPATCH
select HAVE_MOD_ARCH_SPECIFIC
select HAVE_NMI
+ select HAVE_OBJTOOL if AS_HAS_EXPLICIT_RELOCS
select HAVE_PCI
select HAVE_PERF_EVENTS
select HAVE_PERF_REGS
select HAVE_PERF_USER_STACK_DUMP
select HAVE_PREEMPT_DYNAMIC_KEY
select HAVE_REGS_AND_STACK_ACCESS_API
+ select HAVE_RELIABLE_STACKTRACE if UNWINDER_ORC
select HAVE_RETHOOK
select HAVE_RSEQ
select HAVE_RUST
select HAVE_SAMPLE_FTRACE_DIRECT
select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
select HAVE_SETUP_PER_CPU_AREA if NUMA
+ select HAVE_STACK_VALIDATION if HAVE_OBJTOOL
select HAVE_STACKPROTECTOR
select HAVE_SYSCALL_TRACEPOINTS
select HAVE_TIF_NOHZ
@@ -227,15 +232,6 @@ config MACH_LOONGSON64
config FIX_EARLYCON_MEM
def_bool y
-config PAGE_SIZE_4KB
- bool
-
-config PAGE_SIZE_16KB
- bool
-
-config PAGE_SIZE_64KB
- bool
-
config PGTABLE_2LEVEL
bool
@@ -288,7 +284,7 @@ choice
config 4KB_3LEVEL
bool "4KB with 3 levels"
- select PAGE_SIZE_4KB
+ select HAVE_PAGE_SIZE_4KB
select PGTABLE_3LEVEL
help
This option selects 4KB page size with 3 level page tables, which
@@ -296,7 +292,7 @@ config 4KB_3LEVEL
config 4KB_4LEVEL
bool "4KB with 4 levels"
- select PAGE_SIZE_4KB
+ select HAVE_PAGE_SIZE_4KB
select PGTABLE_4LEVEL
help
This option selects 4KB page size with 4 level page tables, which
@@ -304,7 +300,7 @@ config 4KB_4LEVEL
config 16KB_2LEVEL
bool "16KB with 2 levels"
- select PAGE_SIZE_16KB
+ select HAVE_PAGE_SIZE_16KB
select PGTABLE_2LEVEL
help
This option selects 16KB page size with 2 level page tables, which
@@ -312,7 +308,7 @@ config 16KB_2LEVEL
config 16KB_3LEVEL
bool "16KB with 3 levels"
- select PAGE_SIZE_16KB
+ select HAVE_PAGE_SIZE_16KB
select PGTABLE_3LEVEL
help
This option selects 16KB page size with 3 level page tables, which
@@ -320,7 +316,7 @@ config 16KB_3LEVEL
config 64KB_2LEVEL
bool "64KB with 2 levels"
- select PAGE_SIZE_64KB
+ select HAVE_PAGE_SIZE_64KB
select PGTABLE_2LEVEL
help
This option selects 64KB page size with 2 level page tables, which
@@ -328,7 +324,7 @@ config 64KB_2LEVEL
config 64KB_3LEVEL
bool "64KB with 3 levels"
- select PAGE_SIZE_64KB
+ select HAVE_PAGE_SIZE_64KB
select PGTABLE_3LEVEL
help
This option selects 64KB page size with 3 level page tables, which
@@ -634,6 +630,8 @@ config RANDOMIZE_BASE_MAX_OFFSET
This is limited by the size of the lower address memory, 256MB.
+source "kernel/livepatch/Kconfig"
+
endmenu
config ARCH_SELECT_MEMORY_MODEL
diff --git a/arch/loongarch/Kconfig.debug b/arch/loongarch/Kconfig.debug
index 8d36aab53008..98d60630c3d4 100644
--- a/arch/loongarch/Kconfig.debug
+++ b/arch/loongarch/Kconfig.debug
@@ -26,4 +26,15 @@ config UNWINDER_PROLOGUE
Some of the addresses it reports may be incorrect (but better than the
Guess unwinder).
+config UNWINDER_ORC
+ bool "ORC unwinder"
+ select OBJTOOL
+ help
+ This option enables the ORC (Oops Rewind Capability) unwinder for
+ unwinding kernel stack traces. It uses a custom data format which is
+ a simplified version of the DWARF Call Frame Information standard.
+
+ Enabling this option will increase the kernel's runtime memory usage
+ by roughly 2-4MB, depending on your kernel config.
+
endchoice
diff --git a/arch/loongarch/Makefile b/arch/loongarch/Makefile
index 983aa2b1629a..df6caf79537a 100644
--- a/arch/loongarch/Makefile
+++ b/arch/loongarch/Makefile
@@ -26,6 +26,18 @@ endif
32bit-emul = elf32loongarch
64bit-emul = elf64loongarch
+ifdef CONFIG_UNWINDER_ORC
+orc_hash_h := arch/$(SRCARCH)/include/generated/asm/orc_hash.h
+orc_hash_sh := $(srctree)/scripts/orc_hash.sh
+targets += $(orc_hash_h)
+quiet_cmd_orc_hash = GEN $@
+ cmd_orc_hash = mkdir -p $(dir $@); \
+ $(CONFIG_SHELL) $(orc_hash_sh) < $< > $@
+$(orc_hash_h): $(srctree)/arch/loongarch/include/asm/orc_types.h $(orc_hash_sh) FORCE
+ $(call if_changed,orc_hash)
+archprepare: $(orc_hash_h)
+endif
+
ifdef CONFIG_DYNAMIC_FTRACE
KBUILD_CPPFLAGS += -DCC_USING_PATCHABLE_FUNCTION_ENTRY
CC_FLAGS_FTRACE := -fpatchable-function-entry=2
@@ -72,8 +84,6 @@ KBUILD_CFLAGS_KERNEL += $(call cc-option,-mdirect-extern-access)
KBUILD_CFLAGS_KERNEL += $(call cc-option,-fdirect-access-external-data)
KBUILD_AFLAGS_MODULE += $(call cc-option,-fno-direct-access-external-data)
KBUILD_CFLAGS_MODULE += $(call cc-option,-fno-direct-access-external-data)
-KBUILD_AFLAGS_MODULE += $(call cc-option,-mno-relax) $(call cc-option,-Wa$(comma)-mno-relax)
-KBUILD_CFLAGS_MODULE += $(call cc-option,-mno-relax) $(call cc-option,-Wa$(comma)-mno-relax)
else
cflags-y += $(call cc-option,-mno-explicit-relocs)
KBUILD_AFLAGS_KERNEL += -Wa,-mla-global-with-pcrel
@@ -82,6 +92,16 @@ KBUILD_AFLAGS_MODULE += -Wa,-mla-global-with-abs
KBUILD_CFLAGS_MODULE += -fplt -Wa,-mla-global-with-abs,-mla-local-with-abs
endif
+KBUILD_AFLAGS += $(call cc-option,-mno-relax) $(call cc-option,-Wa$(comma)-mno-relax)
+KBUILD_CFLAGS += $(call cc-option,-mno-relax) $(call cc-option,-Wa$(comma)-mno-relax)
+KBUILD_AFLAGS += $(call cc-option,-mthin-add-sub) $(call cc-option,-Wa$(comma)-mthin-add-sub)
+KBUILD_CFLAGS += $(call cc-option,-mthin-add-sub) $(call cc-option,-Wa$(comma)-mthin-add-sub)
+
+ifdef CONFIG_OBJTOOL
+KBUILD_CFLAGS += -fno-jump-tables
+endif
+
+KBUILD_RUSTFLAGS += --target=$(objtree)/scripts/target.json
KBUILD_RUSTFLAGS_MODULE += -Crelocation-model=pic
ifeq ($(CONFIG_RELOCATABLE),y)
diff --git a/arch/loongarch/boot/dts/loongson-2k1000.dtsi b/arch/loongarch/boot/dts/loongson-2k1000.dtsi
index 49a70f8c3cab..b6aeb1f70e2a 100644
--- a/arch/loongarch/boot/dts/loongson-2k1000.dtsi
+++ b/arch/loongarch/boot/dts/loongson-2k1000.dtsi
@@ -100,6 +100,13 @@
#size-cells = <2>;
dma-coherent;
+ isa@18000000 {
+ compatible = "isa";
+ #size-cells = <1>;
+ #address-cells = <2>;
+ ranges = <1 0x0 0x0 0x18000000 0x4000>;
+ };
+
liointc0: interrupt-controller@1fe01400 {
compatible = "loongson,liointc-2.0";
reg = <0x0 0x1fe01400 0x0 0x40>,
diff --git a/arch/loongarch/boot/dts/loongson-2k2000-ref.dts b/arch/loongarch/boot/dts/loongson-2k2000-ref.dts
index dca91caf895e..74b99bd234cc 100644
--- a/arch/loongarch/boot/dts/loongson-2k2000-ref.dts
+++ b/arch/loongarch/boot/dts/loongson-2k2000-ref.dts
@@ -61,12 +61,45 @@
&gmac0 {
status = "okay";
+
+ phy-mode = "gmii";
+ phy-handle = <&phy0>;
+ mdio {
+ compatible = "snps,dwmac-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ phy0: ethernet-phy@0 {
+ reg = <2>;
+ };
+ };
};
&gmac1 {
status = "okay";
+
+ phy-mode = "gmii";
+ phy-handle = <&phy1>;
+ mdio {
+ compatible = "snps,dwmac-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ phy1: ethernet-phy@1 {
+ reg = <2>;
+ };
+ };
};
&gmac2 {
status = "okay";
+
+ phy-mode = "rgmii";
+ phy-handle = <&phy2>;
+ mdio {
+ compatible = "snps,dwmac-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ phy2: ethernet-phy@2 {
+ reg = <0>;
+ };
+ };
};
diff --git a/arch/loongarch/boot/dts/loongson-2k2000.dtsi b/arch/loongarch/boot/dts/loongson-2k2000.dtsi
index a231949b5f55..9eab2d02cbe8 100644
--- a/arch/loongarch/boot/dts/loongson-2k2000.dtsi
+++ b/arch/loongarch/boot/dts/loongson-2k2000.dtsi
@@ -51,6 +51,13 @@
#address-cells = <2>;
#size-cells = <2>;
+ isa@18400000 {
+ compatible = "isa";
+ #size-cells = <1>;
+ #address-cells = <2>;
+ ranges = <1 0x0 0x0 0x18400000 0x4000>;
+ };
+
pmc: power-management@100d0000 {
compatible = "loongson,ls2k2000-pmc", "loongson,ls2k0500-pmc", "syscon";
reg = <0x0 0x100d0000 0x0 0x58>;
@@ -109,6 +116,8 @@
msi: msi-controller@1fe01140 {
compatible = "loongson,pch-msi-1.0";
reg = <0x0 0x1fe01140 0x0 0x8>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
msi-controller;
loongson,msi-base-vec = <64>;
loongson,msi-num-vecs = <192>;
@@ -140,27 +149,34 @@
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";
+ msi-parent = <&msi>;
bus-range = <0x0 0xff>;
- ranges = <0x01000000 0x0 0x00008000 0x0 0x18400000 0x0 0x00008000>,
+ ranges = <0x01000000 0x0 0x00008000 0x0 0x18408000 0x0 0x00008000>,
<0x02000000 0x0 0x60000000 0x0 0x60000000 0x0 0x20000000>;
gmac0: ethernet@3,0 {
reg = <0x1800 0x0 0x0 0x0 0x0>;
- interrupts = <12 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <12 IRQ_TYPE_LEVEL_HIGH>,
+ <13 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "macirq", "eth_lpi";
interrupt-parent = <&pic>;
status = "disabled";
};
gmac1: ethernet@3,1 {
reg = <0x1900 0x0 0x0 0x0 0x0>;
- interrupts = <14 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <14 IRQ_TYPE_LEVEL_HIGH>,
+ <15 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "macirq", "eth_lpi";
interrupt-parent = <&pic>;
status = "disabled";
};
gmac2: ethernet@3,2 {
reg = <0x1a00 0x0 0x0 0x0 0x0>;
- interrupts = <17 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <17 IRQ_TYPE_LEVEL_HIGH>,
+ <18 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "macirq", "eth_lpi";
interrupt-parent = <&pic>;
status = "disabled";
};
diff --git a/arch/loongarch/crypto/crc32-loongarch.c b/arch/loongarch/crypto/crc32-loongarch.c
index a49e507af38c..3eebea3a7b47 100644
--- a/arch/loongarch/crypto/crc32-loongarch.c
+++ b/arch/loongarch/crypto/crc32-loongarch.c
@@ -44,7 +44,6 @@ static u32 crc32_loongarch_hw(u32 crc_, const u8 *p, unsigned int len)
CRC32(crc, value, w);
p += sizeof(u32);
- len -= sizeof(u32);
}
if (len & sizeof(u16)) {
@@ -80,7 +79,6 @@ static u32 crc32c_loongarch_hw(u32 crc_, const u8 *p, unsigned int len)
CRC32C(crc, value, w);
p += sizeof(u32);
- len -= sizeof(u32);
}
if (len & sizeof(u16)) {
diff --git a/arch/loongarch/include/asm/Kbuild b/arch/loongarch/include/asm/Kbuild
index 93783fa24f6e..2dbec7853ae8 100644
--- a/arch/loongarch/include/asm/Kbuild
+++ b/arch/loongarch/include/asm/Kbuild
@@ -1,9 +1,12 @@
# SPDX-License-Identifier: GPL-2.0
+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
diff --git a/arch/loongarch/include/asm/addrspace.h b/arch/loongarch/include/asm/addrspace.h
index b24437e28c6e..7bd47d65bf7a 100644
--- a/arch/loongarch/include/asm/addrspace.h
+++ b/arch/loongarch/include/asm/addrspace.h
@@ -11,6 +11,7 @@
#define _ASM_ADDRSPACE_H
#include <linux/const.h>
+#include <linux/sizes.h>
#include <asm/loongarch.h>
diff --git a/arch/loongarch/include/asm/bug.h b/arch/loongarch/include/asm/bug.h
index d4ca3ba25418..08388876ade4 100644
--- a/arch/loongarch/include/asm/bug.h
+++ b/arch/loongarch/include/asm/bug.h
@@ -44,6 +44,7 @@
do { \
instrumentation_begin(); \
__BUG_FLAGS(BUGFLAG_WARNING|(flags)); \
+ annotate_reachable(); \
instrumentation_end(); \
} while (0)
diff --git a/arch/loongarch/include/asm/cacheflush.h b/arch/loongarch/include/asm/cacheflush.h
index 80bd74106985..f8754d08a31a 100644
--- a/arch/loongarch/include/asm/cacheflush.h
+++ b/arch/loongarch/include/asm/cacheflush.h
@@ -37,8 +37,6 @@ void local_flush_icache_range(unsigned long start, unsigned long end);
#define flush_icache_range local_flush_icache_range
#define flush_icache_user_range local_flush_icache_range
-#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
-
#define flush_cache_all() do { } while (0)
#define flush_cache_mm(mm) do { } while (0)
#define flush_cache_dup_mm(mm) do { } while (0)
@@ -47,7 +45,6 @@ void local_flush_icache_range(unsigned long start, unsigned long end);
#define flush_cache_vmap(start, end) do { } while (0)
#define flush_cache_vunmap(start, end) do { } while (0)
#define flush_icache_user_page(vma, page, addr, len) do { } while (0)
-#define flush_dcache_page(page) do { } while (0)
#define flush_dcache_mmap_lock(mapping) do { } while (0)
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
diff --git a/arch/loongarch/include/asm/exception.h b/arch/loongarch/include/asm/exception.h
index af74a3fdcad1..c6d20736fd92 100644
--- a/arch/loongarch/include/asm/exception.h
+++ b/arch/loongarch/include/asm/exception.h
@@ -6,6 +6,8 @@
#include <asm/ptrace.h>
#include <linux/kprobes.h>
+extern void *exception_table[];
+
void show_registers(struct pt_regs *regs);
asmlinkage void cache_parity_error(void);
diff --git a/arch/loongarch/include/asm/io.h b/arch/loongarch/include/asm/io.h
index c486c2341b66..c2f9979b2979 100644
--- a/arch/loongarch/include/asm/io.h
+++ b/arch/loongarch/include/asm/io.h
@@ -14,11 +14,6 @@
#include <asm/pgtable-bits.h>
#include <asm/string.h>
-/*
- * Change "struct page" to physical address.
- */
-#define page_to_phys(page) ((phys_addr_t)page_to_pfn(page) << PAGE_SHIFT)
-
extern void __init __iomem *early_ioremap(u64 phys_addr, unsigned long size);
extern void __init early_iounmap(void __iomem *addr, unsigned long size);
@@ -71,6 +66,23 @@ extern void __memcpy_fromio(void *to, const volatile void __iomem *from, size_t
#define memcpy_fromio(a, c, l) __memcpy_fromio((a), (c), (l))
#define memcpy_toio(c, a, l) __memcpy_toio((c), (a), (l))
+#define __io_aw() mmiowb()
+
+#ifdef CONFIG_KFENCE
+#define virt_to_phys(kaddr) \
+({ \
+ (likely((unsigned long)kaddr < vm_map_base)) ? __pa((unsigned long)kaddr) : \
+ page_to_phys(tlb_virt_to_page((unsigned long)kaddr)) + offset_in_page((unsigned long)kaddr);\
+})
+
+#define phys_to_virt(paddr) \
+({ \
+ extern char *__kfence_pool; \
+ (unlikely(__kfence_pool == NULL)) ? __va((unsigned long)paddr) : \
+ page_address(phys_to_page((unsigned long)paddr)) + offset_in_page((unsigned long)paddr);\
+})
+#endif
+
#include <asm-generic/io.h>
#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
diff --git a/arch/loongarch/include/asm/kfence.h b/arch/loongarch/include/asm/kfence.h
index 6c82aea1c993..a6a5760da3a3 100644
--- a/arch/loongarch/include/asm/kfence.h
+++ b/arch/loongarch/include/asm/kfence.h
@@ -16,6 +16,7 @@
static inline bool arch_kfence_init_pool(void)
{
int err;
+ char *kaddr, *vaddr;
char *kfence_pool = __kfence_pool;
struct vm_struct *area;
@@ -35,6 +36,14 @@ static inline bool arch_kfence_init_pool(void)
return false;
}
+ kaddr = kfence_pool;
+ vaddr = __kfence_pool;
+ while (kaddr < kfence_pool + KFENCE_POOL_SIZE) {
+ set_page_address(virt_to_page(kaddr), vaddr);
+ kaddr += PAGE_SIZE;
+ vaddr += PAGE_SIZE;
+ }
+
return true;
}
diff --git a/arch/loongarch/include/asm/module.h b/arch/loongarch/include/asm/module.h
index 2ecd82bb64e1..f33f3fd32ecc 100644
--- a/arch/loongarch/include/asm/module.h
+++ b/arch/loongarch/include/asm/module.h
@@ -6,6 +6,7 @@
#define _ASM_MODULE_H
#include <asm/inst.h>
+#include <asm/orc_types.h>
#include <asm-generic/module.h>
#define RELA_STACK_DEPTH 16
@@ -21,6 +22,12 @@ struct mod_arch_specific {
struct mod_section plt;
struct mod_section plt_idx;
+#ifdef CONFIG_UNWINDER_ORC
+ unsigned int num_orcs;
+ int *orc_unwind_ip;
+ struct orc_entry *orc_unwind;
+#endif
+
/* For CONFIG_DYNAMIC_FTRACE */
struct plt_entry *ftrace_trampolines;
};
diff --git a/arch/loongarch/include/asm/orc_header.h b/arch/loongarch/include/asm/orc_header.h
new file mode 100644
index 000000000000..f9d509c3fd70
--- /dev/null
+++ b/arch/loongarch/include/asm/orc_header.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef _ORC_HEADER_H
+#define _ORC_HEADER_H
+
+#include <linux/types.h>
+#include <linux/compiler.h>
+#include <asm/orc_hash.h>
+
+/*
+ * The header is currently a 20-byte hash of the ORC entry definition; see
+ * scripts/orc_hash.sh.
+ */
+#define ORC_HEADER \
+ __used __section(".orc_header") __aligned(4) \
+ static const u8 orc_header[] = { ORC_HASH }
+
+#endif /* _ORC_HEADER_H */
diff --git a/arch/loongarch/include/asm/orc_lookup.h b/arch/loongarch/include/asm/orc_lookup.h
new file mode 100644
index 000000000000..b02e6357def4
--- /dev/null
+++ b/arch/loongarch/include/asm/orc_lookup.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef _ORC_LOOKUP_H
+#define _ORC_LOOKUP_H
+
+/*
+ * This is a lookup table for speeding up access to the .orc_unwind table.
+ * Given an input address offset, the corresponding lookup table entry
+ * specifies a subset of the .orc_unwind table to search.
+ *
+ * Each block represents the end of the previous range and the start of the
+ * next range. An extra block is added to give the last range an end.
+ *
+ * The block size should be a power of 2 to avoid a costly 'div' instruction.
+ *
+ * A block size of 256 was chosen because it roughly doubles unwinder
+ * performance while only adding ~5% to the ORC data footprint.
+ */
+#define LOOKUP_BLOCK_ORDER 8
+#define LOOKUP_BLOCK_SIZE (1 << LOOKUP_BLOCK_ORDER)
+
+#ifndef LINKER_SCRIPT
+
+extern unsigned int orc_lookup[];
+extern unsigned int orc_lookup_end[];
+
+#define LOOKUP_START_IP (unsigned long)_stext
+#define LOOKUP_STOP_IP (unsigned long)_etext
+
+#endif /* LINKER_SCRIPT */
+
+#endif /* _ORC_LOOKUP_H */
diff --git a/arch/loongarch/include/asm/orc_types.h b/arch/loongarch/include/asm/orc_types.h
new file mode 100644
index 000000000000..caf1f71a1057
--- /dev/null
+++ b/arch/loongarch/include/asm/orc_types.h
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef _ORC_TYPES_H
+#define _ORC_TYPES_H
+
+#include <linux/types.h>
+
+/*
+ * The ORC_REG_* registers are base registers which are used to find other
+ * registers on the stack.
+ *
+ * ORC_REG_PREV_SP, also known as DWARF Call Frame Address (CFA), is the
+ * address of the previous frame: the caller's SP before it called the current
+ * function.
+ *
+ * ORC_REG_UNDEFINED means the corresponding register's value didn't change in
+ * the current frame.
+ *
+ * The most commonly used base registers are SP and FP -- which the previous SP
+ * is usually based on -- and PREV_SP and UNDEFINED -- which the previous FP is
+ * usually based on.
+ *
+ * The rest of the base registers are needed for special cases like entry code
+ * and GCC realigned stacks.
+ */
+#define ORC_REG_UNDEFINED 0
+#define ORC_REG_PREV_SP 1
+#define ORC_REG_SP 2
+#define ORC_REG_FP 3
+#define ORC_REG_MAX 4
+
+#define ORC_TYPE_UNDEFINED 0
+#define ORC_TYPE_END_OF_STACK 1
+#define ORC_TYPE_CALL 2
+#define ORC_TYPE_REGS 3
+#define ORC_TYPE_REGS_PARTIAL 4
+
+#ifndef __ASSEMBLY__
+/*
+ * This struct is more or less a vastly simplified version of the DWARF Call
+ * Frame Information standard. It contains only the necessary parts of DWARF
+ * CFI, simplified for ease of access by the in-kernel unwinder. It tells the
+ * unwinder how to find the previous SP and FP (and sometimes entry regs) on
+ * the stack for a given code address. Each instance of the struct corresponds
+ * to one or more code locations.
+ */
+struct orc_entry {
+ s16 sp_offset;
+ s16 fp_offset;
+ s16 ra_offset;
+ unsigned int sp_reg:4;
+ unsigned int fp_reg:4;
+ unsigned int ra_reg:4;
+ unsigned int type:3;
+ unsigned int signal:1;
+};
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ORC_TYPES_H */
diff --git a/arch/loongarch/include/asm/page.h b/arch/loongarch/include/asm/page.h
index 63f137ce82a4..e85df33f11c7 100644
--- a/arch/loongarch/include/asm/page.h
+++ b/arch/loongarch/include/asm/page.h
@@ -11,15 +11,7 @@
/*
* PAGE_SHIFT determines the page size
*/
-#ifdef CONFIG_PAGE_SIZE_4KB
-#define PAGE_SHIFT 12
-#endif
-#ifdef CONFIG_PAGE_SIZE_16KB
-#define PAGE_SHIFT 14
-#endif
-#ifdef CONFIG_PAGE_SIZE_64KB
-#define PAGE_SHIFT 16
-#endif
+#define PAGE_SHIFT CONFIG_PAGE_SHIFT
#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE - 1))
@@ -83,7 +75,29 @@ typedef struct { unsigned long pgprot; } pgprot_t;
#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
#define sym_to_pfn(x) __phys_to_pfn(__pa_symbol(x))
-#define virt_to_pfn(kaddr) PFN_DOWN(PHYSADDR(kaddr))
+struct page *dmw_virt_to_page(unsigned long kaddr);
+struct page *tlb_virt_to_page(unsigned long kaddr);
+
+#define pfn_to_phys(pfn) __pfn_to_phys(pfn)
+#define phys_to_pfn(paddr) __phys_to_pfn(paddr)
+
+#define page_to_phys(page) pfn_to_phys(page_to_pfn(page))
+#define phys_to_page(paddr) pfn_to_page(phys_to_pfn(paddr))
+
+#ifndef CONFIG_KFENCE
+
+#define page_to_virt(page) __va(page_to_phys(page))
+#define virt_to_page(kaddr) phys_to_page(__pa(kaddr))
+
+#else
+
+#define WANT_PAGE_VIRTUAL
+
+#define page_to_virt(page) \
+({ \
+ extern char *__kfence_pool; \
+ (__kfence_pool == NULL) ? __va(page_to_phys(page)) : page_address(page); \
+})
#define virt_to_page(kaddr) \
({ \
@@ -91,6 +105,11 @@ typedef struct { unsigned long pgprot; } pgprot_t;
dmw_virt_to_page((unsigned long)kaddr) : tlb_virt_to_page((unsigned long)kaddr);\
})
+#endif
+
+#define pfn_to_virt(pfn) page_to_virt(pfn_to_page(pfn))
+#define virt_to_pfn(kaddr) page_to_pfn(virt_to_page(kaddr))
+
extern int __virt_addr_valid(volatile void *kaddr);
#define virt_addr_valid(kaddr) __virt_addr_valid((volatile void *)(kaddr))
diff --git a/arch/loongarch/include/asm/percpu.h b/arch/loongarch/include/asm/percpu.h
index 9b36ac003f89..8f290e5546cf 100644
--- a/arch/loongarch/include/asm/percpu.h
+++ b/arch/loongarch/include/asm/percpu.h
@@ -29,7 +29,12 @@ static inline void set_my_cpu_offset(unsigned long off)
__my_cpu_offset = off;
csr_write64(off, PERCPU_BASE_KS);
}
-#define __my_cpu_offset __my_cpu_offset
+
+#define __my_cpu_offset \
+({ \
+ __asm__ __volatile__("":"+r"(__my_cpu_offset)); \
+ __my_cpu_offset; \
+})
#define PERCPU_OP(op, asm_op, c_op) \
static __always_inline unsigned long __percpu_##op(void *ptr, \
diff --git a/arch/loongarch/include/asm/pgtable.h b/arch/loongarch/include/asm/pgtable.h
index 8b5df1bbf9e9..af3acdf3481a 100644
--- a/arch/loongarch/include/asm/pgtable.h
+++ b/arch/loongarch/include/asm/pgtable.h
@@ -363,9 +363,6 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt
extern pgd_t swapper_pg_dir[];
extern pgd_t invalid_pg_dir[];
-struct page *dmw_virt_to_page(unsigned long kaddr);
-struct page *tlb_virt_to_page(unsigned long kaddr);
-
/*
* The following only work if pte_present() is true.
* Undefined behaviour if not..
diff --git a/arch/loongarch/include/asm/qspinlock.h b/arch/loongarch/include/asm/qspinlock.h
deleted file mode 100644
index 34f43f8ad591..000000000000
--- a/arch/loongarch/include/asm/qspinlock.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_QSPINLOCK_H
-#define _ASM_QSPINLOCK_H
-
-#include <asm-generic/qspinlock_types.h>
-
-#define queued_spin_unlock queued_spin_unlock
-
-static inline void queued_spin_unlock(struct qspinlock *lock)
-{
- compiletime_assert_atomic_type(lock->locked);
- c_sync();
- WRITE_ONCE(lock->locked, 0);
-}
-
-#include <asm-generic/qspinlock.h>
-
-#endif /* _ASM_QSPINLOCK_H */
diff --git a/arch/loongarch/include/asm/stackframe.h b/arch/loongarch/include/asm/stackframe.h
index 4fb1e6408b98..45b507a7b06f 100644
--- a/arch/loongarch/include/asm/stackframe.h
+++ b/arch/loongarch/include/asm/stackframe.h
@@ -13,6 +13,7 @@
#include <asm/asm-offsets.h>
#include <asm/loongarch.h>
#include <asm/thread_info.h>
+#include <asm/unwind_hints.h>
/* Make the addition of cfi info a little easier. */
.macro cfi_rel_offset reg offset=0 docfi=0
@@ -162,6 +163,7 @@
li.w t0, CSR_CRMD_WE
csrxchg t0, t0, LOONGARCH_CSR_CRMD
#endif
+ UNWIND_HINT_REGS
.endm
.macro SAVE_ALL docfi=0
@@ -219,6 +221,7 @@
.macro RESTORE_SP_AND_RET docfi=0
cfi_ld sp, PT_R3, \docfi
+ UNWIND_HINT_FUNC
ertn
.endm
diff --git a/arch/loongarch/include/asm/thread_info.h b/arch/loongarch/include/asm/thread_info.h
index 8cb653d49a54..8bf0e6f51546 100644
--- a/arch/loongarch/include/asm/thread_info.h
+++ b/arch/loongarch/include/asm/thread_info.h
@@ -86,6 +86,7 @@ register unsigned long current_stack_pointer __asm__("$sp");
#define TIF_LASX_CTX_LIVE 18 /* LASX context must be preserved */
#define TIF_USEDLBT 19 /* LBT was used by this task this quantum (SMP) */
#define TIF_LBT_CTX_LIVE 20 /* LBT context must be preserved */
+#define TIF_PATCH_PENDING 21 /* pending live patching update */
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
@@ -105,6 +106,7 @@ register unsigned long current_stack_pointer __asm__("$sp");
#define _TIF_LASX_CTX_LIVE (1<<TIF_LASX_CTX_LIVE)
#define _TIF_USEDLBT (1<<TIF_USEDLBT)
#define _TIF_LBT_CTX_LIVE (1<<TIF_LBT_CTX_LIVE)
+#define _TIF_PATCH_PENDING (1<<TIF_PATCH_PENDING)
#endif /* __KERNEL__ */
#endif /* _ASM_THREAD_INFO_H */
diff --git a/arch/loongarch/include/asm/unwind.h b/arch/loongarch/include/asm/unwind.h
index b9dce87afd2e..40a6763c5aec 100644
--- a/arch/loongarch/include/asm/unwind.h
+++ b/arch/loongarch/include/asm/unwind.h
@@ -16,6 +16,7 @@
enum unwinder_type {
UNWINDER_GUESS,
UNWINDER_PROLOGUE,
+ UNWINDER_ORC,
};
struct unwind_state {
@@ -24,7 +25,7 @@ struct unwind_state {
struct task_struct *task;
bool first, error, reset;
int graph_idx;
- unsigned long sp, pc, ra;
+ unsigned long sp, fp, pc, ra;
};
bool default_next_frame(struct unwind_state *state);
@@ -61,14 +62,17 @@ static __always_inline void __unwind_start(struct unwind_state *state,
state->sp = regs->regs[3];
state->pc = regs->csr_era;
state->ra = regs->regs[1];
+ state->fp = regs->regs[22];
} else if (task && task != current) {
state->sp = thread_saved_fp(task);
state->pc = thread_saved_ra(task);
state->ra = 0;
+ state->fp = 0;
} else {
state->sp = (unsigned long)__builtin_frame_address(0);
state->pc = (unsigned long)__builtin_return_address(0);
state->ra = 0;
+ state->fp = 0;
}
state->task = task;
get_stack_info(state->sp, state->task, &state->stack_info);
@@ -77,6 +81,18 @@ static __always_inline void __unwind_start(struct unwind_state *state,
static __always_inline unsigned long __unwind_get_return_address(struct unwind_state *state)
{
- return unwind_done(state) ? 0 : state->pc;
+ if (unwind_done(state))
+ return 0;
+
+ return __kernel_text_address(state->pc) ? state->pc : 0;
}
+
+#ifdef CONFIG_UNWINDER_ORC
+void unwind_init(void);
+void unwind_module_init(struct module *mod, void *orc_ip, size_t orc_ip_size, void *orc, size_t orc_size);
+#else
+static inline void unwind_init(void) {}
+static inline void unwind_module_init(struct module *mod, void *orc_ip, size_t orc_ip_size, void *orc, size_t orc_size) {}
+#endif
+
#endif /* _ASM_UNWIND_H */
diff --git a/arch/loongarch/include/asm/unwind_hints.h b/arch/loongarch/include/asm/unwind_hints.h
new file mode 100644
index 000000000000..a01086ad9dde
--- /dev/null
+++ b/arch/loongarch/include/asm/unwind_hints.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_LOONGARCH_UNWIND_HINTS_H
+#define _ASM_LOONGARCH_UNWIND_HINTS_H
+
+#include <linux/objtool.h>
+#include <asm/orc_types.h>
+
+#ifdef __ASSEMBLY__
+
+.macro UNWIND_HINT_UNDEFINED
+ UNWIND_HINT type=UNWIND_HINT_TYPE_UNDEFINED
+.endm
+
+.macro UNWIND_HINT_END_OF_STACK
+ UNWIND_HINT type=UNWIND_HINT_TYPE_END_OF_STACK
+.endm
+
+.macro UNWIND_HINT_REGS
+ UNWIND_HINT sp_reg=ORC_REG_SP type=UNWIND_HINT_TYPE_REGS
+.endm
+
+.macro UNWIND_HINT_FUNC
+ UNWIND_HINT sp_reg=ORC_REG_SP type=UNWIND_HINT_TYPE_CALL
+.endm
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_LOONGARCH_UNWIND_HINTS_H */
diff --git a/arch/loongarch/include/uapi/asm/kvm.h b/arch/loongarch/include/uapi/asm/kvm.h
index 923d0bd38294..109785922cf9 100644
--- a/arch/loongarch/include/uapi/asm/kvm.h
+++ b/arch/loongarch/include/uapi/asm/kvm.h
@@ -14,8 +14,6 @@
* Some parts derived from the x86 version of this file.
*/
-#define __KVM_HAVE_READONLY_MEM
-
#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
#define KVM_DIRTY_LOG_PAGE_OFFSET 64
diff --git a/arch/loongarch/kernel/Makefile b/arch/loongarch/kernel/Makefile
index 3c808c680370..3a7620b66bc6 100644
--- a/arch/loongarch/kernel/Makefile
+++ b/arch/loongarch/kernel/Makefile
@@ -3,6 +3,8 @@
# Makefile for the Linux/LoongArch kernel.
#
+OBJECT_FILES_NON_STANDARD_head.o := y
+
extra-y := vmlinux.lds
obj-y += head.o cpu-probe.o cacheinfo.o env.o setup.o entry.o genex.o \
@@ -21,6 +23,7 @@ obj-$(CONFIG_ARCH_STRICT_ALIGN) += unaligned.o
CFLAGS_module.o += $(call cc-option,-Wno-override-init,)
CFLAGS_syscall.o += $(call cc-option,-Wno-override-init,)
+CFLAGS_traps.o += $(call cc-option,-Wno-override-init,)
CFLAGS_perf_event.o += $(call cc-option,-Wno-override-init,)
ifdef CONFIG_FUNCTION_TRACER
@@ -62,6 +65,7 @@ obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_UNWINDER_GUESS) += unwind_guess.o
obj-$(CONFIG_UNWINDER_PROLOGUE) += unwind_prologue.o
+obj-$(CONFIG_UNWINDER_ORC) += unwind_orc.o
obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_regs.o
obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
diff --git a/arch/loongarch/kernel/entry.S b/arch/loongarch/kernel/entry.S
index 1ec8e4c4cc2b..48e7e34e355e 100644
--- a/arch/loongarch/kernel/entry.S
+++ b/arch/loongarch/kernel/entry.S
@@ -14,11 +14,13 @@
#include <asm/regdef.h>
#include <asm/stackframe.h>
#include <asm/thread_info.h>
+#include <asm/unwind_hints.h>
.text
.cfi_sections .debug_frame
.align 5
SYM_CODE_START(handle_syscall)
+ UNWIND_HINT_UNDEFINED
csrrd t0, PERCPU_BASE_KS
la.pcrel t1, kernelsp
add.d t1, t1, t0
@@ -57,6 +59,7 @@ SYM_CODE_START(handle_syscall)
cfi_st fp, PT_R22
SAVE_STATIC
+ UNWIND_HINT_REGS
#ifdef CONFIG_KGDB
li.w t1, CSR_CRMD_WE
@@ -75,6 +78,7 @@ SYM_CODE_END(handle_syscall)
_ASM_NOKPROBE(handle_syscall)
SYM_CODE_START(ret_from_fork)
+ UNWIND_HINT_REGS
bl schedule_tail # a0 = struct task_struct *prev
move a0, sp
bl syscall_exit_to_user_mode
@@ -84,6 +88,7 @@ SYM_CODE_START(ret_from_fork)
SYM_CODE_END(ret_from_fork)
SYM_CODE_START(ret_from_kernel_thread)
+ UNWIND_HINT_REGS
bl schedule_tail # a0 = struct task_struct *prev
move a0, s1
jirl ra, s0, 0
diff --git a/arch/loongarch/kernel/fpu.S b/arch/loongarch/kernel/fpu.S
index 4382e36ae3d4..69a85f2479fb 100644
--- a/arch/loongarch/kernel/fpu.S
+++ b/arch/loongarch/kernel/fpu.S
@@ -15,6 +15,7 @@
#include <asm/fpregdef.h>
#include <asm/loongarch.h>
#include <asm/regdef.h>
+#include <asm/unwind_hints.h>
#define FPU_REG_WIDTH 8
#define LSX_REG_WIDTH 16
@@ -526,3 +527,9 @@ SYM_FUNC_END(_restore_lasx_context)
.L_fpu_fault:
li.w a0, -EFAULT # failure
jr ra
+
+#ifdef CONFIG_CPU_HAS_LBT
+STACK_FRAME_NON_STANDARD _restore_fp
+STACK_FRAME_NON_STANDARD _restore_lsx
+STACK_FRAME_NON_STANDARD _restore_lasx
+#endif
diff --git a/arch/loongarch/kernel/genex.S b/arch/loongarch/kernel/genex.S
index 2bb3aa2dcfcb..86d5d90ebefe 100644
--- a/arch/loongarch/kernel/genex.S
+++ b/arch/loongarch/kernel/genex.S
@@ -32,6 +32,7 @@ SYM_FUNC_START(__arch_cpu_idle)
SYM_FUNC_END(__arch_cpu_idle)
SYM_CODE_START(handle_vint)
+ UNWIND_HINT_UNDEFINED
BACKUP_T0T1
SAVE_ALL
la_abs t1, __arch_cpu_idle
@@ -49,6 +50,7 @@ SYM_CODE_START(handle_vint)
SYM_CODE_END(handle_vint)
SYM_CODE_START(except_vec_cex)
+ UNWIND_HINT_UNDEFINED
b cache_parity_error
SYM_CODE_END(except_vec_cex)
@@ -67,6 +69,7 @@ SYM_CODE_END(except_vec_cex)
.macro BUILD_HANDLER exception handler prep
.align 5
SYM_CODE_START(handle_\exception)
+ UNWIND_HINT_UNDEFINED
666:
BACKUP_T0T1
SAVE_ALL
@@ -77,7 +80,9 @@ SYM_CODE_END(except_vec_cex)
668:
RESTORE_ALL_AND_RET
SYM_CODE_END(handle_\exception)
+ .pushsection ".data", "aw", %progbits
SYM_DATA(unwind_hint_\exception, .word 668b - 666b)
+ .popsection
.endm
BUILD_HANDLER ade ade badv
@@ -94,6 +99,7 @@ SYM_CODE_END(except_vec_cex)
BUILD_HANDLER reserved reserved none /* others */
SYM_CODE_START(handle_sys)
+ UNWIND_HINT_UNDEFINED
la_abs t0, handle_syscall
jr t0
SYM_CODE_END(handle_sys)
diff --git a/arch/loongarch/kernel/lbt.S b/arch/loongarch/kernel/lbt.S
index 9c75120a26d8..001f061d226a 100644
--- a/arch/loongarch/kernel/lbt.S
+++ b/arch/loongarch/kernel/lbt.S
@@ -11,6 +11,7 @@
#include <asm/asm-offsets.h>
#include <asm/errno.h>
#include <asm/regdef.h>
+#include <asm/unwind_hints.h>
#define SCR_REG_WIDTH 8
@@ -153,3 +154,5 @@ SYM_FUNC_END(_restore_ftop_context)
.L_lbt_fault:
li.w a0, -EFAULT # failure
jr ra
+
+STACK_FRAME_NON_STANDARD _restore_ftop_context
diff --git a/arch/loongarch/kernel/mcount_dyn.S b/arch/loongarch/kernel/mcount_dyn.S
index 482aa553aa2d..0c65cf09110c 100644
--- a/arch/loongarch/kernel/mcount_dyn.S
+++ b/arch/loongarch/kernel/mcount_dyn.S
@@ -73,6 +73,7 @@ SYM_FUNC_START(ftrace_stub)
SYM_FUNC_END(ftrace_stub)
SYM_CODE_START(ftrace_common)
+ UNWIND_HINT_UNDEFINED
PTR_ADDI a0, ra, -8 /* arg0: ip */
move a1, t0 /* arg1: parent_ip */
la.pcrel t1, function_trace_op
@@ -113,12 +114,14 @@ ftrace_common_return:
SYM_CODE_END(ftrace_common)
SYM_CODE_START(ftrace_caller)
+ UNWIND_HINT_UNDEFINED
ftrace_regs_entry allregs=0
b ftrace_common
SYM_CODE_END(ftrace_caller)
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
SYM_CODE_START(ftrace_regs_caller)
+ UNWIND_HINT_UNDEFINED
ftrace_regs_entry allregs=1
b ftrace_common
SYM_CODE_END(ftrace_regs_caller)
@@ -126,6 +129,7 @@ SYM_CODE_END(ftrace_regs_caller)
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
SYM_CODE_START(ftrace_graph_caller)
+ UNWIND_HINT_UNDEFINED
PTR_L a0, sp, PT_ERA
PTR_ADDI a0, a0, -8 /* arg0: self_addr */
PTR_ADDI a1, sp, PT_R1 /* arg1: parent */
@@ -134,6 +138,7 @@ SYM_CODE_START(ftrace_graph_caller)
SYM_CODE_END(ftrace_graph_caller)
SYM_CODE_START(return_to_handler)
+ UNWIND_HINT_UNDEFINED
/* Save return value regs */
PTR_ADDI sp, sp, -FGRET_REGS_SIZE
PTR_S a0, sp, FGRET_REGS_A0
@@ -155,6 +160,7 @@ SYM_CODE_END(return_to_handler)
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
SYM_CODE_START(ftrace_stub_direct_tramp)
+ UNWIND_HINT_UNDEFINED
jr t0
SYM_CODE_END(ftrace_stub_direct_tramp)
#endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
diff --git a/arch/loongarch/kernel/module.c b/arch/loongarch/kernel/module.c
index b13b2858fe39..c7d0338d12c1 100644
--- a/arch/loongarch/kernel/module.c
+++ b/arch/loongarch/kernel/module.c
@@ -20,6 +20,7 @@
#include <linux/kernel.h>
#include <asm/alternative.h>
#include <asm/inst.h>
+#include <asm/unwind.h>
static int rela_stack_push(s64 stack_value, s64 *rela_stack, size_t *rela_stack_top)
{
@@ -515,15 +516,28 @@ static void module_init_ftrace_plt(const Elf_Ehdr *hdr,
int module_finalize(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs, struct module *mod)
{
- const Elf_Shdr *s, *se;
const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+ const Elf_Shdr *s, *alt = NULL, *orc = NULL, *orc_ip = NULL, *ftrace = NULL;
- for (s = sechdrs, se = sechdrs + hdr->e_shnum; s < se; s++) {
+ for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
if (!strcmp(".altinstructions", secstrs + s->sh_name))
- apply_alternatives((void *)s->sh_addr, (void *)s->sh_addr + s->sh_size);
+ alt = s;
+ if (!strcmp(".orc_unwind", secstrs + s->sh_name))
+ orc = s;
+ if (!strcmp(".orc_unwind_ip", secstrs + s->sh_name))
+ orc_ip = s;
if (!strcmp(".ftrace_trampoline", secstrs + s->sh_name))
- module_init_ftrace_plt(hdr, s, mod);
+ ftrace = s;
}
+ if (alt)
+ apply_alternatives((void *)alt->sh_addr, (void *)alt->sh_addr + alt->sh_size);
+
+ if (orc && orc_ip)
+ unwind_module_init(mod, (void *)orc_ip->sh_addr, orc_ip->sh_size, (void *)orc->sh_addr, orc->sh_size);
+
+ if (ftrace)
+ module_init_ftrace_plt(hdr, ftrace, mod);
+
return 0;
}
diff --git a/arch/loongarch/kernel/relocate_kernel.S b/arch/loongarch/kernel/relocate_kernel.S
index f49f6b053763..84e6de2fd973 100644
--- a/arch/loongarch/kernel/relocate_kernel.S
+++ b/arch/loongarch/kernel/relocate_kernel.S
@@ -15,6 +15,7 @@
#include <asm/addrspace.h>
SYM_CODE_START(relocate_new_kernel)
+ UNWIND_HINT_UNDEFINED
/*
* a0: EFI boot flag for the new kernel
* a1: Command line pointer for the new kernel
@@ -90,6 +91,7 @@ SYM_CODE_END(relocate_new_kernel)
* then start at the entry point from LOONGARCH_IOCSR_MBUF0.
*/
SYM_CODE_START(kexec_smp_wait)
+ UNWIND_HINT_UNDEFINED
1: li.w t0, 0x100 /* wait for init loop */
2: addi.w t0, t0, -1 /* limit mailbox access */
bnez t0, 2b
@@ -106,6 +108,5 @@ SYM_CODE_END(kexec_smp_wait)
relocate_new_kernel_end:
-SYM_DATA_START(relocate_new_kernel_size)
- PTR relocate_new_kernel_end - relocate_new_kernel
-SYM_DATA_END(relocate_new_kernel_size)
+ .section ".data"
+SYM_DATA(relocate_new_kernel_size, .long relocate_new_kernel_end - relocate_new_kernel)
diff --git a/arch/loongarch/kernel/rethook_trampoline.S b/arch/loongarch/kernel/rethook_trampoline.S
index bd5772c96338..d4ceb2fa2a5c 100644
--- a/arch/loongarch/kernel/rethook_trampoline.S
+++ b/arch/loongarch/kernel/rethook_trampoline.S
@@ -76,6 +76,7 @@
.endm
SYM_CODE_START(arch_rethook_trampoline)
+ UNWIND_HINT_UNDEFINED
addi.d sp, sp, -PT_SIZE
save_all_base_regs
diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c
index 634ef17fd38b..60e0fe97f61a 100644
--- a/arch/loongarch/kernel/setup.c
+++ b/arch/loongarch/kernel/setup.c
@@ -47,6 +47,7 @@
#include <asm/sections.h>
#include <asm/setup.h>
#include <asm/time.h>
+#include <asm/unwind.h>
#define SMBIOS_BIOSSIZE_OFFSET 0x09
#define SMBIOS_BIOSEXTERN_OFFSET 0x13
@@ -260,7 +261,7 @@ static void __init arch_reserve_crashkernel(void)
char *cmdline = boot_command_line;
bool high = false;
- if (!IS_ENABLED(CONFIG_KEXEC_CORE))
+ if (!IS_ENABLED(CONFIG_CRASH_RESERVE))
return;
ret = parse_crashkernel(cmdline, memblock_phys_mem_size(),
@@ -490,7 +491,7 @@ static int __init add_legacy_isa_io(struct fwnode_handle *fwnode,
}
vaddr = (unsigned long)(PCI_IOBASE + range->io_start);
- ioremap_page_range(vaddr, vaddr + size, hw_start, pgprot_device(PAGE_KERNEL));
+ vmap_page_range(vaddr, vaddr + size, hw_start, pgprot_device(PAGE_KERNEL));
return 0;
}
@@ -587,6 +588,7 @@ static void __init prefill_possible_map(void)
void __init setup_arch(char **cmdline_p)
{
cpu_probe();
+ unwind_init();
init_environ();
efi_init();
diff --git a/arch/loongarch/kernel/stacktrace.c b/arch/loongarch/kernel/stacktrace.c
index f623feb2129f..9a038d1070d7 100644
--- a/arch/loongarch/kernel/stacktrace.c
+++ b/arch/loongarch/kernel/stacktrace.c
@@ -29,6 +29,7 @@ void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie,
regs->csr_era = thread_saved_ra(task);
}
regs->regs[1] = 0;
+ regs->regs[22] = 0;
}
for (unwind_start(&state, task, regs);
@@ -39,6 +40,46 @@ void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie,
}
}
+int arch_stack_walk_reliable(stack_trace_consume_fn consume_entry,
+ void *cookie, struct task_struct *task)
+{
+ unsigned long addr;
+ struct pt_regs dummyregs;
+ struct pt_regs *regs = &dummyregs;
+ struct unwind_state state;
+
+ if (task == current) {
+ regs->regs[3] = (unsigned long)__builtin_frame_address(0);
+ regs->csr_era = (unsigned long)__builtin_return_address(0);
+ } else {
+ regs->regs[3] = thread_saved_fp(task);
+ regs->csr_era = thread_saved_ra(task);
+ }
+ regs->regs[1] = 0;
+ regs->regs[22] = 0;
+
+ for (unwind_start(&state, task, regs);
+ !unwind_done(&state) && !unwind_error(&state); unwind_next_frame(&state)) {
+ addr = unwind_get_return_address(&state);
+
+ /*
+ * A NULL or invalid return address probably means there's some
+ * generated code which __kernel_text_address() doesn't know about.
+ */
+ if (!addr)
+ return -EINVAL;
+
+ if (!consume_entry(cookie, addr))
+ return -EINVAL;
+ }
+
+ /* Check for stack corruption */
+ if (unwind_error(&state))
+ return -EINVAL;
+
+ return 0;
+}
+
static int
copy_stack_frame(unsigned long fp, struct stack_frame *frame)
{
diff --git a/arch/loongarch/kernel/traps.c b/arch/loongarch/kernel/traps.c
index aebfc3733a76..f9f4eb00c92e 100644
--- a/arch/loongarch/kernel/traps.c
+++ b/arch/loongarch/kernel/traps.c
@@ -53,6 +53,32 @@
#include "access-helper.h"
+void *exception_table[EXCCODE_INT_START] = {
+ [0 ... EXCCODE_INT_START - 1] = handle_reserved,
+
+ [EXCCODE_TLBI] = handle_tlb_load,
+ [EXCCODE_TLBL] = handle_tlb_load,
+ [EXCCODE_TLBS] = handle_tlb_store,
+ [EXCCODE_TLBM] = handle_tlb_modify,
+ [EXCCODE_TLBNR] = handle_tlb_protect,
+ [EXCCODE_TLBNX] = handle_tlb_protect,
+ [EXCCODE_TLBPE] = handle_tlb_protect,
+ [EXCCODE_ADE] = handle_ade,
+ [EXCCODE_ALE] = handle_ale,
+ [EXCCODE_BCE] = handle_bce,
+ [EXCCODE_SYS] = handle_sys,
+ [EXCCODE_BP] = handle_bp,
+ [EXCCODE_INE] = handle_ri,
+ [EXCCODE_IPE] = handle_ri,
+ [EXCCODE_FPDIS] = handle_fpu,
+ [EXCCODE_LSXDIS] = handle_lsx,
+ [EXCCODE_LASXDIS] = handle_lasx,
+ [EXCCODE_FPE] = handle_fpe,
+ [EXCCODE_WATCH] = handle_watch,
+ [EXCCODE_BTDIS] = handle_lbt,
+};
+EXPORT_SYMBOL_GPL(exception_table);
+
static void show_backtrace(struct task_struct *task, const struct pt_regs *regs,
const char *loglvl, bool user)
{
@@ -1150,19 +1176,9 @@ void __init trap_init(void)
for (i = EXCCODE_INT_START; i <= EXCCODE_INT_END; i++)
set_handler(i * VECSIZE, handle_vint, VECSIZE);
- set_handler(EXCCODE_ADE * VECSIZE, handle_ade, VECSIZE);
- set_handler(EXCCODE_ALE * VECSIZE, handle_ale, VECSIZE);
- set_handler(EXCCODE_BCE * VECSIZE, handle_bce, VECSIZE);
- set_handler(EXCCODE_SYS * VECSIZE, handle_sys, VECSIZE);
- set_handler(EXCCODE_BP * VECSIZE, handle_bp, VECSIZE);
- set_handler(EXCCODE_INE * VECSIZE, handle_ri, VECSIZE);
- set_handler(EXCCODE_IPE * VECSIZE, handle_ri, VECSIZE);
- set_handler(EXCCODE_FPDIS * VECSIZE, handle_fpu, VECSIZE);
- set_handler(EXCCODE_LSXDIS * VECSIZE, handle_lsx, VECSIZE);
- set_handler(EXCCODE_LASXDIS * VECSIZE, handle_lasx, VECSIZE);
- set_handler(EXCCODE_FPE * VECSIZE, handle_fpe, VECSIZE);
- set_handler(EXCCODE_BTDIS * VECSIZE, handle_lbt, VECSIZE);
- set_handler(EXCCODE_WATCH * VECSIZE, handle_watch, VECSIZE);
+ /* Set exception vector handler */
+ for (i = EXCCODE_ADE; i <= EXCCODE_BTDIS; i++)
+ set_handler(i * VECSIZE, exception_table[i], VECSIZE);
cache_error_setup();
diff --git a/arch/loongarch/kernel/unwind_orc.c b/arch/loongarch/kernel/unwind_orc.c
new file mode 100644
index 000000000000..b25722876331
--- /dev/null
+++ b/arch/loongarch/kernel/unwind_orc.c
@@ -0,0 +1,528 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/objtool.h>
+#include <linux/module.h>
+#include <linux/sort.h>
+#include <asm/exception.h>
+#include <asm/orc_header.h>
+#include <asm/orc_lookup.h>
+#include <asm/orc_types.h>
+#include <asm/ptrace.h>
+#include <asm/setup.h>
+#include <asm/stacktrace.h>
+#include <asm/tlb.h>
+#include <asm/unwind.h>
+
+ORC_HEADER;
+
+#define orc_warn(fmt, ...) \
+ printk_deferred_once(KERN_WARNING "WARNING: " fmt, ##__VA_ARGS__)
+
+extern int __start_orc_unwind_ip[];
+extern int __stop_orc_unwind_ip[];
+extern struct orc_entry __start_orc_unwind[];
+extern struct orc_entry __stop_orc_unwind[];
+
+static bool orc_init __ro_after_init;
+static unsigned int lookup_num_blocks __ro_after_init;
+
+/* Fake frame pointer entry -- used as a fallback for generated code */
+static struct orc_entry orc_fp_entry = {
+ .sp_reg = ORC_REG_FP,
+ .sp_offset = 16,
+ .fp_reg = ORC_REG_PREV_SP,
+ .fp_offset = -16,
+ .ra_reg = ORC_REG_PREV_SP,
+ .ra_offset = -8,
+ .type = ORC_TYPE_CALL
+};
+
+/*
+ * If we crash with IP==0, the last successfully executed instruction
+ * was probably an indirect function call with a NULL function pointer,
+ * and we don't have unwind information for NULL.
+ * This hardcoded ORC entry for IP==0 allows us to unwind from a NULL function
+ * pointer into its parent and then continue normally from there.
+ */
+static struct orc_entry orc_null_entry = {
+ .sp_reg = ORC_REG_SP,
+ .sp_offset = sizeof(long),
+ .fp_reg = ORC_REG_UNDEFINED,
+ .type = ORC_TYPE_CALL
+};
+
+static inline unsigned long orc_ip(const int *ip)
+{
+ return (unsigned long)ip + *ip;
+}
+
+static struct orc_entry *__orc_find(int *ip_table, struct orc_entry *u_table,
+ unsigned int num_entries, unsigned long ip)
+{
+ int *first = ip_table;
+ int *mid = first, *found = first;
+ int *last = ip_table + num_entries - 1;
+
+ if (!num_entries)
+ return NULL;
+
+ /*
+ * Do a binary range search to find the rightmost duplicate of a given
+ * starting address. Some entries are section terminators which are
+ * "weak" entries for ensuring there are no gaps. They should be
+ * ignored when they conflict with a real entry.
+ */
+ while (first <= last) {
+ mid = first + ((last - first) / 2);
+
+ if (orc_ip(mid) <= ip) {
+ found = mid;
+ first = mid + 1;
+ } else
+ last = mid - 1;
+ }
+
+ return u_table + (found - ip_table);
+}
+
+#ifdef CONFIG_MODULES
+static struct orc_entry *orc_module_find(unsigned long ip)
+{
+ struct module *mod;
+
+ mod = __module_address(ip);
+ if (!mod || !mod->arch.orc_unwind || !mod->arch.orc_unwind_ip)
+ return NULL;
+
+ return __orc_find(mod->arch.orc_unwind_ip, mod->arch.orc_unwind, mod->arch.num_orcs, ip);
+}
+#else
+static struct orc_entry *orc_module_find(unsigned long ip)
+{
+ return NULL;
+}
+#endif
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+static struct orc_entry *orc_find(unsigned long ip);
+
+/*
+ * Ftrace dynamic trampolines do not have orc entries of their own.
+ * But they are copies of the ftrace entries that are static and
+ * defined in ftrace_*.S, which do have orc entries.
+ *
+ * If the unwinder comes across a ftrace trampoline, then find the
+ * ftrace function that was used to create it, and use that ftrace
+ * function's orc entry, as the placement of the return code in
+ * the stack will be identical.
+ */
+static struct orc_entry *orc_ftrace_find(unsigned long ip)
+{
+ struct ftrace_ops *ops;
+ unsigned long tramp_addr, offset;
+
+ ops = ftrace_ops_trampoline(ip);
+ if (!ops)
+ return NULL;
+
+ /* Set tramp_addr to the start of the code copied by the trampoline */
+ if (ops->flags & FTRACE_OPS_FL_SAVE_REGS)
+ tramp_addr = (unsigned long)ftrace_regs_caller;
+ else
+ tramp_addr = (unsigned long)ftrace_caller;
+
+ /* Now place tramp_addr to the location within the trampoline ip is at */
+ offset = ip - ops->trampoline;
+ tramp_addr += offset;
+
+ /* Prevent unlikely recursion */
+ if (ip == tramp_addr)
+ return NULL;
+
+ return orc_find(tramp_addr);
+}
+#else
+static struct orc_entry *orc_ftrace_find(unsigned long ip)
+{
+ return NULL;
+}
+#endif
+
+static struct orc_entry *orc_find(unsigned long ip)
+{
+ static struct orc_entry *orc;
+
+ if (ip == 0)
+ return &orc_null_entry;
+
+ /* For non-init vmlinux addresses, use the fast lookup table: */
+ if (ip >= LOOKUP_START_IP && ip < LOOKUP_STOP_IP) {
+ unsigned int idx, start, stop;
+
+ idx = (ip - LOOKUP_START_IP) / LOOKUP_BLOCK_SIZE;
+
+ if (unlikely((idx >= lookup_num_blocks-1))) {
+ orc_warn("WARNING: bad lookup idx: idx=%u num=%u ip=%pB\n",
+ idx, lookup_num_blocks, (void *)ip);
+ return NULL;
+ }
+
+ start = orc_lookup[idx];
+ stop = orc_lookup[idx + 1] + 1;
+
+ if (unlikely((__start_orc_unwind + start >= __stop_orc_unwind) ||
+ (__start_orc_unwind + stop > __stop_orc_unwind))) {
+ orc_warn("WARNING: bad lookup value: idx=%u num=%u start=%u stop=%u ip=%pB\n",
+ idx, lookup_num_blocks, start, stop, (void *)ip);
+ return NULL;
+ }
+
+ return __orc_find(__start_orc_unwind_ip + start,
+ __start_orc_unwind + start, stop - start, ip);
+ }
+
+ /* vmlinux .init slow lookup: */
+ if (is_kernel_inittext(ip))
+ return __orc_find(__start_orc_unwind_ip, __start_orc_unwind,
+ __stop_orc_unwind_ip - __start_orc_unwind_ip, ip);
+
+ /* Module lookup: */
+ orc = orc_module_find(ip);
+ if (orc)
+ return orc;
+
+ return orc_ftrace_find(ip);
+}
+
+#ifdef CONFIG_MODULES
+
+static DEFINE_MUTEX(sort_mutex);
+static int *cur_orc_ip_table = __start_orc_unwind_ip;
+static struct orc_entry *cur_orc_table = __start_orc_unwind;
+
+static void orc_sort_swap(void *_a, void *_b, int size)
+{
+ int delta = _b - _a;
+ int *a = _a, *b = _b, tmp;
+ struct orc_entry *orc_a, *orc_b;
+
+ /* Swap the .orc_unwind_ip entries: */
+ tmp = *a;
+ *a = *b + delta;
+ *b = tmp - delta;
+
+ /* Swap the corresponding .orc_unwind entries: */
+ orc_a = cur_orc_table + (a - cur_orc_ip_table);
+ orc_b = cur_orc_table + (b - cur_orc_ip_table);
+ swap(*orc_a, *orc_b);
+}
+
+static int orc_sort_cmp(const void *_a, const void *_b)
+{
+ const int *a = _a, *b = _b;
+ unsigned long a_val = orc_ip(a);
+ unsigned long b_val = orc_ip(b);
+ struct orc_entry *orc_a;
+
+ if (a_val > b_val)
+ return 1;
+ if (a_val < b_val)
+ return -1;
+
+ /*
+ * The "weak" section terminator entries need to always be first
+ * to ensure the lookup code skips them in favor of real entries.
+ * These terminator entries exist to handle any gaps created by
+ * whitelisted .o files which didn't get objtool generation.
+ */
+ orc_a = cur_orc_table + (a - cur_orc_ip_table);
+
+ return orc_a->type == ORC_TYPE_UNDEFINED ? -1 : 1;
+}
+
+void unwind_module_init(struct module *mod, void *_orc_ip, size_t orc_ip_size,
+ void *_orc, size_t orc_size)
+{
+ int *orc_ip = _orc_ip;
+ struct orc_entry *orc = _orc;
+ unsigned int num_entries = orc_ip_size / sizeof(int);
+
+ WARN_ON_ONCE(orc_ip_size % sizeof(int) != 0 ||
+ orc_size % sizeof(*orc) != 0 ||
+ num_entries != orc_size / sizeof(*orc));
+
+ /*
+ * The 'cur_orc_*' globals allow the orc_sort_swap() callback to
+ * associate an .orc_unwind_ip table entry with its corresponding
+ * .orc_unwind entry so they can both be swapped.
+ */
+ mutex_lock(&sort_mutex);
+ cur_orc_ip_table = orc_ip;
+ cur_orc_table = orc;
+ sort(orc_ip, num_entries, sizeof(int), orc_sort_cmp, orc_sort_swap);
+ mutex_unlock(&sort_mutex);
+
+ mod->arch.orc_unwind_ip = orc_ip;
+ mod->arch.orc_unwind = orc;
+ mod->arch.num_orcs = num_entries;
+}
+#endif
+
+void __init unwind_init(void)
+{
+ int i;
+ size_t orc_size = (void *)__stop_orc_unwind - (void *)__start_orc_unwind;
+ size_t orc_ip_size = (void *)__stop_orc_unwind_ip - (void *)__start_orc_unwind_ip;
+ size_t num_entries = orc_ip_size / sizeof(int);
+ struct orc_entry *orc;
+
+ if (!num_entries || orc_ip_size % sizeof(int) != 0 ||
+ orc_size % sizeof(struct orc_entry) != 0 ||
+ num_entries != orc_size / sizeof(struct orc_entry)) {
+ orc_warn("WARNING: Bad or missing .orc_unwind table. Disabling unwinder.\n");
+ return;
+ }
+
+ /*
+ * Note, the orc_unwind and orc_unwind_ip tables were already
+ * sorted at build time via the 'sorttable' tool.
+ * It's ready for binary search straight away, no need to sort it.
+ */
+
+ /* Initialize the fast lookup table: */
+ lookup_num_blocks = orc_lookup_end - orc_lookup;
+ for (i = 0; i < lookup_num_blocks-1; i++) {
+ orc = __orc_find(__start_orc_unwind_ip, __start_orc_unwind,
+ num_entries, LOOKUP_START_IP + (LOOKUP_BLOCK_SIZE * i));
+ if (!orc) {
+ orc_warn("WARNING: Corrupt .orc_unwind table. Disabling unwinder.\n");
+ return;
+ }
+
+ orc_lookup[i] = orc - __start_orc_unwind;
+ }
+
+ /* Initialize the ending block: */
+ orc = __orc_find(__start_orc_unwind_ip, __start_orc_unwind, num_entries, LOOKUP_STOP_IP);
+ if (!orc) {
+ orc_warn("WARNING: Corrupt .orc_unwind table. Disabling unwinder.\n");
+ return;
+ }
+ orc_lookup[lookup_num_blocks-1] = orc - __start_orc_unwind;
+
+ orc_init = true;
+}
+
+static inline bool on_stack(struct stack_info *info, unsigned long addr, size_t len)
+{
+ unsigned long begin = info->begin;
+ unsigned long end = info->end;
+
+ return (info->type != STACK_TYPE_UNKNOWN &&
+ addr >= begin && addr < end && addr + len > begin && addr + len <= end);
+}
+
+static bool stack_access_ok(struct unwind_state *state, unsigned long addr, size_t len)
+{
+ struct stack_info *info = &state->stack_info;
+
+ if (on_stack(info, addr, len))
+ return true;
+
+ return !get_stack_info(addr, state->task, info) && on_stack(info, addr, len);
+}
+
+unsigned long unwind_get_return_address(struct unwind_state *state)
+{
+ return __unwind_get_return_address(state);
+}
+EXPORT_SYMBOL_GPL(unwind_get_return_address);
+
+void unwind_start(struct unwind_state *state, struct task_struct *task,
+ struct pt_regs *regs)
+{
+ __unwind_start(state, task, regs);
+ state->type = UNWINDER_ORC;
+ if (!unwind_done(state) && !__kernel_text_address(state->pc))
+ unwind_next_frame(state);
+}
+EXPORT_SYMBOL_GPL(unwind_start);
+
+static bool is_entry_func(unsigned long addr)
+{
+ extern u32 kernel_entry;
+ extern u32 kernel_entry_end;
+
+ return addr >= (unsigned long)&kernel_entry && addr < (unsigned long)&kernel_entry_end;
+}
+
+static inline unsigned long bt_address(unsigned long ra)
+{
+ extern unsigned long eentry;
+
+ if (__kernel_text_address(ra))
+ return ra;
+
+ if (__module_text_address(ra))
+ return ra;
+
+ if (ra >= eentry && ra < eentry + EXCCODE_INT_END * VECSIZE) {
+ unsigned long func;
+ unsigned long type = (ra - eentry) / VECSIZE;
+ unsigned long offset = (ra - eentry) % VECSIZE;
+
+ switch (type) {
+ case 0 ... EXCCODE_INT_START - 1:
+ func = (unsigned long)exception_table[type];
+ break;
+ case EXCCODE_INT_START ... EXCCODE_INT_END:
+ func = (unsigned long)handle_vint;
+ break;
+ default:
+ func = (unsigned long)handle_reserved;
+ break;
+ }
+
+ return func + offset;
+ }
+
+ return ra;
+}
+
+bool unwind_next_frame(struct unwind_state *state)
+{
+ unsigned long *p, pc;
+ struct pt_regs *regs;
+ struct orc_entry *orc;
+ struct stack_info *info = &state->stack_info;
+
+ if (unwind_done(state))
+ return false;
+
+ /* Don't let modules unload while we're reading their ORC data. */
+ preempt_disable();
+
+ if (is_entry_func(state->pc))
+ goto end;
+
+ orc = orc_find(state->pc);
+ if (!orc) {
+ /*
+ * As a fallback, try to assume this code uses a frame pointer.
+ * This is useful for generated code, like BPF, which ORC
+ * doesn't know about. This is just a guess, so the rest of
+ * the unwind is no longer considered reliable.
+ */
+ orc = &orc_fp_entry;
+ state->error = true;
+ } else {
+ if (orc->type == ORC_TYPE_UNDEFINED)
+ goto err;
+
+ if (orc->type == ORC_TYPE_END_OF_STACK)
+ goto end;
+ }
+
+ switch (orc->sp_reg) {
+ case ORC_REG_SP:
+ if (info->type == STACK_TYPE_IRQ && state->sp == info->end)
+ orc->type = ORC_TYPE_REGS;
+ else
+ state->sp = state->sp + orc->sp_offset;
+ break;
+ case ORC_REG_FP:
+ state->sp = state->fp;
+ break;
+ default:
+ orc_warn("unknown SP base reg %d at %pB\n", orc->sp_reg, (void *)state->pc);
+ goto err;
+ }
+
+ switch (orc->fp_reg) {
+ case ORC_REG_PREV_SP:
+ p = (unsigned long *)(state->sp + orc->fp_offset);
+ if (!stack_access_ok(state, (unsigned long)p, sizeof(unsigned long)))
+ goto err;
+
+ state->fp = *p;
+ break;
+ case ORC_REG_UNDEFINED:
+ /* Nothing. */
+ break;
+ default:
+ orc_warn("unknown FP base reg %d at %pB\n", orc->fp_reg, (void *)state->pc);
+ goto err;
+ }
+
+ switch (orc->type) {
+ case ORC_TYPE_CALL:
+ if (orc->ra_reg == ORC_REG_PREV_SP) {
+ p = (unsigned long *)(state->sp + orc->ra_offset);
+ if (!stack_access_ok(state, (unsigned long)p, sizeof(unsigned long)))
+ goto err;
+
+ pc = unwind_graph_addr(state, *p, state->sp);
+ pc -= LOONGARCH_INSN_SIZE;
+ } else if (orc->ra_reg == ORC_REG_UNDEFINED) {
+ if (!state->ra || state->ra == state->pc)
+ goto err;
+
+ pc = unwind_graph_addr(state, state->ra, state->sp);
+ pc -= LOONGARCH_INSN_SIZE;
+ state->ra = 0;
+ } else {
+ orc_warn("unknown ra base reg %d at %pB\n", orc->ra_reg, (void *)state->pc);
+ goto err;
+ }
+ break;
+ case ORC_TYPE_REGS:
+ if (info->type == STACK_TYPE_IRQ && state->sp == info->end)
+ regs = (struct pt_regs *)info->next_sp;
+ else
+ regs = (struct pt_regs *)state->sp;
+
+ if (!stack_access_ok(state, (unsigned long)regs, sizeof(*regs)))
+ goto err;
+
+ if ((info->end == (unsigned long)regs + sizeof(*regs)) &&
+ !regs->regs[3] && !regs->regs[1])
+ goto end;
+
+ if (user_mode(regs))
+ goto end;
+
+ pc = regs->csr_era;
+ if (!__kernel_text_address(pc))
+ goto err;
+
+ state->sp = regs->regs[3];
+ state->ra = regs->regs[1];
+ state->fp = regs->regs[22];
+ get_stack_info(state->sp, state->task, info);
+
+ break;
+ default:
+ orc_warn("unknown .orc_unwind entry type %d at %pB\n", orc->type, (void *)state->pc);
+ goto err;
+ }
+
+ state->pc = bt_address(pc);
+ if (!state->pc) {
+ pr_err("cannot find unwind pc at %pK\n", (void *)pc);
+ goto err;
+ }
+
+ if (!__kernel_text_address(state->pc))
+ goto err;
+
+ preempt_enable();
+ return true;
+
+err:
+ state->error = true;
+
+end:
+ preempt_enable();
+ state->stack_info.type = STACK_TYPE_UNKNOWN;
+ return false;
+}
+EXPORT_SYMBOL_GPL(unwind_next_frame);
diff --git a/arch/loongarch/kernel/vdso.c b/arch/loongarch/kernel/vdso.c
index 14941e4be66d..90dfccb41c14 100644
--- a/arch/loongarch/kernel/vdso.c
+++ b/arch/loongarch/kernel/vdso.c
@@ -21,15 +21,13 @@
#include <asm/vdso.h>
#include <vdso/helpers.h>
#include <vdso/vsyscall.h>
+#include <vdso/datapage.h>
#include <generated/vdso-offsets.h>
extern char vdso_start[], vdso_end[];
/* Kernel-provided data used by the VDSO. */
-static union {
- u8 page[PAGE_SIZE];
- struct vdso_data data[CS_BASES];
-} generic_vdso_data __page_aligned_data;
+static union vdso_data_store generic_vdso_data __page_aligned_data;
static union {
u8 page[LOONGARCH_VDSO_DATA_SIZE];
diff --git a/arch/loongarch/kernel/vmlinux.lds.S b/arch/loongarch/kernel/vmlinux.lds.S
index a5d0cd2035da..e8e97dbf9ca4 100644
--- a/arch/loongarch/kernel/vmlinux.lds.S
+++ b/arch/loongarch/kernel/vmlinux.lds.S
@@ -2,6 +2,7 @@
#include <linux/sizes.h>
#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
+#include <asm/orc_lookup.h>
#define PAGE_SIZE _PAGE_SIZE
#define RO_EXCEPTION_TABLE_ALIGN 4
@@ -122,6 +123,8 @@ SECTIONS
}
#endif
+ ORC_UNWIND_TABLE
+
.sdata : {
*(.sdata)
}
diff --git a/arch/loongarch/kvm/Kconfig b/arch/loongarch/kvm/Kconfig
index 61f7e33b1f95..c4ef2b4d9797 100644
--- a/arch/loongarch/kvm/Kconfig
+++ b/arch/loongarch/kvm/Kconfig
@@ -20,7 +20,6 @@ if VIRTUALIZATION
config KVM
tristate "Kernel-based Virtual Machine (KVM) support"
depends on AS_HAS_LVZ_EXTENSION
- depends on HAVE_KVM
select HAVE_KVM_DIRTY_RING_ACQ_REL
select HAVE_KVM_VCPU_ASYNC_IOCTL
select KVM_COMMON
@@ -28,6 +27,7 @@ config KVM
select KVM_GENERIC_HARDWARE_ENABLING
select KVM_GENERIC_MMU_NOTIFIER
select KVM_MMIO
+ select HAVE_KVM_READONLY_MEM
select KVM_XFER_TO_GUEST_WORK
help
Support hosting virtualized guest machines using
diff --git a/arch/loongarch/kvm/mmu.c b/arch/loongarch/kvm/mmu.c
index 50a6acd7ffe4..a556cff35740 100644
--- a/arch/loongarch/kvm/mmu.c
+++ b/arch/loongarch/kvm/mmu.c
@@ -723,7 +723,7 @@ static int host_pfn_mapping_level(struct kvm *kvm, gfn_t gfn,
/*
* Read each entry once. As above, a non-leaf entry can be promoted to
* a huge page _during_ this walk. Re-reading the entry could send the
- * walk into the weeks, e.g. p*d_large() returns false (sees the old
+ * walk into the weeks, e.g. p*d_leaf() returns false (sees the old
* value) and then p*d_offset() walks into the target huge page instead
* of the old page table (sees the new value).
*/
diff --git a/arch/loongarch/kvm/switch.S b/arch/loongarch/kvm/switch.S
index ba976509bfe8..80e988985a6a 100644
--- a/arch/loongarch/kvm/switch.S
+++ b/arch/loongarch/kvm/switch.S
@@ -8,7 +8,7 @@
#include <asm/asmmacro.h>
#include <asm/loongarch.h>
#include <asm/regdef.h>
-#include <asm/stackframe.h>
+#include <asm/unwind_hints.h>
#define HGPR_OFFSET(x) (PT_R0 + 8*x)
#define GGPR_OFFSET(x) (KVM_ARCH_GGPR + 8*x)
@@ -112,6 +112,7 @@
.text
.cfi_sections .debug_frame
SYM_CODE_START(kvm_exc_entry)
+ UNWIND_HINT_UNDEFINED
csrwr a2, KVM_TEMP_KS
csrrd a2, KVM_VCPU_KS
addi.d a2, a2, KVM_VCPU_ARCH
@@ -213,12 +214,6 @@ SYM_FUNC_START(kvm_enter_guest)
/* Save host GPRs */
kvm_save_host_gpr a2
- /* Save host CRMD, PRMD to stack */
- csrrd a3, LOONGARCH_CSR_CRMD
- st.d a3, a2, PT_CRMD
- csrrd a3, LOONGARCH_CSR_PRMD
- st.d a3, a2, PT_PRMD
-
addi.d a2, a1, KVM_VCPU_ARCH
st.d sp, a2, KVM_ARCH_HSP
st.d tp, a2, KVM_ARCH_HTP
@@ -279,3 +274,9 @@ SYM_FUNC_END(kvm_restore_lasx)
.section ".rodata"
SYM_DATA(kvm_exception_size, .quad kvm_exc_entry_end - kvm_exc_entry)
SYM_DATA(kvm_enter_guest_size, .quad kvm_enter_guest_end - kvm_enter_guest)
+
+#ifdef CONFIG_CPU_HAS_LBT
+STACK_FRAME_NON_STANDARD kvm_restore_fpu
+STACK_FRAME_NON_STANDARD kvm_restore_lsx
+STACK_FRAME_NON_STANDARD kvm_restore_lasx
+#endif
diff --git a/arch/loongarch/kvm/timer.c b/arch/loongarch/kvm/timer.c
index 111328f60872..bcc6b6d063d9 100644
--- a/arch/loongarch/kvm/timer.c
+++ b/arch/loongarch/kvm/timer.c
@@ -23,24 +23,6 @@ static inline u64 tick_to_ns(struct kvm_vcpu *vcpu, u64 tick)
return div_u64(tick * MNSEC_PER_SEC, vcpu->arch.timer_mhz);
}
-/*
- * Push timer forward on timeout.
- * Handle an hrtimer event by push the hrtimer forward a period.
- */
-static enum hrtimer_restart kvm_count_timeout(struct kvm_vcpu *vcpu)
-{
- unsigned long cfg, period;
-
- /* Add periodic tick to current expire time */
- cfg = kvm_read_sw_gcsr(vcpu->arch.csr, LOONGARCH_CSR_TCFG);
- if (cfg & CSR_TCFG_PERIOD) {
- period = tick_to_ns(vcpu, cfg & CSR_TCFG_VAL);
- hrtimer_add_expires_ns(&vcpu->arch.swtimer, period);
- return HRTIMER_RESTART;
- } else
- return HRTIMER_NORESTART;
-}
-
/* Low level hrtimer wake routine */
enum hrtimer_restart kvm_swtimer_wakeup(struct hrtimer *timer)
{
@@ -50,7 +32,7 @@ enum hrtimer_restart kvm_swtimer_wakeup(struct hrtimer *timer)
kvm_queue_irq(vcpu, INT_TI);
rcuwait_wake_up(&vcpu->wait);
- return kvm_count_timeout(vcpu);
+ return HRTIMER_NORESTART;
}
/*
@@ -93,7 +75,8 @@ void kvm_restore_timer(struct kvm_vcpu *vcpu)
/*
* Freeze the soft-timer and sync the guest stable timer with it.
*/
- hrtimer_cancel(&vcpu->arch.swtimer);
+ if (kvm_vcpu_is_blocking(vcpu))
+ hrtimer_cancel(&vcpu->arch.swtimer);
/*
* From LoongArch Reference Manual Volume 1 Chapter 7.6.2
@@ -168,26 +151,20 @@ static void _kvm_save_timer(struct kvm_vcpu *vcpu)
* Here judge one-shot timer fired by checking whether TVAL is larger
* than TCFG
*/
- if (ticks < cfg) {
+ if (ticks < cfg)
delta = tick_to_ns(vcpu, ticks);
- expire = ktime_add_ns(ktime_get(), delta);
- vcpu->arch.expire = expire;
+ else
+ delta = 0;
+
+ expire = ktime_add_ns(ktime_get(), delta);
+ vcpu->arch.expire = expire;
+ if (kvm_vcpu_is_blocking(vcpu)) {
/*
* HRTIMER_MODE_PINNED is suggested since vcpu may run in
* the same physical cpu in next time
*/
hrtimer_start(&vcpu->arch.swtimer, expire, HRTIMER_MODE_ABS_PINNED);
- } else if (vcpu->stat.generic.blocking) {
- /*
- * Inject timer interrupt so that halt polling can dectect and exit.
- * VCPU is scheduled out already and sleeps in rcuwait queue and
- * will not poll pending events again. kvm_queue_irq() is not enough,
- * hrtimer swtimer should be used here.
- */
- expire = ktime_add_ns(ktime_get(), 10);
- vcpu->arch.expire = expire;
- hrtimer_start(&vcpu->arch.swtimer, expire, HRTIMER_MODE_ABS_PINNED);
}
}
diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
index 36106922b5d7..3a8779065f73 100644
--- a/arch/loongarch/kvm/vcpu.c
+++ b/arch/loongarch/kvm/vcpu.c
@@ -304,11 +304,18 @@ static int _kvm_get_cpucfg_mask(int id, u64 *v)
return -EINVAL;
switch (id) {
- case 2:
+ case LOONGARCH_CPUCFG0:
+ *v = GENMASK(31, 0);
+ return 0;
+ case LOONGARCH_CPUCFG1:
+ /* CPUCFG1_MSGINT is not supported by KVM */
+ *v = GENMASK(25, 0);
+ return 0;
+ case LOONGARCH_CPUCFG2:
/* CPUCFG2 features unconditionally supported by KVM */
*v = CPUCFG2_FP | CPUCFG2_FPSP | CPUCFG2_FPDP |
CPUCFG2_FPVERS | CPUCFG2_LLFTP | CPUCFG2_LLFTPREV |
- CPUCFG2_LAM;
+ CPUCFG2_LSPW | CPUCFG2_LAM;
/*
* For the ISA extensions listed below, if one is supported
* by the host, then it is also supported by KVM.
@@ -319,13 +326,25 @@ static int _kvm_get_cpucfg_mask(int id, u64 *v)
*v |= CPUCFG2_LASX;
return 0;
+ case LOONGARCH_CPUCFG3:
+ *v = GENMASK(16, 0);
+ return 0;
+ case LOONGARCH_CPUCFG4:
+ case LOONGARCH_CPUCFG5:
+ *v = GENMASK(31, 0);
+ return 0;
+ case LOONGARCH_CPUCFG16:
+ *v = GENMASK(16, 0);
+ return 0;
+ case LOONGARCH_CPUCFG17 ... LOONGARCH_CPUCFG20:
+ *v = GENMASK(30, 0);
+ return 0;
default:
/*
- * No restrictions on other valid CPUCFG IDs' values, but
- * CPUCFG data is limited to 32 bits as the LoongArch ISA
- * manual says (Volume 1, Section 2.2.10.5 "CPUCFG").
+ * CPUCFG bits should be zero if reserved by HW or not
+ * supported by KVM.
*/
- *v = U32_MAX;
+ *v = 0;
return 0;
}
}
@@ -344,7 +363,7 @@ static int kvm_check_cpucfg(int id, u64 val)
return -EINVAL;
switch (id) {
- case 2:
+ case LOONGARCH_CPUCFG2:
if (!(val & CPUCFG2_LLFTP))
/* Guests must have a constant timer */
return -EINVAL;
diff --git a/arch/loongarch/lib/clear_user.S b/arch/loongarch/lib/clear_user.S
index be741544e62b..7a0db643b286 100644
--- a/arch/loongarch/lib/clear_user.S
+++ b/arch/loongarch/lib/clear_user.S
@@ -10,6 +10,7 @@
#include <asm/asm-extable.h>
#include <asm/cpu.h>
#include <asm/regdef.h>
+#include <asm/unwind_hints.h>
SYM_FUNC_START(__clear_user)
/*
@@ -204,3 +205,5 @@ SYM_FUNC_START(__clear_user_fast)
_asm_extable 28b, .Lsmall_fixup
_asm_extable 29b, .Lexit
SYM_FUNC_END(__clear_user_fast)
+
+STACK_FRAME_NON_STANDARD __clear_user_fast
diff --git a/arch/loongarch/lib/copy_user.S b/arch/loongarch/lib/copy_user.S
index feec3d362803..095ce9181c6c 100644
--- a/arch/loongarch/lib/copy_user.S
+++ b/arch/loongarch/lib/copy_user.S
@@ -10,6 +10,7 @@
#include <asm/asm-extable.h>
#include <asm/cpu.h>
#include <asm/regdef.h>
+#include <asm/unwind_hints.h>
SYM_FUNC_START(__copy_user)
/*
@@ -278,3 +279,5 @@ SYM_FUNC_START(__copy_user_fast)
_asm_extable 58b, .Lexit
_asm_extable 59b, .Lexit
SYM_FUNC_END(__copy_user_fast)
+
+STACK_FRAME_NON_STANDARD __copy_user_fast
diff --git a/arch/loongarch/lib/memcpy.S b/arch/loongarch/lib/memcpy.S
index fa1148878d2b..9517a2f961af 100644
--- a/arch/loongarch/lib/memcpy.S
+++ b/arch/loongarch/lib/memcpy.S
@@ -9,6 +9,7 @@
#include <asm/asmmacro.h>
#include <asm/cpu.h>
#include <asm/regdef.h>
+#include <asm/unwind_hints.h>
.section .noinstr.text, "ax"
@@ -197,3 +198,5 @@ SYM_FUNC_START(__memcpy_fast)
jr ra
SYM_FUNC_END(__memcpy_fast)
_ASM_NOKPROBE(__memcpy_fast)
+
+STACK_FRAME_NON_STANDARD __memcpy_small
diff --git a/arch/loongarch/lib/memset.S b/arch/loongarch/lib/memset.S
index 06d3ca54cbfe..df3846620553 100644
--- a/arch/loongarch/lib/memset.S
+++ b/arch/loongarch/lib/memset.S
@@ -9,6 +9,7 @@
#include <asm/asmmacro.h>
#include <asm/cpu.h>
#include <asm/regdef.h>
+#include <asm/unwind_hints.h>
.macro fill_to_64 r0
bstrins.d \r0, \r0, 15, 8
@@ -166,3 +167,5 @@ SYM_FUNC_START(__memset_fast)
jr ra
SYM_FUNC_END(__memset_fast)
_ASM_NOKPROBE(__memset_fast)
+
+STACK_FRAME_NON_STANDARD __memset_fast
diff --git a/arch/loongarch/mm/mmap.c b/arch/loongarch/mm/mmap.c
index a9630a81b38a..89af7c12e8c0 100644
--- a/arch/loongarch/mm/mmap.c
+++ b/arch/loongarch/mm/mmap.c
@@ -4,6 +4,7 @@
*/
#include <linux/export.h>
#include <linux/io.h>
+#include <linux/kfence.h>
#include <linux/memblock.h>
#include <linux/mm.h>
#include <linux/mman.h>
@@ -111,6 +112,9 @@ int __virt_addr_valid(volatile void *kaddr)
{
unsigned long vaddr = (unsigned long)kaddr;
+ if (is_kfence_address((void *)kaddr))
+ return 1;
+
if ((vaddr < PAGE_OFFSET) || (vaddr >= vm_map_base))
return 0;
diff --git a/arch/loongarch/mm/pgtable.c b/arch/loongarch/mm/pgtable.c
index 2aae72e63871..bda018150000 100644
--- a/arch/loongarch/mm/pgtable.c
+++ b/arch/loongarch/mm/pgtable.c
@@ -11,13 +11,13 @@
struct page *dmw_virt_to_page(unsigned long kaddr)
{
- return pfn_to_page(virt_to_pfn(kaddr));
+ return phys_to_page(__pa(kaddr));
}
EXPORT_SYMBOL(dmw_virt_to_page);
struct page *tlb_virt_to_page(unsigned long kaddr)
{
- return pfn_to_page(pte_pfn(*virt_to_kpte(kaddr)));
+ return phys_to_page(pfn_to_phys(pte_pfn(*virt_to_kpte(kaddr))));
}
EXPORT_SYMBOL(tlb_virt_to_page);
diff --git a/arch/loongarch/mm/tlb.c b/arch/loongarch/mm/tlb.c
index 0b95d32b30c9..5ac9beb5f093 100644
--- a/arch/loongarch/mm/tlb.c
+++ b/arch/loongarch/mm/tlb.c
@@ -9,8 +9,9 @@
#include <linux/hugetlb.h>
#include <linux/export.h>
-#include <asm/cpu.h>
#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+#include <asm/exception.h>
#include <asm/mmu_context.h>
#include <asm/pgtable.h>
#include <asm/tlb.h>
@@ -266,24 +267,20 @@ static void setup_tlb_handler(int cpu)
setup_ptwalker();
local_flush_tlb_all();
+ if (cpu_has_ptw) {
+ exception_table[EXCCODE_TLBI] = handle_tlb_load_ptw;
+ exception_table[EXCCODE_TLBL] = handle_tlb_load_ptw;
+ exception_table[EXCCODE_TLBS] = handle_tlb_store_ptw;
+ exception_table[EXCCODE_TLBM] = handle_tlb_modify_ptw;
+ }
+
/* The tlb handlers are generated only once */
if (cpu == 0) {
memcpy((void *)tlbrentry, handle_tlb_refill, 0x80);
local_flush_icache_range(tlbrentry, tlbrentry + 0x80);
- if (!cpu_has_ptw) {
- set_handler(EXCCODE_TLBI * VECSIZE, handle_tlb_load, VECSIZE);
- set_handler(EXCCODE_TLBL * VECSIZE, handle_tlb_load, VECSIZE);
- set_handler(EXCCODE_TLBS * VECSIZE, handle_tlb_store, VECSIZE);
- set_handler(EXCCODE_TLBM * VECSIZE, handle_tlb_modify, VECSIZE);
- } else {
- set_handler(EXCCODE_TLBI * VECSIZE, handle_tlb_load_ptw, VECSIZE);
- set_handler(EXCCODE_TLBL * VECSIZE, handle_tlb_load_ptw, VECSIZE);
- set_handler(EXCCODE_TLBS * VECSIZE, handle_tlb_store_ptw, VECSIZE);
- set_handler(EXCCODE_TLBM * VECSIZE, handle_tlb_modify_ptw, VECSIZE);
- }
- set_handler(EXCCODE_TLBNR * VECSIZE, handle_tlb_protect, VECSIZE);
- set_handler(EXCCODE_TLBNX * VECSIZE, handle_tlb_protect, VECSIZE);
- set_handler(EXCCODE_TLBPE * VECSIZE, handle_tlb_protect, VECSIZE);
+
+ for (int i = EXCCODE_TLBL; i <= EXCCODE_TLBPE; i++)
+ set_handler(i * VECSIZE, exception_table[i], VECSIZE);
} else {
int vec_sz __maybe_unused;
void *addr __maybe_unused;
diff --git a/arch/loongarch/mm/tlbex.S b/arch/loongarch/mm/tlbex.S
index d5d682f3d29f..a44387b838af 100644
--- a/arch/loongarch/mm/tlbex.S
+++ b/arch/loongarch/mm/tlbex.S
@@ -18,6 +18,7 @@
.macro tlb_do_page_fault, write
SYM_CODE_START(tlb_do_page_fault_\write)
+ UNWIND_HINT_UNDEFINED
SAVE_ALL
csrrd a2, LOONGARCH_CSR_BADV
move a0, sp
@@ -32,6 +33,7 @@
tlb_do_page_fault 1
SYM_CODE_START(handle_tlb_protect)
+ UNWIND_HINT_UNDEFINED
BACKUP_T0T1
SAVE_ALL
move a0, sp
@@ -44,6 +46,7 @@ SYM_CODE_START(handle_tlb_protect)
SYM_CODE_END(handle_tlb_protect)
SYM_CODE_START(handle_tlb_load)
+ UNWIND_HINT_UNDEFINED
csrwr t0, EXCEPTION_KS0
csrwr t1, EXCEPTION_KS1
csrwr ra, EXCEPTION_KS2
@@ -190,6 +193,7 @@ nopage_tlb_load:
SYM_CODE_END(handle_tlb_load)
SYM_CODE_START(handle_tlb_load_ptw)
+ UNWIND_HINT_UNDEFINED
csrwr t0, LOONGARCH_CSR_KS0
csrwr t1, LOONGARCH_CSR_KS1
la_abs t0, tlb_do_page_fault_0
@@ -197,6 +201,7 @@ SYM_CODE_START(handle_tlb_load_ptw)
SYM_CODE_END(handle_tlb_load_ptw)
SYM_CODE_START(handle_tlb_store)
+ UNWIND_HINT_UNDEFINED
csrwr t0, EXCEPTION_KS0
csrwr t1, EXCEPTION_KS1
csrwr ra, EXCEPTION_KS2
@@ -346,6 +351,7 @@ nopage_tlb_store:
SYM_CODE_END(handle_tlb_store)
SYM_CODE_START(handle_tlb_store_ptw)
+ UNWIND_HINT_UNDEFINED
csrwr t0, LOONGARCH_CSR_KS0
csrwr t1, LOONGARCH_CSR_KS1
la_abs t0, tlb_do_page_fault_1
@@ -353,6 +359,7 @@ SYM_CODE_START(handle_tlb_store_ptw)
SYM_CODE_END(handle_tlb_store_ptw)
SYM_CODE_START(handle_tlb_modify)
+ UNWIND_HINT_UNDEFINED
csrwr t0, EXCEPTION_KS0
csrwr t1, EXCEPTION_KS1
csrwr ra, EXCEPTION_KS2
@@ -500,6 +507,7 @@ nopage_tlb_modify:
SYM_CODE_END(handle_tlb_modify)
SYM_CODE_START(handle_tlb_modify_ptw)
+ UNWIND_HINT_UNDEFINED
csrwr t0, LOONGARCH_CSR_KS0
csrwr t1, LOONGARCH_CSR_KS1
la_abs t0, tlb_do_page_fault_1
@@ -507,6 +515,7 @@ SYM_CODE_START(handle_tlb_modify_ptw)
SYM_CODE_END(handle_tlb_modify_ptw)
SYM_CODE_START(handle_tlb_refill)
+ UNWIND_HINT_UNDEFINED
csrwr t0, LOONGARCH_CSR_TLBRSAVE
csrrd t0, LOONGARCH_CSR_PGD
lddir t0, t0, 3
diff --git a/arch/loongarch/vdso/Makefile b/arch/loongarch/vdso/Makefile
index f597cd08a96b..75c6726382c3 100644
--- a/arch/loongarch/vdso/Makefile
+++ b/arch/loongarch/vdso/Makefile
@@ -4,6 +4,7 @@
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
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 4b3e93cac723..6ffa29585194 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -3,6 +3,7 @@ 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_FINALIZE_INIT if MMU
select ARCH_HAS_CURRENT_STACK_POINTER
@@ -84,12 +85,15 @@ config MMU
config MMU_MOTOROLA
bool
+ select HAVE_PAGE_SIZE_4KB
config MMU_COLDFIRE
+ select HAVE_PAGE_SIZE_8KB
bool
config MMU_SUN3
bool
+ select HAVE_PAGE_SIZE_8KB
depends on MMU && !MMU_MOTOROLA && !MMU_COLDFIRE
config ARCH_SUPPORTS_KEXEC
diff --git a/arch/m68k/Kconfig.cpu b/arch/m68k/Kconfig.cpu
index 9dcf245c9cbf..c777a129768a 100644
--- a/arch/m68k/Kconfig.cpu
+++ b/arch/m68k/Kconfig.cpu
@@ -30,6 +30,7 @@ config COLDFIRE
select GENERIC_CSUM
select GPIOLIB
select HAVE_LEGACY_CLK
+ select HAVE_PAGE_SIZE_8KB if !MMU
endchoice
@@ -45,6 +46,7 @@ config M68000
select GENERIC_CSUM
select CPU_NO_EFFICIENT_FFS
select HAVE_ARCH_HASH
+ select HAVE_PAGE_SIZE_4KB
select LEGACY_TIMER_TICK
help
The Freescale (was Motorola) 68000 CPU is the first generation of
diff --git a/arch/m68k/amiga/config.c b/arch/m68k/amiga/config.c
index 7791673e547b..99718f3dc686 100644
--- a/arch/m68k/amiga/config.c
+++ b/arch/m68k/amiga/config.c
@@ -846,6 +846,6 @@ static void amiga_get_hardware_list(struct seq_file *m)
* The Amiga keyboard driver needs key_maps, but we cannot export it in
* drivers/char/defkeymap.c, as it is autogenerated
*/
-#ifdef CONFIG_HW_CONSOLE
+#ifdef CONFIG_VT
EXPORT_SYMBOL_GPL(key_maps);
#endif
diff --git a/arch/m68k/configs/amiga_defconfig b/arch/m68k/configs/amiga_defconfig
index b4d71fea558f..a6f6607efe79 100644
--- a/arch/m68k/configs/amiga_defconfig
+++ b/arch/m68k/configs/amiga_defconfig
@@ -336,7 +336,6 @@ CONFIG_ATA=y
CONFIG_PATA_GAYLE=y
CONFIG_PATA_BUDDHA=y
CONFIG_MD=y
-CONFIG_MD_LINEAR=m
CONFIG_BLK_DEV_DM=m
CONFIG_DM_UNSTRIPED=m
CONFIG_DM_CRYPT=m
@@ -579,12 +578,10 @@ CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_ADIANTUM=m
CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_CFB=m
CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_KEYWRAP=m
CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_OFB=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_AEGIS128=m
diff --git a/arch/m68k/configs/apollo_defconfig b/arch/m68k/configs/apollo_defconfig
index 682d8cd3dd3c..0ca1f9f930bc 100644
--- a/arch/m68k/configs/apollo_defconfig
+++ b/arch/m68k/configs/apollo_defconfig
@@ -316,7 +316,6 @@ CONFIG_SCSI_SAS_ATTRS=m
CONFIG_ISCSI_TCP=m
CONFIG_ISCSI_BOOT_SYSFS=m
CONFIG_MD=y
-CONFIG_MD_LINEAR=m
CONFIG_BLK_DEV_DM=m
CONFIG_DM_UNSTRIPED=m
CONFIG_DM_CRYPT=m
@@ -536,12 +535,10 @@ CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_ADIANTUM=m
CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_CFB=m
CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_KEYWRAP=m
CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_OFB=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_AEGIS128=m
diff --git a/arch/m68k/configs/atari_defconfig b/arch/m68k/configs/atari_defconfig
index 15259ced8463..be030659d8d7 100644
--- a/arch/m68k/configs/atari_defconfig
+++ b/arch/m68k/configs/atari_defconfig
@@ -331,7 +331,6 @@ CONFIG_ATA=y
# CONFIG_ATA_BMDMA is not set
CONFIG_PATA_FALCON=y
CONFIG_MD=y
-CONFIG_MD_LINEAR=m
CONFIG_BLK_DEV_DM=m
CONFIG_DM_UNSTRIPED=m
CONFIG_DM_CRYPT=m
@@ -556,12 +555,10 @@ CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_ADIANTUM=m
CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_CFB=m
CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_KEYWRAP=m
CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_OFB=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_AEGIS128=m
diff --git a/arch/m68k/configs/bvme6000_defconfig b/arch/m68k/configs/bvme6000_defconfig
index 7395c12caef6..ad8f81fbb630 100644
--- a/arch/m68k/configs/bvme6000_defconfig
+++ b/arch/m68k/configs/bvme6000_defconfig
@@ -314,7 +314,6 @@ CONFIG_ISCSI_TCP=m
CONFIG_ISCSI_BOOT_SYSFS=m
CONFIG_BVME6000_SCSI=y
CONFIG_MD=y
-CONFIG_MD_LINEAR=m
CONFIG_BLK_DEV_DM=m
CONFIG_DM_UNSTRIPED=m
CONFIG_DM_CRYPT=m
@@ -528,12 +527,10 @@ CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_ADIANTUM=m
CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_CFB=m
CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_KEYWRAP=m
CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_OFB=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_AEGIS128=m
diff --git a/arch/m68k/configs/hp300_defconfig b/arch/m68k/configs/hp300_defconfig
index 92506bc7f78d..ff253b6accec 100644
--- a/arch/m68k/configs/hp300_defconfig
+++ b/arch/m68k/configs/hp300_defconfig
@@ -315,7 +315,6 @@ CONFIG_SCSI_SAS_ATTRS=m
CONFIG_ISCSI_TCP=m
CONFIG_ISCSI_BOOT_SYSFS=m
CONFIG_MD=y
-CONFIG_MD_LINEAR=m
CONFIG_BLK_DEV_DM=m
CONFIG_DM_UNSTRIPED=m
CONFIG_DM_CRYPT=m
@@ -538,12 +537,10 @@ CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_ADIANTUM=m
CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_CFB=m
CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_KEYWRAP=m
CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_OFB=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_AEGIS128=m
diff --git a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig
index 144bc8c0d8b5..f92b866620a7 100644
--- a/arch/m68k/configs/mac_defconfig
+++ b/arch/m68k/configs/mac_defconfig
@@ -320,7 +320,6 @@ CONFIG_ATA=y
# CONFIG_ATA_BMDMA is not set
CONFIG_PATA_PLATFORM=y
CONFIG_MD=y
-CONFIG_MD_LINEAR=m
CONFIG_BLK_DEV_DM=m
CONFIG_DM_UNSTRIPED=m
CONFIG_DM_CRYPT=m
@@ -555,12 +554,10 @@ CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_ADIANTUM=m
CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_CFB=m
CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_KEYWRAP=m
CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_OFB=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_AEGIS128=m
diff --git a/arch/m68k/configs/multi_defconfig b/arch/m68k/configs/multi_defconfig
index 07594c729497..bd813beaa8a7 100644
--- a/arch/m68k/configs/multi_defconfig
+++ b/arch/m68k/configs/multi_defconfig
@@ -363,7 +363,6 @@ CONFIG_PATA_GAYLE=y
CONFIG_PATA_BUDDHA=y
CONFIG_PATA_PLATFORM=y
CONFIG_MD=y
-CONFIG_MD_LINEAR=m
CONFIG_BLK_DEV_DM=m
CONFIG_DM_UNSTRIPED=m
CONFIG_DM_CRYPT=m
@@ -641,12 +640,10 @@ CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_ADIANTUM=m
CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_CFB=m
CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_KEYWRAP=m
CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_OFB=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_AEGIS128=m
diff --git a/arch/m68k/configs/mvme147_defconfig b/arch/m68k/configs/mvme147_defconfig
index c34de6c1de20..2237ee0fe433 100644
--- a/arch/m68k/configs/mvme147_defconfig
+++ b/arch/m68k/configs/mvme147_defconfig
@@ -313,7 +313,6 @@ CONFIG_ISCSI_TCP=m
CONFIG_ISCSI_BOOT_SYSFS=m
CONFIG_MVME147_SCSI=y
CONFIG_MD=y
-CONFIG_MD_LINEAR=m
CONFIG_BLK_DEV_DM=m
CONFIG_DM_UNSTRIPED=m
CONFIG_DM_CRYPT=m
@@ -527,12 +526,10 @@ CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_ADIANTUM=m
CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_CFB=m
CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_KEYWRAP=m
CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_OFB=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_AEGIS128=m
diff --git a/arch/m68k/configs/mvme16x_defconfig b/arch/m68k/configs/mvme16x_defconfig
index 83bc029d1f33..afb5aa9c5012 100644
--- a/arch/m68k/configs/mvme16x_defconfig
+++ b/arch/m68k/configs/mvme16x_defconfig
@@ -314,7 +314,6 @@ CONFIG_ISCSI_TCP=m
CONFIG_ISCSI_BOOT_SYSFS=m
CONFIG_MVME16x_SCSI=y
CONFIG_MD=y
-CONFIG_MD_LINEAR=m
CONFIG_BLK_DEV_DM=m
CONFIG_DM_UNSTRIPED=m
CONFIG_DM_CRYPT=m
@@ -528,12 +527,10 @@ CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_ADIANTUM=m
CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_CFB=m
CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_KEYWRAP=m
CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_OFB=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_AEGIS128=m
diff --git a/arch/m68k/configs/q40_defconfig b/arch/m68k/configs/q40_defconfig
index 4f551dac2ed7..e40f7a308966 100644
--- a/arch/m68k/configs/q40_defconfig
+++ b/arch/m68k/configs/q40_defconfig
@@ -320,7 +320,6 @@ CONFIG_ATA=y
# CONFIG_ATA_BMDMA is not set
CONFIG_PATA_FALCON=y
CONFIG_MD=y
-CONFIG_MD_LINEAR=m
CONFIG_BLK_DEV_DM=m
CONFIG_DM_UNSTRIPED=m
CONFIG_DM_CRYPT=m
@@ -545,12 +544,10 @@ CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_ADIANTUM=m
CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_CFB=m
CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_KEYWRAP=m
CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_OFB=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_AEGIS128=m
diff --git a/arch/m68k/configs/sun3_defconfig b/arch/m68k/configs/sun3_defconfig
index b1bf01182bd3..4df397c0395f 100644
--- a/arch/m68k/configs/sun3_defconfig
+++ b/arch/m68k/configs/sun3_defconfig
@@ -310,7 +310,6 @@ CONFIG_ISCSI_TCP=m
CONFIG_ISCSI_BOOT_SYSFS=m
CONFIG_SUN3_SCSI=y
CONFIG_MD=y
-CONFIG_MD_LINEAR=m
CONFIG_BLK_DEV_DM=m
CONFIG_DM_UNSTRIPED=m
CONFIG_DM_CRYPT=m
@@ -526,12 +525,10 @@ CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_ADIANTUM=m
CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_CFB=m
CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_KEYWRAP=m
CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_OFB=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_AEGIS128=m
diff --git a/arch/m68k/configs/sun3x_defconfig b/arch/m68k/configs/sun3x_defconfig
index 5c9a3f71f036..aa7719b3947f 100644
--- a/arch/m68k/configs/sun3x_defconfig
+++ b/arch/m68k/configs/sun3x_defconfig
@@ -311,7 +311,6 @@ CONFIG_ISCSI_TCP=m
CONFIG_ISCSI_BOOT_SYSFS=m
CONFIG_SUN3X_ESP=y
CONFIG_MD=y
-CONFIG_MD_LINEAR=m
CONFIG_BLK_DEV_DM=m
CONFIG_DM_UNSTRIPED=m
CONFIG_DM_CRYPT=m
@@ -526,12 +525,10 @@ CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_ADIANTUM=m
CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_CFB=m
CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_KEYWRAP=m
CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_OFB=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_AEGIS128=m
diff --git a/arch/m68k/emu/nfblock.c b/arch/m68k/emu/nfblock.c
index a708fbd5a844..642fb80c5c4e 100644
--- a/arch/m68k/emu/nfblock.c
+++ b/arch/m68k/emu/nfblock.c
@@ -96,6 +96,9 @@ static const struct block_device_operations nfhd_ops = {
static int __init nfhd_init_one(int id, u32 blocks, u32 bsize)
{
+ struct queue_limits lim = {
+ .logical_block_size = bsize,
+ };
struct nfhd_device *dev;
int dev_id = id - NFHD_DEV_OFFSET;
int err = -ENOMEM;
@@ -117,9 +120,11 @@ static int __init nfhd_init_one(int id, u32 blocks, u32 bsize)
dev->bsize = bsize;
dev->bshift = ffs(bsize) - 10;
- dev->disk = blk_alloc_disk(NUMA_NO_NODE);
- if (!dev->disk)
+ dev->disk = blk_alloc_disk(&lim, NUMA_NO_NODE);
+ if (IS_ERR(dev->disk)) {
+ err = PTR_ERR(dev->disk);
goto free_dev;
+ }
dev->disk->major = major_num;
dev->disk->first_minor = dev_id * 16;
@@ -128,7 +133,6 @@ static int __init nfhd_init_one(int id, u32 blocks, u32 bsize)
dev->disk->private_data = dev;
sprintf(dev->disk->disk_name, "nfhd%u", dev_id);
set_capacity(dev->disk, (sector_t)blocks * (bsize / 512));
- blk_queue_logical_block_size(dev->disk->queue, bsize);
err = add_disk(dev->disk);
if (err)
goto out_cleanup_disk;
diff --git a/arch/m68k/hp300/config.c b/arch/m68k/hp300/config.c
index e4bd6913f50e..1a2739852351 100644
--- a/arch/m68k/hp300/config.c
+++ b/arch/m68k/hp300/config.c
@@ -10,6 +10,7 @@
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/serial_8250.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/console.h>
@@ -67,9 +68,6 @@ static char *hp300_models[] __initdata = {
static char hp300_model_name[13] = "HP9000/";
extern void hp300_reset(void);
-#ifdef CONFIG_SERIAL_8250_CONSOLE
-extern int hp300_setup_serial_console(void) __init;
-#endif
int __init hp300_parse_bootinfo(const struct bi_record *record)
{
@@ -263,7 +261,5 @@ void __init config_hp300(void)
} else {
panic("Unknown HP9000 Model");
}
-#ifdef CONFIG_SERIAL_8250_CONSOLE
hp300_setup_serial_console();
-#endif
}
diff --git a/arch/m68k/include/asm/cachetype.h b/arch/m68k/include/asm/cachetype.h
new file mode 100644
index 000000000000..7fad5d9ab8fe
--- /dev/null
+++ b/arch/m68k/include/asm/cachetype.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_M68K_CACHETYPE_H
+#define __ASM_M68K_CACHETYPE_H
+
+#include <linux/types.h>
+
+#define cpu_dcache_is_aliasing() true
+
+#endif
diff --git a/arch/m68k/include/asm/page.h b/arch/m68k/include/asm/page.h
index a5993ad83ed8..8cfb84b49975 100644
--- a/arch/m68k/include/asm/page.h
+++ b/arch/m68k/include/asm/page.h
@@ -7,11 +7,7 @@
#include <asm/page_offset.h>
/* PAGE_SHIFT determines the page size */
-#if defined(CONFIG_SUN3) || defined(CONFIG_COLDFIRE)
-#define PAGE_SHIFT 13
-#else
-#define PAGE_SHIFT 12
-#endif
+#define PAGE_SHIFT CONFIG_PAGE_SHIFT
#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
#define PAGE_OFFSET (PAGE_OFFSET_RAW)
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index 211f338d6235..f18ec02ddeb2 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -31,6 +31,7 @@ config MICROBLAZE
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_FUNCTION_TRACER
+ select HAVE_PAGE_SIZE_4KB
select HAVE_PCI
select IRQ_DOMAIN
select XILINX_INTC
diff --git a/arch/microblaze/include/asm/page.h b/arch/microblaze/include/asm/page.h
index 86a4ce07c192..8810f4f1c3b0 100644
--- a/arch/microblaze/include/asm/page.h
+++ b/arch/microblaze/include/asm/page.h
@@ -20,7 +20,7 @@
#ifdef __KERNEL__
/* PAGE_SHIFT determines the page size */
-#define PAGE_SHIFT 12
+#define PAGE_SHIFT CONFIG_PAGE_SHIFT
#define PAGE_SIZE (ASM_CONST(1) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
diff --git a/arch/mips/Kbuild b/arch/mips/Kbuild
index e2d623621a00..e901bf554483 100644
--- a/arch/mips/Kbuild
+++ b/arch/mips/Kbuild
@@ -11,6 +11,7 @@ obj- := $(platform-y)
# mips object files
# The object files are linked as core-y files would be linked
+obj-y += generic/
obj-y += kernel/
obj-y += mm/
obj-y += net/
diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms
index a2311c4bce6a..5c145b67d3bf 100644
--- a/arch/mips/Kbuild.platforms
+++ b/arch/mips/Kbuild.platforms
@@ -17,6 +17,7 @@ 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 797ae590ebdb..516dc7022bd7 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -4,6 +4,7 @@ config MIPS
default y
select ARCH_32BIT_OFF_T if !64BIT
select ARCH_BINFMT_ELF_STATE if MIPS_FP_SUPPORT
+ select ARCH_HAS_CPU_CACHE_ALIASING
select ARCH_HAS_CPU_FINALIZE_INIT
select ARCH_HAS_CURRENT_STACK_POINTER if !CC_IS_CLANG || CLANG_VERSION >= 140000
select ARCH_HAS_DEBUG_VIRTUAL if !64BIT
@@ -14,7 +15,7 @@ config MIPS
select ARCH_HAS_STRNCPY_FROM_USER
select ARCH_HAS_STRNLEN_USER
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
- select ARCH_HAS_UBSAN_SANITIZE_ALL
+ select ARCH_HAS_UBSAN
select ARCH_HAS_GCOV_PROFILE_ALL
select ARCH_KEEP_MEMBLOCK
select ARCH_USE_BUILTIN_BSWAP
@@ -81,6 +82,9 @@ config MIPS
select HAVE_LD_DEAD_CODE_DATA_ELIMINATION
select HAVE_MOD_ARCH_SPECIFIC
select HAVE_NMI
+ select HAVE_PAGE_SIZE_4KB if !CPU_LOONGSON2EF && !CPU_LOONGSON64
+ select HAVE_PAGE_SIZE_16KB if !CPU_R3000
+ select HAVE_PAGE_SIZE_64KB if !CPU_R3000
select HAVE_PERF_EVENTS
select HAVE_PERF_REGS
select HAVE_PERF_USER_STACK_DUMP
@@ -109,6 +113,9 @@ config MIPS_FIXUP_BIGPHYS_ADDR
config MIPS_GENERIC
bool
+config MACH_GENERIC_CORE
+ bool
+
config MACH_INGENIC
bool
select SYS_SUPPORTS_32BIT_KERNEL
@@ -145,6 +152,7 @@ config MIPS_GENERIC_KERNEL
select DMA_NONCOHERENT
select HAVE_PCI
select IRQ_MIPS_CPU
+ select MACH_GENERIC_CORE
select MIPS_AUTO_PFN_OFFSET
select MIPS_CPU_SCACHE
select MIPS_GIC
@@ -413,6 +421,7 @@ config MACH_INGENIC_SOC
bool "Ingenic SoC based machines"
select MIPS_GENERIC
select MACH_INGENIC
+ select MACH_GENERIC_CORE
select SYS_SUPPORTS_ZBOOT_UART16550
select CPU_SUPPORTS_CPUFREQ
select MIPS_EXTERNAL_TIMER
@@ -566,6 +575,50 @@ config MACH_PIC32
Microchip PIC32 is a family of general-purpose 32 bit MIPS core
microcontrollers.
+config MACH_EYEQ5
+ bool "Mobileye EyeQ5 SoC"
+ select MACH_GENERIC_CORE
+ select ARM_AMBA
+ select PHYSICAL_START_BOOL
+ select ARCH_SPARSEMEM_DEFAULT if 64BIT
+ select BOOT_RAW
+ select BUILTIN_DTB
+ select CEVT_R4K
+ select CLKSRC_MIPS_GIC
+ select COMMON_CLK
+ select CPU_MIPSR2_IRQ_EI
+ select CPU_MIPSR2_IRQ_VI
+ select CSRC_R4K
+ select DMA_NONCOHERENT
+ select HAVE_PCI
+ select IRQ_MIPS_CPU
+ select MIPS_AUTO_PFN_OFFSET
+ select MIPS_CPU_SCACHE
+ select MIPS_GIC
+ select MIPS_L1_CACHE_SHIFT_7
+ select PCI_DRIVERS_GENERIC
+ select SMP_UP if SMP
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_MIPS64_R6
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_HIGHMEM
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_SUPPORTS_MIPS_CPS
+ select SYS_SUPPORTS_RELOCATABLE
+ select SYS_SUPPORTS_ZBOOT
+ select UHI_BOOT
+ select USB_EHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN
+ select USB_EHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
+ select USB_OHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN
+ select USB_OHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
+ select USB_UHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN
+ 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.
+
+ bool
+
config MACH_NINTENDO64
bool "Nintendo 64 console"
select CEVT_R4K
@@ -599,6 +652,7 @@ config RALINK
config MACH_REALTEK_RTL
bool "Realtek RTL838x/RTL839x based machines"
select MIPS_GENERIC
+ select MACH_GENERIC_CORE
select DMA_NONCOHERENT
select IRQ_MIPS_CPU
select CSRC_R4K
@@ -948,6 +1002,15 @@ config CAVIUM_OCTEON_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.
+
source "arch/mips/alchemy/Kconfig"
source "arch/mips/ath25/Kconfig"
source "arch/mips/ath79/Kconfig"
@@ -1250,6 +1313,7 @@ config CPU_LOONGSON64
select CPU_SUPPORTS_HIGHMEM
select CPU_SUPPORTS_HUGEPAGES
select CPU_SUPPORTS_MSA
+ select CPU_SUPPORTS_VZ
select CPU_DIEI_BROKEN if !LOONGSON3_ENHANCEMENT
select CPU_MIPSR2_IRQ_VI
select DMA_NONCOHERENT
@@ -1261,7 +1325,6 @@ config CPU_LOONGSON64
select MIPS_FP_SUPPORT
select GPIOLIB
select SWIOTLB
- select HAVE_KVM
help
The Loongson GSx64(GS264/GS464/GS464E/GS464V) series of processor
cores implements the MIPS64R2 instruction set with many extensions,
@@ -1269,44 +1332,6 @@ config CPU_LOONGSON64
3B1000, 3B1500, 3A2000, 3A3000 and 3A4000) processors. However, old
Loongson-2E/2F is not covered here and will be removed in future.
-config LOONGSON3_ENHANCEMENT
- bool "New Loongson-3 CPU Enhancements"
- default n
- depends on CPU_LOONGSON64
- help
- New Loongson-3 cores (since Loongson-3A R2, as opposed to Loongson-3A
- R1, Loongson-3B R1 and Loongson-3B R2) has many enhancements, such as
- FTLB, L1-VCache, EI/DI/Wait/Prefetch instruction, DSP/DSPr2 ASE, User
- Local register, Read-Inhibit/Execute-Inhibit, SFB (Store Fill Buffer),
- Fast TLB refill support, etc.
-
- This option enable those enhancements which are not probed at run
- time. If you want a generic kernel to run on all Loongson 3 machines,
- please say 'N' here. If you want a high-performance kernel to run on
- new Loongson-3 machines only, please say 'Y' here.
-
-config CPU_LOONGSON3_WORKAROUNDS
- bool "Loongson-3 LLSC Workarounds"
- default y if SMP
- depends on CPU_LOONGSON64
- help
- Loongson-3 processors have the llsc issues which require workarounds.
- Without workarounds the system may hang unexpectedly.
-
- Say Y, unless you know what you are doing.
-
-config CPU_LOONGSON3_CPUCFG_EMULATION
- bool "Emulate the CPUCFG instruction on older Loongson cores"
- default y
- depends on CPU_LOONGSON64
- help
- Loongson-3A R4 and newer have the CPUCFG instruction available for
- userland to query CPU capabilities, much like CPUID on x86. This
- option provides emulation of the instruction on older Loongson
- cores, back to Loongson-3A1000.
-
- If unsure, please say Y.
-
config CPU_LOONGSON2E
bool "Loongson 2E"
depends on SYS_HAS_CPU_LOONGSON2E
@@ -1374,7 +1399,6 @@ config CPU_MIPS32_R2
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_HIGHMEM
select CPU_SUPPORTS_MSA
- select HAVE_KVM
help
Choose this option to build a kernel for release 2 or later of the
MIPS32 architecture. Most modern embedded systems with a 32-bit
@@ -1389,7 +1413,7 @@ config CPU_MIPS32_R5
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_HIGHMEM
select CPU_SUPPORTS_MSA
- select HAVE_KVM
+ select CPU_SUPPORTS_VZ
select MIPS_O32_FP64_SUPPORT
help
Choose this option to build a kernel for release 5 or later of the
@@ -1405,7 +1429,7 @@ config CPU_MIPS32_R6
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_HIGHMEM
select CPU_SUPPORTS_MSA
- select HAVE_KVM
+ select CPU_SUPPORTS_VZ
select MIPS_O32_FP64_SUPPORT
help
Choose this option to build a kernel for release 6 or later of the
@@ -1441,7 +1465,6 @@ config CPU_MIPS64_R2
select CPU_SUPPORTS_HIGHMEM
select CPU_SUPPORTS_HUGEPAGES
select CPU_SUPPORTS_MSA
- select HAVE_KVM
help
Choose this option to build a kernel for release 2 or later of the
MIPS64 architecture. Many modern embedded systems with a 64-bit
@@ -1459,7 +1482,7 @@ config CPU_MIPS64_R5
select CPU_SUPPORTS_HUGEPAGES
select CPU_SUPPORTS_MSA
select MIPS_O32_FP64_SUPPORT if 32BIT || MIPS32_O32
- select HAVE_KVM
+ select CPU_SUPPORTS_VZ
help
Choose this option to build a kernel for release 5 or later of the
MIPS64 architecture. This is a intermediate MIPS architecture
@@ -1477,7 +1500,7 @@ config CPU_MIPS64_R6
select CPU_SUPPORTS_HUGEPAGES
select CPU_SUPPORTS_MSA
select MIPS_O32_FP64_SUPPORT if 32BIT || MIPS32_O32
- select HAVE_KVM
+ select CPU_SUPPORTS_VZ
help
Choose this option to build a kernel for release 6 or later of the
MIPS64 architecture. New MIPS processors, starting with the Warrior
@@ -1492,9 +1515,9 @@ config CPU_P5600
select CPU_SUPPORTS_HIGHMEM
select CPU_SUPPORTS_MSA
select CPU_SUPPORTS_CPUFREQ
+ select CPU_SUPPORTS_VZ
select CPU_MIPSR2_IRQ_VI
select CPU_MIPSR2_IRQ_EI
- select HAVE_KVM
select MIPS_O32_FP64_SUPPORT
help
Choose this option to build a kernel for MIPS Warrior P5600 CPU.
@@ -1608,13 +1631,15 @@ config CPU_CAVIUM_OCTEON
depends on SYS_HAS_CPU_CAVIUM_OCTEON
select CPU_HAS_PREFETCH
select CPU_SUPPORTS_64BIT_KERNEL
+ select HAVE_PAGE_SIZE_8KB if !MIPS_VA_BITS_48
+ select HAVE_PAGE_SIZE_32KB if !MIPS_VA_BITS_48
select WEAK_ORDERING
select CPU_SUPPORTS_HIGHMEM
select CPU_SUPPORTS_HUGEPAGES
select USB_EHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
select USB_OHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
select MIPS_L1_CACHE_SHIFT_7
- select HAVE_KVM
+ select CPU_SUPPORTS_VZ
help
The Cavium Octeon processor is a highly integrated chip containing
many ethernet hardware widgets for networking tasks. The processor
@@ -1644,6 +1669,44 @@ config CPU_BMIPS
endchoice
+config LOONGSON3_ENHANCEMENT
+ bool "New Loongson-3 CPU Enhancements"
+ default n
+ depends on CPU_LOONGSON64
+ help
+ New Loongson-3 cores (since Loongson-3A R2, as opposed to Loongson-3A
+ R1, Loongson-3B R1 and Loongson-3B R2) has many enhancements, such as
+ FTLB, L1-VCache, EI/DI/Wait/Prefetch instruction, DSP/DSPr2 ASE, User
+ Local register, Read-Inhibit/Execute-Inhibit, SFB (Store Fill Buffer),
+ Fast TLB refill support, etc.
+
+ This option enable those enhancements which are not probed at run
+ time. If you want a generic kernel to run on all Loongson 3 machines,
+ please say 'N' here. If you want a high-performance kernel to run on
+ new Loongson-3 machines only, please say 'Y' here.
+
+config CPU_LOONGSON3_WORKAROUNDS
+ bool "Loongson-3 LLSC Workarounds"
+ default y if SMP
+ depends on CPU_LOONGSON64
+ help
+ Loongson-3 processors have the llsc issues which require workarounds.
+ Without workarounds the system may hang unexpectedly.
+
+ Say Y, unless you know what you are doing.
+
+config CPU_LOONGSON3_CPUCFG_EMULATION
+ bool "Emulate the CPUCFG instruction on older Loongson cores"
+ default y
+ depends on CPU_LOONGSON64
+ help
+ Loongson-3A R4 and newer have the CPUCFG instruction available for
+ userland to query CPU capabilities, much like CPUID on x86. This
+ option provides emulation of the instruction on older Loongson
+ cores, back to Loongson-3A1000.
+
+ If unsure, please say Y.
+
config CPU_MIPS32_3_5_FEATURES
bool "MIPS32 Release 3.5 Features"
depends on SYS_HAS_CPU_MIPS32_R3_5
@@ -1969,6 +2032,8 @@ config CPU_SUPPORTS_ADDRWINCFG
config CPU_SUPPORTS_HUGEPAGES
bool
depends on !(32BIT && (PHYS_ADDR_T_64BIT || EVA))
+config CPU_SUPPORTS_VZ
+ bool
config MIPS_PGD_C0_CONTEXT
bool
depends on 64BIT
@@ -2029,59 +2094,6 @@ config ZBOOT_LOAD_ADDRESS
This is only used if non-zero.
-choice
- prompt "Kernel page size"
- default PAGE_SIZE_4KB
-
-config PAGE_SIZE_4KB
- bool "4kB"
- depends on !CPU_LOONGSON2EF && !CPU_LOONGSON64
- help
- This option select the standard 4kB Linux page size. On some
- R3000-family processors this is the only available page size. Using
- 4kB page size will minimize memory consumption and is therefore
- recommended for low memory systems.
-
-config PAGE_SIZE_8KB
- bool "8kB"
- depends on CPU_CAVIUM_OCTEON
- depends on !MIPS_VA_BITS_48
- help
- Using 8kB page size will result in higher performance kernel at
- the price of higher memory consumption. This option is available
- only on cnMIPS processors. Note that you will need a suitable Linux
- distribution to support this.
-
-config PAGE_SIZE_16KB
- bool "16kB"
- depends on !CPU_R3000
- help
- Using 16kB page size will result in higher performance kernel at
- the price of higher memory consumption. This option is available on
- all non-R3000 family processors. Note that you will need a suitable
- Linux distribution to support this.
-
-config PAGE_SIZE_32KB
- bool "32kB"
- depends on CPU_CAVIUM_OCTEON
- depends on !MIPS_VA_BITS_48
- help
- Using 32kB page size will result in higher performance kernel at
- the price of higher memory consumption. This option is available
- only on cnMIPS cores. Note that you will need a suitable Linux
- distribution to support this.
-
-config PAGE_SIZE_64KB
- bool "64kB"
- depends on !CPU_R3000
- help
- Using 64kB page size will result in higher performance kernel at
- the price of higher memory consumption. This option is available on
- all non-R3000 family processor. Not that at the time of this
- writing this option is still high experimental.
-
-endchoice
-
config ARCH_FORCE_MAX_ORDER
int "Maximum zone order"
default "13" if MIPS_HUGE_TLB_SUPPORT && PAGE_SIZE_64KB
@@ -2171,7 +2183,8 @@ config CPU_R4K_CACHE_TLB
config MIPS_MT_SMP
bool "MIPS MT SMP support (1 TC on each available VPE)"
default y
- depends on SYS_SUPPORTS_MULTITHREADING && !CPU_MIPSR6 && !CPU_MICROMIPS
+ depends on TARGET_ISA_REV > 0 && TARGET_ISA_REV < 6
+ depends on SYS_SUPPORTS_MULTITHREADING && !CPU_MICROMIPS
select CPU_MIPSR2_IRQ_VI
select CPU_MIPSR2_IRQ_EI
select SYNC_R4K
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index f49807e1f19b..80aecba24892 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -148,10 +148,10 @@ cflags-y += $(call cc-option,-Wa$(comma)-mno-fix-loongson3-llsc,)
#
# CPU-dependent compiler/assembler options for optimization.
#
-cflags-$(CONFIG_CPU_R3000) += -march=r3000
-cflags-$(CONFIG_CPU_R4300) += -march=r4300 -Wa,--trap
-cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap
-cflags-$(CONFIG_CPU_TX49XX) += -march=r4600 -Wa,--trap
+cflags-$(CONFIG_CPU_R3000) += $(call cc-option,-march=r3000,-march=mips1)
+cflags-$(CONFIG_CPU_R4300) += $(call cc-option,-march=r4300,-march=mips3) -Wa,--trap
+cflags-$(CONFIG_CPU_R4X00) += $(call cc-option,-march=r4600,-march=mips3) -Wa,--trap
+cflags-$(CONFIG_CPU_TX49XX) += $(call cc-option,-march=r4600,-march=mips3) -Wa,--trap
cflags-$(CONFIG_CPU_MIPS32_R1) += -march=mips32 -Wa,--trap
cflags-$(CONFIG_CPU_MIPS32_R2) += -march=mips32r2 -Wa,--trap
cflags-$(CONFIG_CPU_MIPS32_R5) += -march=mips32r5 -Wa,--trap -modd-spreg
@@ -160,37 +160,35 @@ cflags-$(CONFIG_CPU_MIPS64_R1) += -march=mips64 -Wa,--trap
cflags-$(CONFIG_CPU_MIPS64_R2) += -march=mips64r2 -Wa,--trap
cflags-$(CONFIG_CPU_MIPS64_R5) += -march=mips64r5 -Wa,--trap
cflags-$(CONFIG_CPU_MIPS64_R6) += -march=mips64r6 -Wa,--trap
-cflags-$(CONFIG_CPU_P5600) += -march=p5600 -Wa,--trap -modd-spreg
-cflags-$(CONFIG_CPU_R5000) += -march=r5000 -Wa,--trap
-cflags-$(CONFIG_CPU_R5500) += $(call cc-option,-march=r5500,-march=r5000) \
+cflags-$(CONFIG_CPU_P5600) += $(call cc-option,-march=p5600,-march=mips32r5) \
+ -Wa,--trap -modd-spreg
+cflags-$(CONFIG_CPU_R5000) += $(call cc-option,-march=r5000,-march=mips4) \
-Wa,--trap
-cflags-$(CONFIG_CPU_NEVADA) += $(call cc-option,-march=rm5200,-march=r5000) \
+cflags-$(CONFIG_CPU_R5500) += $(call cc-option,-march=r5500,-march=mips4) \
-Wa,--trap
-cflags-$(CONFIG_CPU_RM7000) += $(call cc-option,-march=rm7000,-march=r5000) \
+cflags-$(CONFIG_CPU_NEVADA) += $(call cc-option,-march=rm5200,-march=mips4) \
-Wa,--trap
-cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-march=sb1,-march=r5000) \
+cflags-$(CONFIG_CPU_RM7000) += $(call cc-option,-march=rm7000,-march=mips4) \
+ -Wa,--trap
+cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-march=sb1,-march=mips64r1) \
-Wa,--trap
cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-mno-mdmx)
cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-mno-mips3d)
-cflags-$(CONFIG_CPU_R10000) += $(call cc-option,-march=r10000,-march=r8000) \
+cflags-$(CONFIG_CPU_R10000) += $(call cc-option,-march=r10000,-march=mips4) \
-Wa,--trap
-cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += $(call cc-option,-march=octeon) -Wa,--trap
-ifeq (,$(findstring march=octeon, $(cflags-$(CONFIG_CPU_CAVIUM_OCTEON))))
-cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += -Wa,-march=octeon
-endif
+cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += -march=octeon -Wa,--trap
cflags-$(CONFIG_CAVIUM_CN63XXP1) += -Wa,-mfix-cn63xxp1
-cflags-$(CONFIG_CPU_BMIPS) += -march=mips32 -Wa,-mips32 -Wa,--trap
+cflags-$(CONFIG_CPU_BMIPS) += -march=mips32 -Wa,--trap
-cflags-$(CONFIG_CPU_LOONGSON2E) += -march=loongson2e -Wa,--trap
-cflags-$(CONFIG_CPU_LOONGSON2F) += -march=loongson2f -Wa,--trap
+cflags-$(CONFIG_CPU_LOONGSON2E) += \
+ $(call cc-option,-march=loongson2e,-march=mips3) -Wa,--trap
+cflags-$(CONFIG_CPU_LOONGSON2F) += \
+ $(call cc-option,-march=loongson2f,-march=mips3) -Wa,--trap
# Some -march= flags enable MMI instructions, and GCC complains about that
# support being enabled alongside -msoft-float. Thus explicitly disable MMI.
cflags-$(CONFIG_CPU_LOONGSON2EF) += $(call cc-option,-mno-loongson-mmi)
-ifdef CONFIG_CPU_LOONGSON64
-cflags-$(CONFIG_CPU_LOONGSON64) += -Wa,--trap
-cflags-$(CONFIG_CC_IS_GCC) += -march=loongson3a
-cflags-$(CONFIG_CC_IS_CLANG) += -march=mips64r2
-endif
+cflags-$(CONFIG_CPU_LOONGSON64) += \
+ $(call cc-option,-march=loongson3a,-march=mips64r2) -Wa,--trap
cflags-$(CONFIG_CPU_LOONGSON64) += $(call cc-option,-mno-loongson-mmi)
cflags-$(CONFIG_CPU_R4000_WORKAROUNDS) += $(call cc-option,-mfix-r4000,)
@@ -299,7 +297,7 @@ drivers-$(CONFIG_PCI) += arch/mips/pci/
ifdef CONFIG_64BIT
ifndef KBUILD_SYM32
ifeq ($(shell expr $(load-y) \< 0xffffffff80000000), 0)
- KBUILD_SYM32 = y
+ KBUILD_SYM32 = $(call cc-option-yn, -msym32)
endif
endif
diff --git a/arch/mips/alchemy/common/clock.c b/arch/mips/alchemy/common/clock.c
index c01be8c45271..6c8996e20a7d 100644
--- a/arch/mips/alchemy/common/clock.c
+++ b/arch/mips/alchemy/common/clock.c
@@ -771,7 +771,7 @@ static int __init alchemy_clk_init_fgens(int ctype)
}
id.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE;
- a = kzalloc((sizeof(*a)) * 6, GFP_KERNEL);
+ a = kcalloc(6, sizeof(*a), GFP_KERNEL);
if (!a)
return -ENOMEM;
diff --git a/arch/mips/boot/compressed/uart-16550.c b/arch/mips/boot/compressed/uart-16550.c
index 09dcd2c561d9..db618e72a0c4 100644
--- a/arch/mips/boot/compressed/uart-16550.c
+++ b/arch/mips/boot/compressed/uart-16550.c
@@ -8,6 +8,8 @@
#include <asm/addrspace.h>
+#include "decompress.h"
+
#if defined(CONFIG_MACH_LOONGSON64) || defined(CONFIG_MIPS_MALTA)
#define UART_BASE 0x1fd003f8
#define PORT(offset) (CKSEG1ADDR(UART_BASE) + (offset))
diff --git a/arch/mips/boot/compressed/uart-alchemy.c b/arch/mips/boot/compressed/uart-alchemy.c
index 8ec63011e7dc..003967c084b3 100644
--- a/arch/mips/boot/compressed/uart-alchemy.c
+++ b/arch/mips/boot/compressed/uart-alchemy.c
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
#include <asm/mach-au1x00/au1000.h>
+#include "decompress.h"
+
void putc(char c)
{
alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
diff --git a/arch/mips/boot/compressed/uart-prom.c b/arch/mips/boot/compressed/uart-prom.c
index a8a0a32e05d1..5fa3b9945333 100644
--- a/arch/mips/boot/compressed/uart-prom.c
+++ b/arch/mips/boot/compressed/uart-prom.c
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
#include <asm/setup.h>
+#include "decompress.h"
+
void putc(char c)
{
prom_putchar(c);
diff --git a/arch/mips/boot/dts/Makefile b/arch/mips/boot/dts/Makefile
index 928f38a79dff..efff87cb33a9 100644
--- a/arch/mips/boot/dts/Makefile
+++ b/arch/mips/boot/dts/Makefile
@@ -8,6 +8,7 @@ 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/mobileye/Makefile b/arch/mips/boot/dts/mobileye/Makefile
new file mode 100644
index 000000000000..01c01c3aad81
--- /dev/null
+++ b/arch/mips/boot/dts/mobileye/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
+# Copyright 2023 Mobileye Vision Technologies Ltd.
+
+dtb-$(CONFIG_MACH_EYEQ5) += eyeq5-epm5.dtb
diff --git a/arch/mips/boot/dts/mobileye/eyeq5-epm5.dts b/arch/mips/boot/dts/mobileye/eyeq5-epm5.dts
new file mode 100644
index 000000000000..6898b2d8267d
--- /dev/null
+++ b/arch/mips/boot/dts/mobileye/eyeq5-epm5.dts
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Copyright 2023 Mobileye Vision Technologies Ltd.
+ */
+
+/dts-v1/;
+
+#include "eyeq5.dtsi"
+
+/ {
+ compatible = "mobileye,eyeq5-epm5", "mobileye,eyeq5";
+ model = "Mobile EyeQ5 MP5 Evaluation board";
+
+ chosen {
+ stdout-path = "serial2:115200n8";
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x40000000 0x0 0x02000000>,
+ <0x8 0x02000000 0x0 0x7E000000>;
+ };
+};
diff --git a/arch/mips/boot/dts/mobileye/eyeq5-fixed-clocks.dtsi b/arch/mips/boot/dts/mobileye/eyeq5-fixed-clocks.dtsi
new file mode 100644
index 000000000000..78f5533a95c6
--- /dev/null
+++ b/arch/mips/boot/dts/mobileye/eyeq5-fixed-clocks.dtsi
@@ -0,0 +1,292 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Copyright 2023 Mobileye Vision Technologies Ltd.
+ */
+
+/ {
+ /* 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 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <1857210000>;
+ };
+
+/* PLL_CPU derivatives */
+ occ_cpu: occ-cpu {
+ compatible = "fixed-factor-clock";
+ clocks = <&pll_cpu>;
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ };
+ si_css0_ref_clk: si-css0-ref-clk { /* gate ClkRstGen_si_css0_ref */
+ compatible = "fixed-factor-clock";
+ clocks = <&occ_cpu>;
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ };
+ cpc_clk: cpc-clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&si_css0_ref_clk>;
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ };
+ core0_clk: core0-clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&si_css0_ref_clk>;
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ };
+ core1_clk: core1-clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&si_css0_ref_clk>;
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ };
+ core2_clk: core2-clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&si_css0_ref_clk>;
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ };
+ core3_clk: core3-clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&si_css0_ref_clk>;
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ };
+ cm_clk: cm-clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&si_css0_ref_clk>;
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ };
+ mem_clk: mem-clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&si_css0_ref_clk>;
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ };
+ occ_isram: occ-isram {
+ compatible = "fixed-factor-clock";
+ clocks = <&pll_cpu>;
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ };
+ isram_clk: isram-clk { /* gate ClkRstGen_isram */
+ compatible = "fixed-factor-clock";
+ clocks = <&occ_isram>;
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ };
+ occ_dbu: occ-dbu {
+ compatible = "fixed-factor-clock";
+ clocks = <&pll_cpu>;
+ #clock-cells = <0>;
+ clock-div = <10>;
+ clock-mult = <1>;
+ };
+ si_dbu_tp_pclk: si-dbu-tp-pclk { /* gate ClkRstGen_dbu */
+ compatible = "fixed-factor-clock";
+ clocks = <&occ_dbu>;
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ };
+/* PLL_VDI derivatives */
+ occ_vdi: occ-vdi {
+ compatible = "fixed-factor-clock";
+ clocks = <&pll_vdi>;
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ };
+ vdi_clk: vdi-clk { /* gate ClkRstGen_vdi */
+ compatible = "fixed-factor-clock";
+ clocks = <&occ_vdi>;
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ };
+ occ_can_ser: occ-can-ser {
+ compatible = "fixed-factor-clock";
+ clocks = <&pll_vdi>;
+ #clock-cells = <0>;
+ clock-div = <16>;
+ clock-mult = <1>;
+ };
+ can_ser_clk: can-ser-clk { /* gate ClkRstGen_can_ser */
+ compatible = "fixed-factor-clock";
+ clocks = <&occ_can_ser>;
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ };
+ i2c_ser_clk: i2c-ser-clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&pll_vdi>;
+ #clock-cells = <0>;
+ clock-div = <20>;
+ clock-mult = <1>;
+ };
+/* PLL_PER derivatives */
+ occ_periph: occ-periph {
+ compatible = "fixed-factor-clock";
+ clocks = <&pll_per>;
+ #clock-cells = <0>;
+ clock-div = <16>;
+ clock-mult = <1>;
+ };
+ periph_clk: periph-clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&occ_periph>;
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ };
+ can_clk: can-clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&occ_periph>;
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ };
+ spi_clk: spi-clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&occ_periph>;
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ };
+ uart_clk: uart-clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&occ_periph>;
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ };
+ i2c_clk: i2c-clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&occ_periph>;
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ clock-output-names = "i2c_clk";
+ };
+ timer_clk: timer-clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&occ_periph>;
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ clock-output-names = "timer_clk";
+ };
+ gpio_clk: gpio-clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&occ_periph>;
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ clock-output-names = "gpio_clk";
+ };
+ emmc_sys_clk: emmc-sys-clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&pll_per>;
+ #clock-cells = <0>;
+ clock-div = <10>;
+ clock-mult = <1>;
+ clock-output-names = "emmc_sys_clk";
+ };
+ ccf_ctrl_clk: ccf-ctrl-clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&pll_per>;
+ #clock-cells = <0>;
+ clock-div = <4>;
+ clock-mult = <1>;
+ clock-output-names = "ccf_ctrl_clk";
+ };
+ occ_mjpeg_core: occ-mjpeg-core {
+ compatible = "fixed-factor-clock";
+ clocks = <&pll_per>;
+ #clock-cells = <0>;
+ clock-div = <2>;
+ clock-mult = <1>;
+ clock-output-names = "occ_mjpeg_core";
+ };
+ hsm_clk: hsm-clk { /* gate ClkRstGen_hsm */
+ compatible = "fixed-factor-clock";
+ clocks = <&occ_mjpeg_core>;
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ clock-output-names = "hsm_clk";
+ };
+ mjpeg_core_clk: mjpeg-core-clk { /* gate ClkRstGen_mjpeg_gen */
+ compatible = "fixed-factor-clock";
+ clocks = <&occ_mjpeg_core>;
+ #clock-cells = <0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ clock-output-names = "mjpeg_core_clk";
+ };
+ fcmu_a_clk: fcmu-a-clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&pll_per>;
+ #clock-cells = <0>;
+ clock-div = <20>;
+ clock-mult = <1>;
+ clock-output-names = "fcmu_a_clk";
+ };
+ occ_pci_sys: occ-pci-sys {
+ compatible = "fixed-factor-clock";
+ clocks = <&pll_per>;
+ #clock-cells = <0>;
+ clock-div = <8>;
+ clock-mult = <1>;
+ clock-output-names = "occ_pci_sys";
+ };
+ pclk: pclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <250000000>; /* 250MHz */
+ };
+ tsu_clk: tsu-clk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <125000000>; /* 125MHz */
+ };
+};
diff --git a/arch/mips/boot/dts/mobileye/eyeq5.dtsi b/arch/mips/boot/dts/mobileye/eyeq5.dtsi
new file mode 100644
index 000000000000..6cc5980e2fa1
--- /dev/null
+++ b/arch/mips/boot/dts/mobileye/eyeq5.dtsi
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
+/*
+* Copyright 2023 Mobileye Vision Technologies Ltd.
+*/
+
+#include <dt-bindings/interrupt-controller/mips-gic.h>
+
+#include "eyeq5-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 = <&core0_clk>;
+ };
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ /* These reserved memory regions are also defined in bootmanager
+ * for configuring inbound translation for BARS, don't change
+ * these without syncing with bootmanager
+ */
+ shmem0_reserved: shmem@804000000 {
+ reg = <0x8 0x04000000 0x0 0x1000000>;
+ };
+ shmem1_reserved: shmem@805000000 {
+ reg = <0x8 0x05000000 0x0 0x1000000>;
+ };
+ pci0_msi_reserved: pci0-msi@806000000 {
+ reg = <0x8 0x06000000 0x0 0x100000>;
+ };
+ pci1_msi_reserved: pci1-msi@806100000 {
+ reg = <0x8 0x06100000 0x0 0x100000>;
+ };
+
+ mini_coredump0_reserved: mini-coredump0@806200000 {
+ reg = <0x8 0x06200000 0x0 0x100000>;
+ };
+ mhm_reserved_0: the-mhm-reserved-0@0 {
+ reg = <0x8 0x00000000 0x0 0x0000800>;
+ };
+ };
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ };
+
+ cpu_intc: interrupt-controller {
+ compatible = "mti,cpu-interrupt-controller";
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ };
+
+ soc: soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+ compatible = "simple-bus";
+
+ uart0: serial@800000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0 0x800000 0x0 0x1000>;
+ reg-io-width = <4>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SHARED 6 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&uart_clk>, <&occ_periph>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+
+ uart1: serial@900000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0 0x900000 0x0 0x1000>;
+ reg-io-width = <4>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SHARED 6 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&uart_clk>, <&occ_periph>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+
+ uart2: serial@a00000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0 0xa00000 0x0 0x1000>;
+ reg-io-width = <4>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SHARED 6 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&uart_clk>, <&occ_periph>;
+ clock-names = "uartclk", "apb_pclk";
+ };
+
+ gic: interrupt-controller@140000 {
+ compatible = "mti,gic";
+ reg = <0x0 0x140000 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 = <&core0_clk>;
+ };
+ };
+ };
+};
diff --git a/arch/mips/boot/dts/ralink/mt7621.dtsi b/arch/mips/boot/dts/ralink/mt7621.dtsi
index 35a10258f235..6e95e6f19a6a 100644
--- a/arch/mips/boot/dts/ralink/mt7621.dtsi
+++ b/arch/mips/boot/dts/ralink/mt7621.dtsi
@@ -115,14 +115,58 @@
compatible = "ns16550a";
reg = <0xc00 0x100>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+
clocks = <&sysc MT7621_CLK_UART1>;
interrupt-parent = <&gic>;
interrupts = <GIC_SHARED 26 IRQ_TYPE_LEVEL_HIGH>;
+ no-loopback-test;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+ };
+
+ serial1: serial@d00 {
+ compatible = "ns16550a";
+ reg = <0xd00 0x100>;
+
+ reg-io-width = <4>;
reg-shift = <2>;
+
+ clocks = <&sysc MT7621_CLK_UART2>;
+
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SHARED 27 IRQ_TYPE_LEVEL_HIGH>;
+
+ no-loopback-test;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins>;
+
+ status = "disabled";
+ };
+
+ serial2: serial@e00 {
+ compatible = "ns16550a";
+ reg = <0xe00 0x100>;
+
reg-io-width = <4>;
+ reg-shift = <2>;
+
+ clocks = <&sysc MT7621_CLK_UART3>;
+
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SHARED 28 IRQ_TYPE_LEVEL_HIGH>;
+
no-loopback-test;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins>;
+
+ status = "disabled";
};
spi0: spi@b00 {
@@ -263,6 +307,9 @@
0x1e1d0700 0x0100>;
reg-names = "mac", "ippc";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
clocks = <&sysc MT7621_CLK_XTAL>;
clock-names = "sys_ck";
diff --git a/arch/mips/configs/eyeq5_defconfig b/arch/mips/configs/eyeq5_defconfig
new file mode 100644
index 000000000000..c35c29a4d479
--- /dev/null
+++ b/arch/mips/configs/eyeq5_defconfig
@@ -0,0 +1,108 @@
+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_MACH_EYEQ5=y
+CONFIG_FIT_IMAGE_FDT_EPM5=y
+CONFIG_PAGE_SIZE_16KB=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_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_PTP_1588_CLOCK is not set
+CONFIG_PINCTRL=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/generic/Makefile b/arch/mips/generic/Makefile
index e37a59bae0a6..56011d738441 100644
--- a/arch/mips/generic/Makefile
+++ b/arch/mips/generic/Makefile
@@ -4,9 +4,9 @@
# Author: Paul Burton <paul.burton@mips.com>
#
-obj-y += init.o
-obj-y += irq.o
-obj-y += proc.o
+obj-$(CONFIG_MACH_GENERIC_CORE) += init.o
+obj-$(CONFIG_MACH_GENERIC_CORE) += irq.o
+obj-$(CONFIG_MACH_GENERIC_CORE) += proc.o
obj-$(CONFIG_YAMON_DT_SHIM) += yamon-dt.o
obj-$(CONFIG_LEGACY_BOARD_SEAD3) += board-sead3.o
diff --git a/arch/mips/include/asm/addrspace.h b/arch/mips/include/asm/addrspace.h
index 59a48c60a065..7e9ef01cb182 100644
--- a/arch/mips/include/asm/addrspace.h
+++ b/arch/mips/include/asm/addrspace.h
@@ -48,6 +48,11 @@
#define KSEGX(a) ((_ACAST32_(a)) & _ACAST32_(0xe0000000))
/*
+ * Gives the size of each kernel segment
+ */
+#define CSEGX_SIZE 0x20000000
+
+/*
* Returns the physical address of a CKSEGx / XKPHYS address
*/
#define CPHYSADDR(a) ((_ACAST32_(a)) & 0x1fffffff)
diff --git a/arch/mips/include/asm/asmmacro.h b/arch/mips/include/asm/asmmacro.h
index 067a635d3bc8..18c2ae58cdf3 100644
--- a/arch/mips/include/asm/asmmacro.h
+++ b/arch/mips/include/asm/asmmacro.h
@@ -216,27 +216,33 @@
* Temporary until all gas have MT ASE support
*/
.macro DMT reg=0
- .word 0x41600bc1 | (\reg << 16)
+ insn_if_mips 0x41600bc1 | (\reg << 16)
+ insn32_if_mm 0x0000057C | (\reg << 21)
.endm
.macro EMT reg=0
- .word 0x41600be1 | (\reg << 16)
+ insn_if_mips 0x41600be1 | (\reg << 16)
+ insn32_if_mm 0x0000257C | (\reg << 21)
.endm
.macro DVPE reg=0
- .word 0x41600001 | (\reg << 16)
+ insn_if_mips 0x41600001 | (\reg << 16)
+ insn32_if_mm 0x0000157C | (\reg << 21)
.endm
.macro EVPE reg=0
- .word 0x41600021 | (\reg << 16)
+ insn_if_mips 0x41600021 | (\reg << 16)
+ insn32_if_mm 0x0000357C | (\reg << 21)
.endm
- .macro MFTR rt=0, rd=0, u=0, sel=0
- .word 0x41000000 | (\rt << 16) | (\rd << 11) | (\u << 5) | (\sel)
+ .macro MFTR rs=0, rt=0, u=0, sel=0
+ insn_if_mips 0x41000000 | (\rt << 16) | (\rs << 11) | (\u << 5) | (\sel)
+ insn32_if_mm 0x0000000E | (\rt << 21) | (\rs << 16) | (\u << 10) | (\sel << 4)
.endm
- .macro MTTR rt=0, rd=0, u=0, sel=0
- .word 0x41800000 | (\rt << 16) | (\rd << 11) | (\u << 5) | (\sel)
+ .macro MTTR rt=0, rs=0, u=0, sel=0
+ insn_if_mips 0x41800000 | (\rt << 16) | (\rs << 11) | (\u << 5) | (\sel)
+ insn32_if_mm 0x00000006 | (\rt << 21) | (\rs << 16) | (\u << 10) | (\sel << 4)
.endm
#ifdef TOOLCHAIN_SUPPORTS_MSA
diff --git a/arch/mips/include/asm/cachetype.h b/arch/mips/include/asm/cachetype.h
new file mode 100644
index 000000000000..9f4ba2fe1155
--- /dev/null
+++ b/arch/mips/include/asm/cachetype.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_MIPS_CACHETYPE_H
+#define __ASM_MIPS_CACHETYPE_H
+
+#include <asm/cpu-features.h>
+
+#define cpu_dcache_is_aliasing() cpu_has_dc_aliases
+
+#endif
diff --git a/arch/mips/include/asm/cdmm.h b/arch/mips/include/asm/cdmm.h
index c06dbf8ba937..81fa99084178 100644
--- a/arch/mips/include/asm/cdmm.h
+++ b/arch/mips/include/asm/cdmm.h
@@ -63,7 +63,7 @@ struct mips_cdmm_driver {
*/
phys_addr_t mips_cdmm_phys_base(void);
-extern struct bus_type mips_cdmm_bustype;
+extern const struct bus_type mips_cdmm_bustype;
void __iomem *mips_cdmm_early_probe(unsigned int dev_type);
#define to_mips_cdmm_device(d) container_of(d, struct mips_cdmm_device, dev)
diff --git a/arch/mips/include/asm/mach-generic/spaces.h b/arch/mips/include/asm/mach-generic/spaces.h
index b247575c5e69..f8783d339fb0 100644
--- a/arch/mips/include/asm/mach-generic/spaces.h
+++ b/arch/mips/include/asm/mach-generic/spaces.h
@@ -49,6 +49,8 @@
#define HIGHMEM_START _AC(0x20000000, UL)
#endif
+#define CKSEG0ADDR_OR_64BIT(x) CKSEG0ADDR(x)
+#define CKSEG1ADDR_OR_64BIT(x) CKSEG1ADDR(x)
#endif /* CONFIG_32BIT */
#ifdef CONFIG_64BIT
@@ -82,6 +84,8 @@
#define TO_CAC(x) (CAC_BASE | ((x) & TO_PHYS_MASK))
#define TO_UNCAC(x) (UNCAC_BASE | ((x) & TO_PHYS_MASK))
+#define CKSEG0ADDR_OR_64BIT(x) TO_CAC(x)
+#define CKSEG1ADDR_OR_64BIT(x) TO_UNCAC(x)
#endif /* CONFIG_64BIT */
/*
diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h
index 23c67c0871b1..c2930a75b7e4 100644
--- a/arch/mips/include/asm/mips-cm.h
+++ b/arch/mips/include/asm/mips-cm.h
@@ -22,16 +22,28 @@ extern void __iomem *mips_gcr_base;
extern void __iomem *mips_cm_l2sync_base;
/**
- * __mips_cm_phys_base - retrieve the physical base address of the CM
+ * mips_cm_phys_base - retrieve the physical base address of the CM
*
* This function returns the physical base address of the Coherence Manager
* global control block, or 0 if no Coherence Manager is present. It provides
* a default implementation which reads the CMGCRBase register where available,
* and may be overridden by platforms which determine this address in a
- * different way by defining a function with the same prototype except for the
- * name mips_cm_phys_base (without underscores).
+ * different way by defining a function with the same prototype.
*/
-extern phys_addr_t __mips_cm_phys_base(void);
+extern phys_addr_t mips_cm_phys_base(void);
+
+/**
+ * mips_cm_l2sync_phys_base - retrieve the physical base address of the CM
+ * L2-sync region
+ *
+ * This function returns the physical base address of the Coherence Manager
+ * L2-cache only region. It provides a default implementation which reads the
+ * CMGCRL2OnlySyncBase register where available or returns a 4K region just
+ * behind the CM GCR base address. It may be overridden by platforms which
+ * determine this address in a different way by defining a function with the
+ * same prototype.
+ */
+extern phys_addr_t mips_cm_l2sync_phys_base(void);
/*
* mips_cm_is64 - determine CM register width
@@ -311,6 +323,7 @@ GCR_CX_ACCESSOR_RW(32, 0x018, other)
/* GCR_Cx_RESET_BASE - Configure where powered up cores will fetch from */
GCR_CX_ACCESSOR_RW(32, 0x020, reset_base)
#define CM_GCR_Cx_RESET_BASE_BEVEXCBASE GENMASK(31, 12)
+#define CM_GCR_Cx_RESET_BASE_MODE BIT(1)
/* GCR_Cx_ID - Identify the current core */
GCR_CX_ACCESSOR_RO(32, 0x028, id)
diff --git a/arch/mips/include/asm/mips_mt.h b/arch/mips/include/asm/mips_mt.h
index b444523ecd50..28917f1582b3 100644
--- a/arch/mips/include/asm/mips_mt.h
+++ b/arch/mips/include/asm/mips_mt.h
@@ -26,6 +26,6 @@ static inline void mips_mt_set_cpuoptions(void) { }
#endif
struct class;
-extern struct class *mt_class;
+extern const struct class mt_class;
#endif /* __ASM_MIPS_MT_H */
diff --git a/arch/mips/include/asm/mipsmtregs.h b/arch/mips/include/asm/mipsmtregs.h
index a8d67c2f4f7b..30e86861c206 100644
--- a/arch/mips/include/asm/mipsmtregs.h
+++ b/arch/mips/include/asm/mipsmtregs.h
@@ -189,19 +189,24 @@ static inline unsigned core_nvpes(void)
return ((conf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;
}
+#define _ASM_SET_DVPE \
+ _ASM_MACRO_1R(dvpe, rt, \
+ _ASM_INSN_IF_MIPS(0x41600001 | __rt << 16) \
+ _ASM_INSN32_IF_MM(0x0000157C | __rt << 21))
+#define _ASM_UNSET_DVPE ".purgem dvpe\n\t"
+
static inline unsigned int dvpe(void)
{
int res = 0;
__asm__ __volatile__(
- " .set push \n"
- " .set noreorder \n"
- " .set noat \n"
- " .set mips32r2 \n"
- " .word 0x41610001 # dvpe $1 \n"
- " move %0, $1 \n"
- " ehb \n"
- " .set pop \n"
+ " .set push \n"
+ " .set "MIPS_ISA_LEVEL" \n"
+ _ASM_SET_DVPE
+ " dvpe %0 \n"
+ " ehb \n"
+ _ASM_UNSET_DVPE
+ " .set pop \n"
: "=r" (res));
instruction_hazard();
@@ -209,16 +214,22 @@ static inline unsigned int dvpe(void)
return res;
}
+#define _ASM_SET_EVPE \
+ _ASM_MACRO_1R(evpe, rt, \
+ _ASM_INSN_IF_MIPS(0x41600021 | __rt << 16) \
+ _ASM_INSN32_IF_MM(0x0000357C | __rt << 21))
+#define _ASM_UNSET_EVPE ".purgem evpe\n\t"
+
static inline void __raw_evpe(void)
{
__asm__ __volatile__(
- " .set push \n"
- " .set noreorder \n"
- " .set noat \n"
- " .set mips32r2 \n"
- " .word 0x41600021 # evpe \n"
- " ehb \n"
- " .set pop \n");
+ " .set push \n"
+ " .set "MIPS_ISA_LEVEL" \n"
+ _ASM_SET_EVPE
+ " evpe $0 \n"
+ " ehb \n"
+ _ASM_UNSET_EVPE
+ " .set pop \n");
}
/* Enable virtual processor execution if previous suggested it should be.
@@ -232,18 +243,24 @@ static inline void evpe(int previous)
__raw_evpe();
}
+#define _ASM_SET_DMT \
+ _ASM_MACRO_1R(dmt, rt, \
+ _ASM_INSN_IF_MIPS(0x41600bc1 | __rt << 16) \
+ _ASM_INSN32_IF_MM(0x0000057C | __rt << 21))
+#define _ASM_UNSET_DMT ".purgem dmt\n\t"
+
static inline unsigned int dmt(void)
{
int res;
__asm__ __volatile__(
- " .set push \n"
- " .set mips32r2 \n"
- " .set noat \n"
- " .word 0x41610BC1 # dmt $1 \n"
- " ehb \n"
- " move %0, $1 \n"
- " .set pop \n"
+ " .set push \n"
+ " .set "MIPS_ISA_LEVEL" \n"
+ _ASM_SET_DMT
+ " dmt %0 \n"
+ " ehb \n"
+ _ASM_UNSET_DMT
+ " .set pop \n"
: "=r" (res));
instruction_hazard();
@@ -251,14 +268,21 @@ static inline unsigned int dmt(void)
return res;
}
+#define _ASM_SET_EMT \
+ _ASM_MACRO_1R(emt, rt, \
+ _ASM_INSN_IF_MIPS(0x41600be1 | __rt << 16) \
+ _ASM_INSN32_IF_MM(0x0000257C | __rt << 21))
+#define _ASM_UNSET_EMT ".purgem emt\n\t"
+
static inline void __raw_emt(void)
{
__asm__ __volatile__(
- " .set push \n"
- " .set noreorder \n"
- " .set mips32r2 \n"
- " .word 0x41600be1 # emt \n"
- " ehb \n"
+ " .set push \n"
+ " .set "MIPS_ISA_LEVEL" \n"
+ _ASM_SET_EMT
+ " emt $0 \n"
+ _ASM_UNSET_EMT
+ " ehb \n"
" .set pop");
}
@@ -276,41 +300,55 @@ static inline void emt(int previous)
static inline void ehb(void)
{
__asm__ __volatile__(
- " .set push \n"
- " .set mips32r2 \n"
- " ehb \n"
- " .set pop \n");
+ " .set push \n"
+ " .set "MIPS_ISA_LEVEL" \n"
+ " ehb \n"
+ " .set pop \n");
}
-#define mftc0(rt,sel) \
+#define _ASM_SET_MFTC0 \
+ _ASM_MACRO_2R_1S(mftc0, rs, rt, sel, \
+ _ASM_INSN_IF_MIPS(0x41000000 | __rt << 16 | \
+ __rs << 11 | \\sel) \
+ _ASM_INSN32_IF_MM(0x0000000E | __rt << 21 | \
+ __rs << 16 | \\sel << 4))
+#define _ASM_UNSET_MFTC0 ".purgem mftc0\n\t"
+
+#define mftc0(rt, sel) \
({ \
- unsigned long __res; \
+ unsigned long __res; \
\
__asm__ __volatile__( \
- " .set push \n" \
- " .set mips32r2 \n" \
- " .set noat \n" \
- " # mftc0 $1, $" #rt ", " #sel " \n" \
- " .word 0x41000800 | (" #rt " << 16) | " #sel " \n" \
- " move %0, $1 \n" \
- " .set pop \n" \
+ " .set push \n" \
+ " .set "MIPS_ISA_LEVEL" \n" \
+ _ASM_SET_MFTC0 \
+ " mftc0 $1, " #rt ", " #sel " \n" \
+ _ASM_UNSET_MFTC0 \
+ " .set pop \n" \
: "=r" (__res)); \
\
__res; \
})
+#define _ASM_SET_MFTGPR \
+ _ASM_MACRO_2R(mftgpr, rs, rt, \
+ _ASM_INSN_IF_MIPS(0x41000020 | __rt << 16 | \
+ __rs << 11) \
+ _ASM_INSN32_IF_MM(0x0000040E | __rt << 21 | \
+ __rs << 16))
+#define _ASM_UNSET_MFTGPR ".purgem mftgpr\n\t"
+
#define mftgpr(rt) \
({ \
unsigned long __res; \
\
__asm__ __volatile__( \
- " .set push \n" \
- " .set noat \n" \
- " .set mips32r2 \n" \
- " # mftgpr $1," #rt " \n" \
- " .word 0x41000820 | (" #rt " << 16) \n" \
- " move %0, $1 \n" \
- " .set pop \n" \
+ " .set push \n" \
+ " .set "MIPS_ISA_LEVEL" \n" \
+ _ASM_SET_MFTGPR \
+ " mftgpr %0," #rt " \n" \
+ _ASM_UNSET_MFTGPR \
+ " .set pop \n" \
: "=r" (__res)); \
\
__res; \
@@ -321,35 +359,49 @@ static inline void ehb(void)
unsigned long __res; \
\
__asm__ __volatile__( \
- " mftr %0, " #rt ", " #u ", " #sel " \n" \
+ " mftr %0, " #rt ", " #u ", " #sel " \n" \
: "=r" (__res)); \
\
__res; \
})
-#define mttgpr(rd,v) \
+#define _ASM_SET_MTTGPR \
+ _ASM_MACRO_2R(mttgpr, rt, rs, \
+ _ASM_INSN_IF_MIPS(0x41800020 | __rt << 16 | \
+ __rs << 11) \
+ _ASM_INSN32_IF_MM(0x00000406 | __rt << 21 | \
+ __rs << 16))
+#define _ASM_UNSET_MTTGPR ".purgem mttgpr\n\t"
+
+#define mttgpr(rs, v) \
do { \
__asm__ __volatile__( \
- " .set push \n" \
- " .set mips32r2 \n" \
- " .set noat \n" \
- " move $1, %0 \n" \
- " # mttgpr $1, " #rd " \n" \
- " .word 0x41810020 | (" #rd " << 11) \n" \
- " .set pop \n" \
+ " .set push \n" \
+ " .set "MIPS_ISA_LEVEL" \n" \
+ _ASM_SET_MTTGPR \
+ " mttgpr %0, " #rs " \n" \
+ _ASM_UNSET_MTTGPR \
+ " .set pop \n" \
: : "r" (v)); \
} while (0)
-#define mttc0(rd, sel, v) \
+#define _ASM_SET_MTTC0 \
+ _ASM_MACRO_2R_1S(mttc0, rt, rs, sel, \
+ _ASM_INSN_IF_MIPS(0x41800000 | __rt << 16 | \
+ __rs << 11 | \\sel) \
+ _ASM_INSN32_IF_MM(0x0000040E | __rt << 21 | \
+ __rs << 16 | \\sel << 4))
+#define _ASM_UNSET_MTTC0 ".purgem mttc0\n\t"
+
+#define mttc0(rs, sel, v) \
({ \
__asm__ __volatile__( \
- " .set push \n" \
- " .set mips32r2 \n" \
- " .set noat \n" \
- " move $1, %0 \n" \
- " # mttc0 %0," #rd ", " #sel " \n" \
- " .word 0x41810000 | (" #rd " << 11) | " #sel " \n" \
- " .set pop \n" \
+ " .set push \n" \
+ " .set "MIPS_ISA_LEVEL" \n" \
+ _ASM_SET_MTTC0 \
+ " mttc0 %0," #rs ", " #sel " \n" \
+ _ASM_UNSET_MTTC0 \
+ " .set pop \n" \
: \
: "r" (v)); \
})
@@ -371,49 +423,49 @@ do { \
/* you *must* set the target tc (settc) before trying to use these */
-#define read_vpe_c0_vpecontrol() mftc0(1, 1)
-#define write_vpe_c0_vpecontrol(val) mttc0(1, 1, val)
-#define read_vpe_c0_vpeconf0() mftc0(1, 2)
-#define write_vpe_c0_vpeconf0(val) mttc0(1, 2, val)
-#define read_vpe_c0_vpeconf1() mftc0(1, 3)
-#define write_vpe_c0_vpeconf1(val) mttc0(1, 3, val)
-#define read_vpe_c0_count() mftc0(9, 0)
-#define write_vpe_c0_count(val) mttc0(9, 0, val)
-#define read_vpe_c0_status() mftc0(12, 0)
-#define write_vpe_c0_status(val) mttc0(12, 0, val)
-#define read_vpe_c0_cause() mftc0(13, 0)
-#define write_vpe_c0_cause(val) mttc0(13, 0, val)
-#define read_vpe_c0_config() mftc0(16, 0)
-#define write_vpe_c0_config(val) mttc0(16, 0, val)
-#define read_vpe_c0_config1() mftc0(16, 1)
-#define write_vpe_c0_config1(val) mttc0(16, 1, val)
-#define read_vpe_c0_config7() mftc0(16, 7)
-#define write_vpe_c0_config7(val) mttc0(16, 7, val)
-#define read_vpe_c0_ebase() mftc0(15, 1)
-#define write_vpe_c0_ebase(val) mttc0(15, 1, val)
-#define write_vpe_c0_compare(val) mttc0(11, 0, val)
-#define read_vpe_c0_badvaddr() mftc0(8, 0)
-#define read_vpe_c0_epc() mftc0(14, 0)
-#define write_vpe_c0_epc(val) mttc0(14, 0, val)
+#define read_vpe_c0_vpecontrol() mftc0($1, 1)
+#define write_vpe_c0_vpecontrol(val) mttc0($1, 1, val)
+#define read_vpe_c0_vpeconf0() mftc0($1, 2)
+#define write_vpe_c0_vpeconf0(val) mttc0($1, 2, val)
+#define read_vpe_c0_vpeconf1() mftc0($1, 3)
+#define write_vpe_c0_vpeconf1(val) mttc0($1, 3, val)
+#define read_vpe_c0_count() mftc0($9, 0)
+#define write_vpe_c0_count(val) mttc0($9, 0, val)
+#define read_vpe_c0_status() mftc0($12, 0)
+#define write_vpe_c0_status(val) mttc0($12, 0, val)
+#define read_vpe_c0_cause() mftc0($13, 0)
+#define write_vpe_c0_cause(val) mttc0($13, 0, val)
+#define read_vpe_c0_config() mftc0($16, 0)
+#define write_vpe_c0_config(val) mttc0($16, 0, val)
+#define read_vpe_c0_config1() mftc0($16, 1)
+#define write_vpe_c0_config1(val) mttc0($16, 1, val)
+#define read_vpe_c0_config7() mftc0($16, 7)
+#define write_vpe_c0_config7(val) mttc0($16, 7, val)
+#define read_vpe_c0_ebase() mftc0($15, 1)
+#define write_vpe_c0_ebase(val) mttc0($15, 1, val)
+#define write_vpe_c0_compare(val) mttc0($11, 0, val)
+#define read_vpe_c0_badvaddr() mftc0($8, 0)
+#define read_vpe_c0_epc() mftc0($14, 0)
+#define write_vpe_c0_epc(val) mttc0($14, 0, val)
/* TC */
-#define read_tc_c0_tcstatus() mftc0(2, 1)
-#define write_tc_c0_tcstatus(val) mttc0(2, 1, val)
-#define read_tc_c0_tcbind() mftc0(2, 2)
-#define write_tc_c0_tcbind(val) mttc0(2, 2, val)
-#define read_tc_c0_tcrestart() mftc0(2, 3)
-#define write_tc_c0_tcrestart(val) mttc0(2, 3, val)
-#define read_tc_c0_tchalt() mftc0(2, 4)
-#define write_tc_c0_tchalt(val) mttc0(2, 4, val)
-#define read_tc_c0_tccontext() mftc0(2, 5)
-#define write_tc_c0_tccontext(val) mttc0(2, 5, val)
+#define read_tc_c0_tcstatus() mftc0($2, 1)
+#define write_tc_c0_tcstatus(val) mttc0($2, 1, val)
+#define read_tc_c0_tcbind() mftc0($2, 2)
+#define write_tc_c0_tcbind(val) mttc0($2, 2, val)
+#define read_tc_c0_tcrestart() mftc0($2, 3)
+#define write_tc_c0_tcrestart(val) mttc0($2, 3, val)
+#define read_tc_c0_tchalt() mftc0($2, 4)
+#define write_tc_c0_tchalt(val) mttc0($2, 4, val)
+#define read_tc_c0_tccontext() mftc0($2, 5)
+#define write_tc_c0_tccontext(val) mttc0($2, 5, val)
/* GPR */
-#define read_tc_gpr_sp() mftgpr(29)
-#define write_tc_gpr_sp(val) mttgpr(29, val)
-#define read_tc_gpr_gp() mftgpr(28)
-#define write_tc_gpr_gp(val) mttgpr(28, val)
+#define read_tc_gpr_sp() mftgpr($29)
+#define write_tc_gpr_sp(val) mttgpr($29, val)
+#define read_tc_gpr_gp() mftgpr($28)
+#define write_tc_gpr_gp(val) mttgpr($28, val)
__BUILD_SET_C0(mvpcontrol)
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index ec58cb76d076..3c6ddc0c2c7a 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -42,59 +42,198 @@
/*
* Coprocessor 0 register names
+ *
+ * CP0_REGISTER variant is meant to be used in assembly code, C0_REGISTER
+ * variant is meant to be used in C (uasm) code.
*/
-#define CP0_INDEX $0
-#define CP0_RANDOM $1
-#define CP0_ENTRYLO0 $2
-#define CP0_ENTRYLO1 $3
-#define CP0_CONF $3
-#define CP0_GLOBALNUMBER $3, 1
-#define CP0_CONTEXT $4
-#define CP0_PAGEMASK $5
-#define CP0_PAGEGRAIN $5, 1
-#define CP0_SEGCTL0 $5, 2
-#define CP0_SEGCTL1 $5, 3
-#define CP0_SEGCTL2 $5, 4
-#define CP0_WIRED $6
-#define CP0_INFO $7
-#define CP0_HWRENA $7
-#define CP0_BADVADDR $8
-#define CP0_BADINSTR $8, 1
-#define CP0_COUNT $9
-#define CP0_ENTRYHI $10
-#define CP0_GUESTCTL1 $10, 4
-#define CP0_GUESTCTL2 $10, 5
-#define CP0_GUESTCTL3 $10, 6
-#define CP0_COMPARE $11
-#define CP0_GUESTCTL0EXT $11, 4
-#define CP0_STATUS $12
-#define CP0_GUESTCTL0 $12, 6
-#define CP0_GTOFFSET $12, 7
-#define CP0_CAUSE $13
-#define CP0_EPC $14
-#define CP0_PRID $15
-#define CP0_EBASE $15, 1
-#define CP0_CMGCRBASE $15, 3
-#define CP0_CONFIG $16
-#define CP0_CONFIG3 $16, 3
-#define CP0_CONFIG5 $16, 5
-#define CP0_CONFIG6 $16, 6
-#define CP0_LLADDR $17
-#define CP0_WATCHLO $18
-#define CP0_WATCHHI $19
-#define CP0_XCONTEXT $20
-#define CP0_FRAMEMASK $21
-#define CP0_DIAGNOSTIC $22
-#define CP0_DIAGNOSTIC1 $22, 1
-#define CP0_DEBUG $23
-#define CP0_DEPC $24
-#define CP0_PERFORMANCE $25
-#define CP0_ECC $26
-#define CP0_CACHEERR $27
-#define CP0_TAGLO $28
-#define CP0_TAGHI $29
-#define CP0_ERROREPC $30
-#define CP0_DESAVE $31
+#define CP0_INDEX $0
+#define C0_INDEX 0, 0
+
+#define CP0_RANDOM $1
+#define C0_RANDOM 1, 0
+
+#define CP0_ENTRYLO0 $2
+#define C0_ENTRYLO0 2, 0
+
+#define CP0_ENTRYLO1 $3
+#define C0_ENTRYLO1 3, 0
+
+#define CP0_CONF $3
+#define C0_CONF 3, 0
+
+#define CP0_GLOBALNUMBER $3, 1
+#define C0_GLOBALNUMBER 3, 1
+
+#define CP0_CONTEXT $4
+#define C0_CONTEXT 4, 0
+
+#define CP0_PAGEMASK $5
+#define C0_PAGEMASK 5, 0
+
+#define CP0_PAGEGRAIN $5, 1
+#define C0_PAGEGRAIN 5, 1
+
+#define CP0_SEGCTL0 $5, 2
+#define C0_SEGCTL0 5, 2
+
+#define CP0_SEGCTL1 $5, 3
+#define C0_SEGCTL1 5, 3
+
+#define CP0_SEGCTL2 $5, 4
+#define C0_SEGCTL2 5, 4
+
+#define CP0_PWBASE $5, 5
+#define C0_PWBASE 5, 5
+
+#define CP0_PWFIELD $5, 6
+#define C0_PWFIELD 5, 6
+
+#define CP0_PWCTL $5, 7
+#define C0_PWCTL 5, 7
+
+#define CP0_WIRED $6
+#define C0_WIRED 6, 0
+
+#define CP0_INFO $7
+#define C0_INFO 7, 0
+
+#define CP0_HWRENA $7
+#define C0_HWRENA 7, 0
+
+#define CP0_BADVADDR $8
+#define C0_BADVADDR 8, 0
+
+#define CP0_BADINSTR $8, 1
+#define C0_BADINSTR 8, 1
+
+#define CP0_BADINSTRP $8, 2
+#define C0_BADINSTRP 8, 2
+
+#define CP0_COUNT $9
+#define C0_COUNT 9, 0
+
+#define CP0_PGD $9, 7
+#define C0_PGD 9, 7
+
+#define CP0_ENTRYHI $10
+#define C0_ENTRYHI 10, 0
+
+#define CP0_GUESTCTL1 $10, 4
+#define C0_GUESTCTL1 10, 5
+
+#define CP0_GUESTCTL2 $10, 5
+#define C0_GUESTCTL2 10, 5
+
+#define CP0_GUESTCTL3 $10, 6
+#define C0_GUESTCTL3 10, 6
+
+#define CP0_COMPARE $11
+#define C0_COMPARE 11, 0
+
+#define CP0_GUESTCTL0EXT $11, 4
+#define C0_GUESTCTL0EXT 11, 4
+
+#define CP0_STATUS $12
+#define C0_STATUS 12, 0
+
+#define CP0_GUESTCTL0 $12, 6
+#define C0_GUESTCTL0 12, 6
+
+#define CP0_GTOFFSET $12, 7
+#define C0_GTOFFSET 12, 7
+
+#define CP0_CAUSE $13
+#define C0_CAUSE 13, 0
+
+#define CP0_EPC $14
+#define C0_EPC 14, 0
+
+#define CP0_PRID $15
+#define C0_PRID 15, 0
+
+#define CP0_EBASE $15, 1
+#define C0_EBASE 15, 1
+
+#define CP0_CMGCRBASE $15, 3
+#define C0_CMGCRBASE 15, 3
+
+#define CP0_CONFIG $16
+#define C0_CONFIG 16, 0
+
+#define CP0_CONFIG1 $16, 1
+#define C0_CONFIG1 16, 1
+
+#define CP0_CONFIG2 $16, 2
+#define C0_CONFIG2 16, 2
+
+#define CP0_CONFIG3 $16, 3
+#define C0_CONFIG3 16, 3
+
+#define CP0_CONFIG4 $16, 4
+#define C0_CONFIG4 16, 4
+
+#define CP0_CONFIG5 $16, 5
+#define C0_CONFIG5 16, 5
+
+#define CP0_CONFIG6 $16, 6
+#define C0_CONFIG6 16, 6
+
+#define CP0_LLADDR $17
+#define C0_LLADDR 17, 0
+
+#define CP0_WATCHLO $18
+#define C0_WATCHLO 18, 0
+
+#define CP0_WATCHHI $19
+#define C0_WATCHHI 19, 0
+
+#define CP0_XCONTEXT $20
+#define C0_XCONTEXT 20, 0
+
+#define CP0_FRAMEMASK $21
+#define C0_FRAMEMASK 21, 0
+
+#define CP0_DIAGNOSTIC $22
+#define C0_DIAGNOSTIC 22, 0
+
+#define CP0_DIAGNOSTIC1 $22, 1
+#define C0_DIAGNOSTIC1 22, 1
+
+#define CP0_DEBUG $23
+#define C0_DEBUG 23, 0
+
+#define CP0_DEPC $24
+#define C0_DEPC 24, 0
+
+#define CP0_PERFORMANCE $25
+#define C0_PERFORMANCE 25, 0
+
+#define CP0_ECC $26
+#define C0_ECC 26, 0
+
+#define CP0_CACHEERR $27
+#define C0_CACHEERR 27, 0
+
+#define CP0_TAGLO $28
+#define C0_TAGLO 28, 0
+
+#define CP0_DTAGLO $28, 2
+#define C0_DTAGLO 28, 2
+
+#define CP0_DDATALO $28, 3
+#define C0_DDATALO 28, 3
+
+#define CP0_STAGLO $28, 4
+#define C0_STAGLO 28, 4
+
+#define CP0_TAGHI $29
+#define C0_TAGHI 29, 0
+
+#define CP0_ERROREPC $30
+#define C0_ERROREPC 30, 0
+
+#define CP0_DESAVE $31
+#define C0_DESAVE 31, 0
/*
* R4640/R4650 cp0 register names. These registers are listed
@@ -291,6 +430,12 @@
#define ST0_DE 0x00010000
#define ST0_CE 0x00020000
+#ifdef CONFIG_64BIT
+#define ST0_KX_IF_64 ST0_KX
+#else
+#define ST0_KX_IF_64 0
+#endif
+
/*
* Setting c0_status.co enables Hit_Writeback and Hit_Writeback_Invalidate
* cacheops in userspace. This bit exists only on RM7000 and RM9000
@@ -1277,11 +1422,13 @@ static inline int mm_insn_16bit(u16 insn)
*/
/* Match an individual register number and assign to \var */
-#define _IFC_REG(n) \
- ".ifc \\r, $" #n "\n\t" \
+#define _IFC_REG_NAME(name, n) \
+ ".ifc \\r, $" #name "\n\t" \
"\\var = " #n "\n\t" \
".endif\n\t"
+#define _IFC_REG(n) _IFC_REG_NAME(n, n)
+
#define _ASM_SET_PARSE_R \
".macro parse_r var r\n\t" \
"\\var = -1\n\t" \
@@ -1293,6 +1440,7 @@ static inline int mm_insn_16bit(u16 insn)
_IFC_REG(20) _IFC_REG(21) _IFC_REG(22) _IFC_REG(23) \
_IFC_REG(24) _IFC_REG(25) _IFC_REG(26) _IFC_REG(27) \
_IFC_REG(28) _IFC_REG(29) _IFC_REG(30) _IFC_REG(31) \
+ _IFC_REG_NAME(sp, 29) _IFC_REG_NAME(fp, 30) \
".iflt \\var\n\t" \
".error \"Unable to parse register name \\r\"\n\t" \
".endif\n\t" \
@@ -1307,6 +1455,15 @@ static inline int mm_insn_16bit(u16 insn)
* the ENC encodings.
*/
+/* Instructions with 1 register operand */
+#define _ASM_MACRO_1R(OP, R1, ENC) \
+ ".macro " #OP " " #R1 "\n\t" \
+ _ASM_SET_PARSE_R \
+ "parse_r __" #R1 ", \\" #R1 "\n\t" \
+ ENC \
+ _ASM_UNSET_PARSE_R \
+ ".endm\n\t"
+
/* Instructions with 1 register operand & 1 immediate operand */
#define _ASM_MACRO_1R1I(OP, R1, I2, ENC) \
".macro " #OP " " #R1 ", " #I2 "\n\t" \
@@ -2078,7 +2235,14 @@ do { \
_ASM_INSN_IF_MIPS(0x4200000c) \
_ASM_INSN32_IF_MM(0x0000517c)
#else /* !TOOLCHAIN_SUPPORTS_VIRT */
-#define _ASM_SET_VIRT ".set\tvirt\n\t"
+#if MIPS_ISA_REV >= 5
+#define _ASM_SET_VIRT_ISA
+#elif defined(CONFIG_64BIT)
+#define _ASM_SET_VIRT_ISA ".set\tmips64r5\n\t"
+#else
+#define _ASM_SET_VIRT_ISA ".set\tmips32r5\n\t"
+#endif
+#define _ASM_SET_VIRT _ASM_SET_VIRT_ISA ".set\tvirt\n\t"
#define _ASM_SET_MFGC0 _ASM_SET_VIRT
#define _ASM_SET_DMFGC0 _ASM_SET_VIRT
#define _ASM_SET_MTGC0 _ASM_SET_VIRT
@@ -2099,7 +2263,6 @@ do { \
({ int __res; \
__asm__ __volatile__( \
".set\tpush\n\t" \
- ".set\tmips32r5\n\t" \
_ASM_SET_MFGC0 \
"mfgc0\t%0, " #source ", %1\n\t" \
_ASM_UNSET_MFGC0 \
@@ -2113,7 +2276,6 @@ do { \
({ unsigned long long __res; \
__asm__ __volatile__( \
".set\tpush\n\t" \
- ".set\tmips64r5\n\t" \
_ASM_SET_DMFGC0 \
"dmfgc0\t%0, " #source ", %1\n\t" \
_ASM_UNSET_DMFGC0 \
@@ -2127,7 +2289,6 @@ do { \
do { \
__asm__ __volatile__( \
".set\tpush\n\t" \
- ".set\tmips32r5\n\t" \
_ASM_SET_MTGC0 \
"mtgc0\t%z0, " #register ", %1\n\t" \
_ASM_UNSET_MTGC0 \
@@ -2140,7 +2301,6 @@ do { \
do { \
__asm__ __volatile__( \
".set\tpush\n\t" \
- ".set\tmips64r5\n\t" \
_ASM_SET_DMTGC0 \
"dmtgc0\t%z0, " #register ", %1\n\t" \
_ASM_UNSET_DMTGC0 \
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h
index ef9585d96f6b..4609cb0326cf 100644
--- a/arch/mips/include/asm/page.h
+++ b/arch/mips/include/asm/page.h
@@ -17,21 +17,7 @@
/*
* PAGE_SHIFT determines the page size
*/
-#ifdef CONFIG_PAGE_SIZE_4KB
-#define PAGE_SHIFT 12
-#endif
-#ifdef CONFIG_PAGE_SIZE_8KB
-#define PAGE_SHIFT 13
-#endif
-#ifdef CONFIG_PAGE_SIZE_16KB
-#define PAGE_SHIFT 14
-#endif
-#ifdef CONFIG_PAGE_SIZE_32KB
-#define PAGE_SHIFT 15
-#endif
-#ifdef CONFIG_PAGE_SIZE_64KB
-#define PAGE_SHIFT 16
-#endif
+#define PAGE_SHIFT CONFIG_PAGE_SHIFT
#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1))
diff --git a/arch/mips/include/asm/regdef.h b/arch/mips/include/asm/regdef.h
index 3c687df1d515..236051364f78 100644
--- a/arch/mips/include/asm/regdef.h
+++ b/arch/mips/include/asm/regdef.h
@@ -17,6 +17,96 @@
#if _MIPS_SIM == _MIPS_SIM_ABI32
/*
+ * General purpose register numbers for 32 bit ABI
+ */
+#define GPR_ZERO 0 /* wired zero */
+#define GPR_AT 1 /* assembler temp */
+#define GPR_V0 2 /* return value */
+#define GPR_V1 3
+#define GPR_A0 4 /* argument registers */
+#define GPR_A1 5
+#define GPR_A2 6
+#define GPR_A3 7
+#define GPR_T0 8 /* caller saved */
+#define GPR_T1 9
+#define GPR_T2 10
+#define GPR_T3 11
+#define GPR_T4 12
+#define GPR_TA0 12
+#define GPR_T5 13
+#define GPR_TA1 13
+#define GPR_T6 14
+#define GPR_TA2 14
+#define GPR_T7 15
+#define GPR_TA3 15
+#define GPR_S0 16 /* callee saved */
+#define GPR_S1 17
+#define GPR_S2 18
+#define GPR_S3 19
+#define GPR_S4 20
+#define GPR_S5 21
+#define GPR_S6 22
+#define GPR_S7 23
+#define GPR_T8 24 /* caller saved */
+#define GPR_T9 25
+#define GPR_JP 25 /* PIC jump register */
+#define GPR_K0 26 /* kernel scratch */
+#define GPR_K1 27
+#define GPR_GP 28 /* global pointer */
+#define GPR_SP 29 /* stack pointer */
+#define GPR_FP 30 /* frame pointer */
+#define GPR_S8 30 /* same like fp! */
+#define GPR_RA 31 /* return address */
+
+#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
+
+#if _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32
+
+#define GPR_ZERO 0 /* wired zero */
+#define GPR_AT 1 /* assembler temp */
+#define GPR_V0 2 /* return value - caller saved */
+#define GPR_V1 3
+#define GPR_A0 4 /* argument registers */
+#define GPR_A1 5
+#define GPR_A2 6
+#define GPR_A3 7
+#define GPR_A4 8 /* arg reg 64 bit; caller saved in 32 bit */
+#define GPR_TA0 8
+#define GPR_A5 9
+#define GPR_TA1 9
+#define GPR_A6 10
+#define GPR_TA2 10
+#define GPR_A7 11
+#define GPR_TA3 11
+#define GPR_T0 12 /* caller saved */
+#define GPR_T1 13
+#define GPR_T2 14
+#define GPR_T3 15
+#define GPR_S0 16 /* callee saved */
+#define GPR_S1 17
+#define GPR_S2 18
+#define GPR_S3 19
+#define GPR_S4 20
+#define GPR_S5 21
+#define GPR_S6 22
+#define GPR_S7 23
+#define GPR_T8 24 /* caller saved */
+#define GPR_T9 25 /* callee address for PIC/temp */
+#define GPR_JP 25 /* PIC jump register */
+#define GPR_K0 26 /* kernel temporary */
+#define GPR_K1 27
+#define GPR_GP 28 /* global pointer - caller saved for PIC */
+#define GPR_SP 29 /* stack pointer */
+#define GPR_FP 30 /* frame pointer */
+#define GPR_S8 30 /* callee saved */
+#define GPR_RA 31 /* return address */
+
+#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32 */
+
+#ifdef __ASSEMBLY__
+#if _MIPS_SIM == _MIPS_SIM_ABI32
+
+/*
* Symbolic register names for 32 bit ABI
*/
#define zero $0 /* wired zero */
@@ -102,5 +192,6 @@
#define ra $31 /* return address */
#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32 */
+#endif /* __ASSEMBLY__ */
#endif /* _ASM_REGDEF_H */
diff --git a/arch/mips/include/asm/smp-cps.h b/arch/mips/include/asm/smp-cps.h
index 22a572b70fe3..ab94e50f62b8 100644
--- a/arch/mips/include/asm/smp-cps.h
+++ b/arch/mips/include/asm/smp-cps.h
@@ -24,7 +24,7 @@ struct core_boot_config {
extern struct core_boot_config *mips_cps_core_bootcfg;
-extern void mips_cps_core_entry(void);
+extern void mips_cps_core_boot(int cca, void __iomem *gcr_base);
extern void mips_cps_core_init(void);
extern void mips_cps_boot_vpes(struct core_boot_config *cfg, unsigned vpe);
@@ -32,7 +32,12 @@ extern void mips_cps_boot_vpes(struct core_boot_config *cfg, unsigned vpe);
extern void mips_cps_pm_save(void);
extern void mips_cps_pm_restore(void);
-extern void *mips_cps_core_entry_patch_end;
+extern void excep_tlbfill(void);
+extern void excep_xtlbfill(void);
+extern void excep_cache(void);
+extern void excep_genex(void);
+extern void excep_intex(void);
+extern void excep_ejtag(void);
#ifdef CONFIG_MIPS_CPS
diff --git a/arch/mips/include/asm/vdso.h b/arch/mips/include/asm/vdso.h
index cc7b516129a8..afb03d45bcd0 100644
--- a/arch/mips/include/asm/vdso.h
+++ b/arch/mips/include/asm/vdso.h
@@ -50,9 +50,4 @@ extern struct mips_vdso_image vdso_image_o32;
extern struct mips_vdso_image vdso_image_n32;
#endif
-union mips_vdso_data {
- struct vdso_data data[CS_BASES];
- u8 page[PAGE_SIZE];
-};
-
#endif /* __ASM_VDSO_H */
diff --git a/arch/mips/include/uapi/asm/kvm.h b/arch/mips/include/uapi/asm/kvm.h
index edcf717c4327..9673dc9cb315 100644
--- a/arch/mips/include/uapi/asm/kvm.h
+++ b/arch/mips/include/uapi/asm/kvm.h
@@ -20,8 +20,6 @@
* Some parts derived from the x86 version of this file.
*/
-#define __KVM_HAVE_READONLY_MEM
-
#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
/*
diff --git a/arch/mips/kernel/cps-vec.S b/arch/mips/kernel/cps-vec.S
index 64ecfdac6580..f876309130ad 100644
--- a/arch/mips/kernel/cps-vec.S
+++ b/arch/mips/kernel/cps-vec.S
@@ -4,6 +4,7 @@
* Author: Paul Burton <paul.burton@mips.com>
*/
+#include <linux/init.h>
#include <asm/addrspace.h>
#include <asm/asm.h>
#include <asm/asm-offsets.h>
@@ -82,39 +83,10 @@
.endm
-.balign 0x1000
-
-LEAF(mips_cps_core_entry)
- /*
- * These first several instructions will be patched by cps_smp_setup to load the
- * CCA to use into register s0 and GCR base address to register s1.
- */
- .rept CPS_ENTRY_PATCH_INSNS
- nop
- .endr
-
- .global mips_cps_core_entry_patch_end
-mips_cps_core_entry_patch_end:
-
- /* Check whether we're here due to an NMI */
- mfc0 k0, CP0_STATUS
- and k0, k0, ST0_NMI
- beqz k0, not_nmi
- nop
-
- /* This is an NMI */
- PTR_LA k0, nmi_handler
- jr k0
- nop
-
-not_nmi:
- /* Setup Cause */
- li t0, CAUSEF_IV
- mtc0 t0, CP0_CAUSE
-
- /* Setup Status */
- li t0, ST0_CU1 | ST0_CU0 | ST0_BEV | STATUS_BITDEPS
- mtc0 t0, CP0_STATUS
+LEAF(mips_cps_core_boot)
+ /* Save CCA and GCR base */
+ move s0, a0
+ move s1, a1
/* We don't know how to do coherence setup on earlier ISA */
#if MIPS_ISA_REV > 0
@@ -178,49 +150,45 @@ not_nmi:
PTR_L sp, VPEBOOTCFG_SP(v1)
jr t1
nop
- END(mips_cps_core_entry)
+ END(mips_cps_core_boot)
-.org 0x200
+ __INIT
LEAF(excep_tlbfill)
DUMP_EXCEP("TLB Fill")
b .
nop
END(excep_tlbfill)
-.org 0x280
LEAF(excep_xtlbfill)
DUMP_EXCEP("XTLB Fill")
b .
nop
END(excep_xtlbfill)
-.org 0x300
LEAF(excep_cache)
DUMP_EXCEP("Cache")
b .
nop
END(excep_cache)
-.org 0x380
LEAF(excep_genex)
DUMP_EXCEP("General")
b .
nop
END(excep_genex)
-.org 0x400
LEAF(excep_intex)
DUMP_EXCEP("Interrupt")
b .
nop
END(excep_intex)
-.org 0x480
LEAF(excep_ejtag)
PTR_LA k0, ejtag_debug_handler
jr k0
nop
END(excep_ejtag)
+ __FINIT
LEAF(mips_cps_core_init)
#ifdef CONFIG_MIPS_MT_SMP
@@ -428,7 +396,7 @@ LEAF(mips_cps_boot_vpes)
/* Calculate a pointer to the VPEs struct vpe_boot_config */
li t0, VPEBOOTCFG_SIZE
mul t0, t0, ta1
- addu t0, t0, ta3
+ PTR_ADDU t0, t0, ta3
/* Set the TC restart PC */
lw t1, VPEBOOTCFG_PC(t0)
@@ -603,10 +571,10 @@ dcache_done:
lw $1, TI_CPU(gp)
sll $1, $1, LONGLOG
PTR_LA \dest, __per_cpu_offset
- addu $1, $1, \dest
+ PTR_ADDU $1, $1, \dest
lw $1, 0($1)
PTR_LA \dest, cps_cpu_state
- addu \dest, \dest, $1
+ PTR_ADDU \dest, \dest, $1
.set pop
.endm
diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c
index 84b3affb9de8..3a115fab5573 100644
--- a/arch/mips/kernel/mips-cm.c
+++ b/arch/mips/kernel/mips-cm.c
@@ -179,7 +179,7 @@ static char *cm3_causes[32] = {
static DEFINE_PER_CPU_ALIGNED(spinlock_t, cm_core_lock);
static DEFINE_PER_CPU_ALIGNED(unsigned long, cm_core_lock_flags);
-phys_addr_t __mips_cm_phys_base(void)
+phys_addr_t __weak mips_cm_phys_base(void)
{
unsigned long cmgcr;
@@ -198,10 +198,7 @@ phys_addr_t __mips_cm_phys_base(void)
return (cmgcr & MIPS_CMGCRF_BASE) << (36 - 32);
}
-phys_addr_t mips_cm_phys_base(void)
- __attribute__((weak, alias("__mips_cm_phys_base")));
-
-static phys_addr_t __mips_cm_l2sync_phys_base(void)
+phys_addr_t __weak mips_cm_l2sync_phys_base(void)
{
u32 base_reg;
@@ -217,9 +214,6 @@ static phys_addr_t __mips_cm_l2sync_phys_base(void)
return mips_cm_phys_base() + MIPS_CM_GCR_SIZE;
}
-phys_addr_t mips_cm_l2sync_phys_base(void)
- __attribute__((weak, alias("__mips_cm_l2sync_phys_base")));
-
static void mips_cm_probe_l2sync(void)
{
unsigned major_rev;
diff --git a/arch/mips/kernel/mips-mt.c b/arch/mips/kernel/mips-mt.c
index c07d64438b5b..c938ba208fc0 100644
--- a/arch/mips/kernel/mips-mt.c
+++ b/arch/mips/kernel/mips-mt.c
@@ -229,19 +229,13 @@ void mips_mt_set_cpuoptions(void)
}
}
-struct class *mt_class;
+const struct class mt_class = {
+ .name = "mt",
+};
static int __init mips_mt_init(void)
{
- struct class *mtc;
-
- mtc = class_create("mt");
- if (IS_ERR(mtc))
- return PTR_ERR(mtc);
-
- mt_class = mtc;
-
- return 0;
+ return class_register(&mt_class);
}
subsys_initcall(mips_mt_init);
diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c
index 9bf60d7d44d3..d09ca77e624d 100644
--- a/arch/mips/kernel/pm-cps.c
+++ b/arch/mips/kernel/pm-cps.c
@@ -18,6 +18,7 @@
#include <asm/mipsmtregs.h>
#include <asm/pm.h>
#include <asm/pm-cps.h>
+#include <asm/regdef.h>
#include <asm/smp-cps.h>
#include <asm/uasm.h>
@@ -69,13 +70,6 @@ DEFINE_PER_CPU_ALIGNED(struct mips_static_suspend_state, cps_cpu_state);
static struct uasm_label labels[32];
static struct uasm_reloc relocs[32];
-enum mips_reg {
- zero, at, v0, v1, a0, a1, a2, a3,
- t0, t1, t2, t3, t4, t5, t6, t7,
- s0, s1, s2, s3, s4, s5, s6, s7,
- t8, t9, k0, k1, gp, sp, fp, ra,
-};
-
bool cps_pm_support_state(enum cps_pm_state state)
{
return test_bit(state, state_support);
@@ -203,13 +197,13 @@ static void cps_gen_cache_routine(u32 **pp, struct uasm_label **pl,
return;
/* Load base address */
- UASM_i_LA(pp, t0, (long)CKSEG0);
+ UASM_i_LA(pp, GPR_T0, (long)CKSEG0);
/* Calculate end address */
if (cache_size < 0x8000)
- uasm_i_addiu(pp, t1, t0, cache_size);
+ uasm_i_addiu(pp, GPR_T1, GPR_T0, cache_size);
else
- UASM_i_LA(pp, t1, (long)(CKSEG0 + cache_size));
+ UASM_i_LA(pp, GPR_T1, (long)(CKSEG0 + cache_size));
/* Start of cache op loop */
uasm_build_label(pl, *pp, lbl);
@@ -217,19 +211,19 @@ static void cps_gen_cache_routine(u32 **pp, struct uasm_label **pl,
/* Generate the cache ops */
for (i = 0; i < unroll_lines; i++) {
if (cpu_has_mips_r6) {
- uasm_i_cache(pp, op, 0, t0);
- uasm_i_addiu(pp, t0, t0, cache->linesz);
+ uasm_i_cache(pp, op, 0, GPR_T0);
+ uasm_i_addiu(pp, GPR_T0, GPR_T0, cache->linesz);
} else {
- uasm_i_cache(pp, op, i * cache->linesz, t0);
+ uasm_i_cache(pp, op, i * cache->linesz, GPR_T0);
}
}
if (!cpu_has_mips_r6)
/* Update the base address */
- uasm_i_addiu(pp, t0, t0, unroll_lines * cache->linesz);
+ uasm_i_addiu(pp, GPR_T0, GPR_T0, unroll_lines * cache->linesz);
/* Loop if we haven't reached the end address yet */
- uasm_il_bne(pp, pr, t0, t1, lbl);
+ uasm_il_bne(pp, pr, GPR_T0, GPR_T1, lbl);
uasm_i_nop(pp);
}
@@ -275,25 +269,25 @@ static int cps_gen_flush_fsb(u32 **pp, struct uasm_label **pl,
*/
/* Preserve perf counter setup */
- uasm_i_mfc0(pp, t2, 25, (perf_counter * 2) + 0); /* PerfCtlN */
- uasm_i_mfc0(pp, t3, 25, (perf_counter * 2) + 1); /* PerfCntN */
+ uasm_i_mfc0(pp, GPR_T2, 25, (perf_counter * 2) + 0); /* PerfCtlN */
+ uasm_i_mfc0(pp, GPR_T3, 25, (perf_counter * 2) + 1); /* PerfCntN */
/* Setup perf counter to count FSB full pipeline stalls */
- uasm_i_addiu(pp, t0, zero, (perf_event << 5) | 0xf);
- uasm_i_mtc0(pp, t0, 25, (perf_counter * 2) + 0); /* PerfCtlN */
+ uasm_i_addiu(pp, GPR_T0, GPR_ZERO, (perf_event << 5) | 0xf);
+ uasm_i_mtc0(pp, GPR_T0, 25, (perf_counter * 2) + 0); /* PerfCtlN */
uasm_i_ehb(pp);
- uasm_i_mtc0(pp, zero, 25, (perf_counter * 2) + 1); /* PerfCntN */
+ uasm_i_mtc0(pp, GPR_ZERO, 25, (perf_counter * 2) + 1); /* PerfCntN */
uasm_i_ehb(pp);
/* Base address for loads */
- UASM_i_LA(pp, t0, (long)CKSEG0);
+ UASM_i_LA(pp, GPR_T0, (long)CKSEG0);
/* Start of clear loop */
uasm_build_label(pl, *pp, lbl);
/* Perform some loads to fill the FSB */
for (i = 0; i < num_loads; i++)
- uasm_i_lw(pp, zero, i * line_size * line_stride, t0);
+ uasm_i_lw(pp, GPR_ZERO, i * line_size * line_stride, GPR_T0);
/*
* Invalidate the new D-cache entries so that the cache will need
@@ -301,9 +295,9 @@ static int cps_gen_flush_fsb(u32 **pp, struct uasm_label **pl,
*/
for (i = 0; i < num_loads; i++) {
uasm_i_cache(pp, Hit_Invalidate_D,
- i * line_size * line_stride, t0);
+ i * line_size * line_stride, GPR_T0);
uasm_i_cache(pp, Hit_Writeback_Inv_SD,
- i * line_size * line_stride, t0);
+ i * line_size * line_stride, GPR_T0);
}
/* Barrier ensuring previous cache invalidates are complete */
@@ -311,16 +305,16 @@ static int cps_gen_flush_fsb(u32 **pp, struct uasm_label **pl,
uasm_i_ehb(pp);
/* Check whether the pipeline stalled due to the FSB being full */
- uasm_i_mfc0(pp, t1, 25, (perf_counter * 2) + 1); /* PerfCntN */
+ uasm_i_mfc0(pp, GPR_T1, 25, (perf_counter * 2) + 1); /* PerfCntN */
/* Loop if it didn't */
- uasm_il_beqz(pp, pr, t1, lbl);
+ uasm_il_beqz(pp, pr, GPR_T1, lbl);
uasm_i_nop(pp);
/* Restore perf counter 1. The count may well now be wrong... */
- uasm_i_mtc0(pp, t2, 25, (perf_counter * 2) + 0); /* PerfCtlN */
+ uasm_i_mtc0(pp, GPR_T2, 25, (perf_counter * 2) + 0); /* PerfCtlN */
uasm_i_ehb(pp);
- uasm_i_mtc0(pp, t3, 25, (perf_counter * 2) + 1); /* PerfCntN */
+ uasm_i_mtc0(pp, GPR_T3, 25, (perf_counter * 2) + 1); /* PerfCntN */
uasm_i_ehb(pp);
return 0;
@@ -330,12 +324,12 @@ static void cps_gen_set_top_bit(u32 **pp, struct uasm_label **pl,
struct uasm_reloc **pr,
unsigned r_addr, int lbl)
{
- uasm_i_lui(pp, t0, uasm_rel_hi(0x80000000));
+ uasm_i_lui(pp, GPR_T0, uasm_rel_hi(0x80000000));
uasm_build_label(pl, *pp, lbl);
- uasm_i_ll(pp, t1, 0, r_addr);
- uasm_i_or(pp, t1, t1, t0);
- uasm_i_sc(pp, t1, 0, r_addr);
- uasm_il_beqz(pp, pr, t1, lbl);
+ uasm_i_ll(pp, GPR_T1, 0, r_addr);
+ uasm_i_or(pp, GPR_T1, GPR_T1, GPR_T0);
+ uasm_i_sc(pp, GPR_T1, 0, r_addr);
+ uasm_il_beqz(pp, pr, GPR_T1, lbl);
uasm_i_nop(pp);
}
@@ -344,9 +338,9 @@ static void *cps_gen_entry_code(unsigned cpu, enum cps_pm_state state)
struct uasm_label *l = labels;
struct uasm_reloc *r = relocs;
u32 *buf, *p;
- const unsigned r_online = a0;
- const unsigned r_nc_count = a1;
- const unsigned r_pcohctl = t7;
+ const unsigned r_online = GPR_A0;
+ const unsigned r_nc_count = GPR_A1;
+ const unsigned r_pcohctl = GPR_T8;
const unsigned max_instrs = 256;
unsigned cpc_cmd;
int err;
@@ -383,8 +377,8 @@ static void *cps_gen_entry_code(unsigned cpu, enum cps_pm_state state)
* with the return address placed in v0 to avoid clobbering
* the ra register before it is saved.
*/
- UASM_i_LA(&p, t0, (long)mips_cps_pm_save);
- uasm_i_jalr(&p, v0, t0);
+ UASM_i_LA(&p, GPR_T0, (long)mips_cps_pm_save);
+ uasm_i_jalr(&p, GPR_V0, GPR_T0);
uasm_i_nop(&p);
}
@@ -399,11 +393,11 @@ static void *cps_gen_entry_code(unsigned cpu, enum cps_pm_state state)
/* Increment ready_count */
uasm_i_sync(&p, __SYNC_mb);
uasm_build_label(&l, p, lbl_incready);
- uasm_i_ll(&p, t1, 0, r_nc_count);
- uasm_i_addiu(&p, t2, t1, 1);
- uasm_i_sc(&p, t2, 0, r_nc_count);
- uasm_il_beqz(&p, &r, t2, lbl_incready);
- uasm_i_addiu(&p, t1, t1, 1);
+ uasm_i_ll(&p, GPR_T1, 0, r_nc_count);
+ uasm_i_addiu(&p, GPR_T2, GPR_T1, 1);
+ uasm_i_sc(&p, GPR_T2, 0, r_nc_count);
+ uasm_il_beqz(&p, &r, GPR_T2, lbl_incready);
+ uasm_i_addiu(&p, GPR_T1, GPR_T1, 1);
/* Barrier ensuring all CPUs see the updated r_nc_count value */
uasm_i_sync(&p, __SYNC_mb);
@@ -412,7 +406,7 @@ static void *cps_gen_entry_code(unsigned cpu, enum cps_pm_state state)
* If this is the last VPE to become ready for non-coherence
* then it should branch below.
*/
- uasm_il_beq(&p, &r, t1, r_online, lbl_disable_coherence);
+ uasm_il_beq(&p, &r, GPR_T1, r_online, lbl_disable_coherence);
uasm_i_nop(&p);
if (state < CPS_PM_POWER_GATED) {
@@ -422,13 +416,13 @@ static void *cps_gen_entry_code(unsigned cpu, enum cps_pm_state state)
* has been disabled before proceeding, which it will do
* by polling for the top bit of ready_count being set.
*/
- uasm_i_addiu(&p, t1, zero, -1);
+ uasm_i_addiu(&p, GPR_T1, GPR_ZERO, -1);
uasm_build_label(&l, p, lbl_poll_cont);
- uasm_i_lw(&p, t0, 0, r_nc_count);
- uasm_il_bltz(&p, &r, t0, lbl_secondary_cont);
+ uasm_i_lw(&p, GPR_T0, 0, r_nc_count);
+ uasm_il_bltz(&p, &r, GPR_T0, lbl_secondary_cont);
uasm_i_ehb(&p);
if (cpu_has_mipsmt)
- uasm_i_yield(&p, zero, t1);
+ uasm_i_yield(&p, GPR_ZERO, GPR_T1);
uasm_il_b(&p, &r, lbl_poll_cont);
uasm_i_nop(&p);
} else {
@@ -438,16 +432,16 @@ static void *cps_gen_entry_code(unsigned cpu, enum cps_pm_state state)
*/
if (cpu_has_mipsmt) {
/* Halt the VPE via C0 tchalt register */
- uasm_i_addiu(&p, t0, zero, TCHALT_H);
- uasm_i_mtc0(&p, t0, 2, 4);
+ uasm_i_addiu(&p, GPR_T0, GPR_ZERO, TCHALT_H);
+ uasm_i_mtc0(&p, GPR_T0, 2, 4);
} else if (cpu_has_vp) {
/* Halt the VP via the CPC VP_STOP register */
unsigned int vpe_id;
vpe_id = cpu_vpe_id(&cpu_data[cpu]);
- uasm_i_addiu(&p, t0, zero, 1 << vpe_id);
- UASM_i_LA(&p, t1, (long)addr_cpc_cl_vp_stop());
- uasm_i_sw(&p, t0, 0, t1);
+ uasm_i_addiu(&p, GPR_T0, GPR_ZERO, 1 << vpe_id);
+ UASM_i_LA(&p, GPR_T1, (long)addr_cpc_cl_vp_stop());
+ uasm_i_sw(&p, GPR_T0, 0, GPR_T1);
} else {
BUG();
}
@@ -482,9 +476,9 @@ static void *cps_gen_entry_code(unsigned cpu, enum cps_pm_state state)
* defined by the interAptiv & proAptiv SUMs as ensuring that the
* operation resulting from the preceding store is complete.
*/
- uasm_i_addiu(&p, t0, zero, 1 << cpu_core(&cpu_data[cpu]));
- uasm_i_sw(&p, t0, 0, r_pcohctl);
- uasm_i_lw(&p, t0, 0, r_pcohctl);
+ uasm_i_addiu(&p, GPR_T0, GPR_ZERO, 1 << cpu_core(&cpu_data[cpu]));
+ uasm_i_sw(&p, GPR_T0, 0, r_pcohctl);
+ uasm_i_lw(&p, GPR_T0, 0, r_pcohctl);
/* Barrier to ensure write to coherence control is complete */
uasm_i_sync(&p, __SYNC_full);
@@ -492,8 +486,8 @@ static void *cps_gen_entry_code(unsigned cpu, enum cps_pm_state state)
}
/* Disable coherence */
- uasm_i_sw(&p, zero, 0, r_pcohctl);
- uasm_i_lw(&p, t0, 0, r_pcohctl);
+ uasm_i_sw(&p, GPR_ZERO, 0, r_pcohctl);
+ uasm_i_lw(&p, GPR_T0, 0, r_pcohctl);
if (state >= CPS_PM_CLOCK_GATED) {
err = cps_gen_flush_fsb(&p, &l, &r, &cpu_data[cpu],
@@ -515,9 +509,9 @@ static void *cps_gen_entry_code(unsigned cpu, enum cps_pm_state state)
}
/* Issue the CPC command */
- UASM_i_LA(&p, t0, (long)addr_cpc_cl_cmd());
- uasm_i_addiu(&p, t1, zero, cpc_cmd);
- uasm_i_sw(&p, t1, 0, t0);
+ UASM_i_LA(&p, GPR_T0, (long)addr_cpc_cl_cmd());
+ uasm_i_addiu(&p, GPR_T1, GPR_ZERO, cpc_cmd);
+ uasm_i_sw(&p, GPR_T1, 0, GPR_T0);
if (state == CPS_PM_POWER_GATED) {
/* If anything goes wrong just hang */
@@ -564,12 +558,12 @@ static void *cps_gen_entry_code(unsigned cpu, enum cps_pm_state state)
* will run this. The first will actually re-enable coherence & the
* rest will just be performing a rather unusual nop.
*/
- uasm_i_addiu(&p, t0, zero, mips_cm_revision() < CM_REV_CM3
+ uasm_i_addiu(&p, GPR_T0, GPR_ZERO, mips_cm_revision() < CM_REV_CM3
? CM_GCR_Cx_COHERENCE_COHDOMAINEN
: CM3_GCR_Cx_COHERENCE_COHEN);
- uasm_i_sw(&p, t0, 0, r_pcohctl);
- uasm_i_lw(&p, t0, 0, r_pcohctl);
+ uasm_i_sw(&p, GPR_T0, 0, r_pcohctl);
+ uasm_i_lw(&p, GPR_T0, 0, r_pcohctl);
/* Barrier to ensure write to coherence control is complete */
uasm_i_sync(&p, __SYNC_full);
@@ -579,11 +573,11 @@ static void *cps_gen_entry_code(unsigned cpu, enum cps_pm_state state)
/* Decrement ready_count */
uasm_build_label(&l, p, lbl_decready);
uasm_i_sync(&p, __SYNC_mb);
- uasm_i_ll(&p, t1, 0, r_nc_count);
- uasm_i_addiu(&p, t2, t1, -1);
- uasm_i_sc(&p, t2, 0, r_nc_count);
- uasm_il_beqz(&p, &r, t2, lbl_decready);
- uasm_i_andi(&p, v0, t1, (1 << fls(smp_num_siblings)) - 1);
+ uasm_i_ll(&p, GPR_T1, 0, r_nc_count);
+ uasm_i_addiu(&p, GPR_T2, GPR_T1, -1);
+ uasm_i_sc(&p, GPR_T2, 0, r_nc_count);
+ uasm_il_beqz(&p, &r, GPR_T2, lbl_decready);
+ uasm_i_andi(&p, GPR_V0, GPR_T1, (1 << fls(smp_num_siblings)) - 1);
/* Barrier ensuring all CPUs see the updated r_nc_count value */
uasm_i_sync(&p, __SYNC_mb);
@@ -612,7 +606,7 @@ static void *cps_gen_entry_code(unsigned cpu, enum cps_pm_state state)
}
/* The core is coherent, time to return to C code */
- uasm_i_jr(&p, ra);
+ uasm_i_jr(&p, GPR_RA);
uasm_i_nop(&p);
gen_done:
diff --git a/arch/mips/kernel/rtlx-mt.c b/arch/mips/kernel/rtlx-mt.c
index 38c6925a1bea..ff7535de42ca 100644
--- a/arch/mips/kernel/rtlx-mt.c
+++ b/arch/mips/kernel/rtlx-mt.c
@@ -95,11 +95,11 @@ int __init rtlx_module_init(void)
atomic_set(&channel_wqs[i].in_open, 0);
mutex_init(&channel_wqs[i].mutex);
- dev = device_create(mt_class, NULL, MKDEV(major, i), NULL,
+ dev = device_create(&mt_class, NULL, MKDEV(major, i), NULL,
"%s%d", RTLX_MODULE_NAME, i);
if (IS_ERR(dev)) {
while (i--)
- device_destroy(mt_class, MKDEV(major, i));
+ device_destroy(&mt_class, MKDEV(major, i));
err = PTR_ERR(dev);
goto out_chrdev;
@@ -127,7 +127,7 @@ int __init rtlx_module_init(void)
out_class:
for (i = 0; i < RTLX_CHANNELS; i++)
- device_destroy(mt_class, MKDEV(major, i));
+ device_destroy(&mt_class, MKDEV(major, i));
out_chrdev:
unregister_chrdev(major, RTLX_MODULE_NAME);
@@ -139,7 +139,7 @@ void __exit rtlx_module_exit(void)
int i;
for (i = 0; i < RTLX_CHANNELS; i++)
- device_destroy(mt_class, MKDEV(major, i));
+ device_destroy(&mt_class, MKDEV(major, i));
unregister_chrdev(major, RTLX_MODULE_NAME);
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 9c30de151597..12a1a4ffb602 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -442,8 +442,6 @@ static void __init mips_reserve_vmcore(void)
#endif
}
-#ifdef CONFIG_KEXEC
-
/* 64M alignment for crash kernel regions */
#define CRASH_ALIGN SZ_64M
#define CRASH_ADDR_MAX SZ_512M
@@ -454,6 +452,9 @@ static void __init mips_parse_crashkernel(void)
unsigned long long crash_size, crash_base;
int ret;
+ if (!IS_ENABLED(CONFIG_CRASH_RESERVE))
+ return;
+
total_mem = memblock_phys_mem_size();
ret = parse_crashkernel(boot_command_line, total_mem,
&crash_size, &crash_base,
@@ -489,6 +490,9 @@ static void __init request_crashkernel(struct resource *res)
{
int ret;
+ if (!IS_ENABLED(CONFIG_CRASH_RESERVE))
+ return;
+
if (crashk_res.start == crashk_res.end)
return;
@@ -498,15 +502,6 @@ static void __init request_crashkernel(struct resource *res)
(unsigned long)(resource_size(&crashk_res) >> 20),
(unsigned long)(crashk_res.start >> 20));
}
-#else /* !defined(CONFIG_KEXEC) */
-static void __init mips_parse_crashkernel(void)
-{
-}
-
-static void __init request_crashkernel(struct resource *res)
-{
-}
-#endif /* !defined(CONFIG_KEXEC) */
static void __init check_kernel_sections_mem(void)
{
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index f6c37d407f36..9cc087dd1c19 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -7,6 +7,7 @@
#include <linux/cpu.h>
#include <linux/delay.h>
#include <linux/io.h>
+#include <linux/memblock.h>
#include <linux/sched/task_stack.h>
#include <linux/sched/hotplug.h>
#include <linux/slab.h>
@@ -20,12 +21,24 @@
#include <asm/mipsregs.h>
#include <asm/pm-cps.h>
#include <asm/r4kcache.h>
+#include <asm/regdef.h>
#include <asm/smp.h>
#include <asm/smp-cps.h>
#include <asm/time.h>
#include <asm/uasm.h>
+#define BEV_VEC_SIZE 0x500
+#define BEV_VEC_ALIGN 0x1000
+
+enum label_id {
+ label_not_nmi = 1,
+};
+
+UASM_L_LA(_not_nmi)
+
static DECLARE_BITMAP(core_power, NR_CPUS);
+static uint32_t core_entry_reg;
+static phys_addr_t cps_vec_pa;
struct core_boot_config *mips_cps_core_bootcfg;
@@ -34,10 +47,100 @@ static unsigned __init core_vpe_count(unsigned int cluster, unsigned core)
return min(smp_max_threads, mips_cps_numvps(cluster, core));
}
+static void __init *mips_cps_build_core_entry(void *addr)
+{
+ extern void (*nmi_handler)(void);
+ u32 *p = addr;
+ u32 val;
+ struct uasm_label labels[2];
+ struct uasm_reloc relocs[2];
+ struct uasm_label *l = labels;
+ struct uasm_reloc *r = relocs;
+
+ memset(labels, 0, sizeof(labels));
+ memset(relocs, 0, sizeof(relocs));
+
+ uasm_i_mfc0(&p, GPR_K0, C0_STATUS);
+ UASM_i_LA(&p, GPR_T9, ST0_NMI);
+ uasm_i_and(&p, GPR_K0, GPR_K0, GPR_T9);
+
+ uasm_il_bnez(&p, &r, GPR_K0, label_not_nmi);
+ uasm_i_nop(&p);
+ UASM_i_LA(&p, GPR_K0, (long)&nmi_handler);
+
+ uasm_l_not_nmi(&l, p);
+
+ val = CAUSEF_IV;
+ uasm_i_lui(&p, GPR_K0, val >> 16);
+ uasm_i_ori(&p, GPR_K0, GPR_K0, val & 0xffff);
+ uasm_i_mtc0(&p, GPR_K0, C0_CAUSE);
+ val = ST0_CU1 | ST0_CU0 | ST0_BEV | ST0_KX_IF_64;
+ uasm_i_lui(&p, GPR_K0, val >> 16);
+ uasm_i_ori(&p, GPR_K0, GPR_K0, val & 0xffff);
+ uasm_i_mtc0(&p, GPR_K0, C0_STATUS);
+ uasm_i_ehb(&p);
+ uasm_i_ori(&p, GPR_A0, 0, read_c0_config() & CONF_CM_CMASK);
+ UASM_i_LA(&p, GPR_A1, (long)mips_gcr_base);
+#if defined(KBUILD_64BIT_SYM32) || defined(CONFIG_32BIT)
+ UASM_i_LA(&p, GPR_T9, CKSEG1ADDR(__pa_symbol(mips_cps_core_boot)));
+#else
+ UASM_i_LA(&p, GPR_T9, TO_UNCAC(__pa_symbol(mips_cps_core_boot)));
+#endif
+ uasm_i_jr(&p, GPR_T9);
+ uasm_i_nop(&p);
+
+ uasm_resolve_relocs(relocs, labels);
+
+ return p;
+}
+
+static int __init allocate_cps_vecs(void)
+{
+ /* Try to allocate in KSEG1 first */
+ cps_vec_pa = memblock_phys_alloc_range(BEV_VEC_SIZE, BEV_VEC_ALIGN,
+ 0x0, CSEGX_SIZE - 1);
+
+ if (cps_vec_pa)
+ core_entry_reg = CKSEG1ADDR(cps_vec_pa) &
+ CM_GCR_Cx_RESET_BASE_BEVEXCBASE;
+
+ if (!cps_vec_pa && mips_cm_is64) {
+ cps_vec_pa = memblock_phys_alloc_range(BEV_VEC_SIZE, BEV_VEC_ALIGN,
+ 0x0, SZ_4G - 1);
+ if (cps_vec_pa)
+ core_entry_reg = (cps_vec_pa & CM_GCR_Cx_RESET_BASE_BEVEXCBASE) |
+ CM_GCR_Cx_RESET_BASE_MODE;
+ }
+
+ if (!cps_vec_pa)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static void __init setup_cps_vecs(void)
+{
+ void *cps_vec;
+
+ cps_vec = (void *)CKSEG1ADDR_OR_64BIT(cps_vec_pa);
+ mips_cps_build_core_entry(cps_vec);
+
+ memcpy(cps_vec + 0x200, &excep_tlbfill, 0x80);
+ memcpy(cps_vec + 0x280, &excep_xtlbfill, 0x80);
+ memcpy(cps_vec + 0x300, &excep_cache, 0x80);
+ memcpy(cps_vec + 0x380, &excep_genex, 0x80);
+ memcpy(cps_vec + 0x400, &excep_intex, 0x80);
+ memcpy(cps_vec + 0x480, &excep_ejtag, 0x80);
+
+ /* Make sure no prefetched data in cache */
+ blast_inv_dcache_range(CKSEG0ADDR_OR_64BIT(cps_vec_pa), CKSEG0ADDR_OR_64BIT(cps_vec_pa) + BEV_VEC_SIZE);
+ bc_inv(CKSEG0ADDR_OR_64BIT(cps_vec_pa), BEV_VEC_SIZE);
+ __sync();
+}
+
static void __init cps_smp_setup(void)
{
unsigned int nclusters, ncores, nvpes, core_vpes;
- unsigned long core_entry;
int cl, c, v;
/* Detect & record VPE topology */
@@ -94,10 +197,11 @@ static void __init cps_smp_setup(void)
/* Make core 0 coherent with everything */
write_gcr_cl_coherence(0xff);
- if (mips_cm_revision() >= CM_REV_CM3) {
- core_entry = CKSEG1ADDR((unsigned long)mips_cps_core_entry);
- write_gcr_bev_base(core_entry);
- }
+ if (allocate_cps_vecs())
+ pr_err("Failed to allocate CPS vectors\n");
+
+ if (core_entry_reg && mips_cm_revision() >= CM_REV_CM3)
+ write_gcr_bev_base(core_entry_reg);
#ifdef CONFIG_MIPS_MT_FPAFF
/* If we have an FPU, enroll ourselves in the FPU-full mask */
@@ -110,10 +214,14 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
{
unsigned ncores, core_vpes, c, cca;
bool cca_unsuitable, cores_limited;
- u32 *entry_code;
mips_mt_set_cpuoptions();
+ if (!core_entry_reg) {
+ pr_err("core_entry address unsuitable, disabling smp-cps\n");
+ goto err_out;
+ }
+
/* Detect whether the CCA is unsuited to multi-core SMP */
cca = read_c0_config() & CONF_CM_CMASK;
switch (cca) {
@@ -145,20 +253,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
(cca_unsuitable && cpu_has_dc_aliases) ? " & " : "",
cpu_has_dc_aliases ? "dcache aliasing" : "");
- /*
- * Patch the start of mips_cps_core_entry to provide:
- *
- * s0 = kseg0 CCA
- */
- entry_code = (u32 *)&mips_cps_core_entry;
- uasm_i_addiu(&entry_code, 16, 0, cca);
- UASM_i_LA(&entry_code, 17, (long)mips_gcr_base);
- BUG_ON((void *)entry_code > (void *)&mips_cps_core_entry_patch_end);
- blast_dcache_range((unsigned long)&mips_cps_core_entry,
- (unsigned long)entry_code);
- bc_wback_inv((unsigned long)&mips_cps_core_entry,
- (void *)entry_code - (void *)&mips_cps_core_entry);
- __sync();
+ setup_cps_vecs();
/* Allocate core boot configuration structs */
ncores = mips_cps_numcores(0);
@@ -213,7 +308,7 @@ static void boot_core(unsigned int core, unsigned int vpe_id)
mips_cm_lock_other(0, core, 0, CM_GCR_Cx_OTHER_BLOCK_LOCAL);
/* Set its reset vector */
- write_gcr_co_reset_base(CKSEG1ADDR((unsigned long)mips_cps_core_entry));
+ write_gcr_co_reset_base(core_entry_reg);
/* Ensure its coherency is disabled */
write_gcr_co_coherence(0);
@@ -290,7 +385,6 @@ static int cps_boot_secondary(int cpu, struct task_struct *idle)
unsigned vpe_id = cpu_vpe_id(&cpu_data[cpu]);
struct core_boot_config *core_cfg = &mips_cps_core_bootcfg[core];
struct vpe_boot_config *vpe_cfg = &core_cfg->vpe_config[vpe_id];
- unsigned long core_entry;
unsigned int remote;
int err;
@@ -314,8 +408,7 @@ static int cps_boot_secondary(int cpu, struct task_struct *idle)
if (cpu_has_vp) {
mips_cm_lock_other(0, core, vpe_id, CM_GCR_Cx_OTHER_BLOCK_LOCAL);
- core_entry = CKSEG1ADDR((unsigned long)mips_cps_core_entry);
- write_gcr_co_reset_base(core_entry);
+ write_gcr_co_reset_base(core_entry_reg);
mips_cm_unlock_other();
}
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index a1c1cb5de913..dc29bd9656b0 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -58,6 +58,7 @@
#include <asm/module.h>
#include <asm/msa.h>
#include <asm/ptrace.h>
+#include <asm/regdef.h>
#include <asm/sections.h>
#include <asm/siginfo.h>
#include <asm/tlbdebug.h>
@@ -2041,13 +2042,12 @@ void __init *set_except_vector(int n, void *addr)
unsigned long jump_mask = ~((1 << 28) - 1);
#endif
u32 *buf = (u32 *)(ebase + 0x200);
- unsigned int k0 = 26;
if ((handler & jump_mask) == ((ebase + 0x200) & jump_mask)) {
uasm_i_j(&buf, handler & ~jump_mask);
uasm_i_nop(&buf);
} else {
- UASM_i_LA(&buf, k0, handler);
- uasm_i_jr(&buf, k0);
+ UASM_i_LA(&buf, GPR_K0, handler);
+ uasm_i_jr(&buf, GPR_K0);
uasm_i_nop(&buf);
}
local_flush_icache_range(ebase + 0x200, (unsigned long)buf);
@@ -2299,7 +2299,7 @@ static const char panic_null_cerr[] =
void set_uncached_handler(unsigned long offset, void *addr,
unsigned long size)
{
- unsigned long uncached_ebase = CKSEG1ADDR(ebase);
+ unsigned long uncached_ebase = CKSEG1ADDR_OR_64BIT(__pa(ebase));
if (!addr)
panic(panic_null_cerr);
@@ -2351,10 +2351,13 @@ void __init trap_init(void)
* EVA is special though as it allows segments to be rearranged
* and to become uncached during cache error handling.
*/
- if (!IS_ENABLED(CONFIG_EVA) && !WARN_ON(ebase_pa >= 0x20000000))
+ if (!IS_ENABLED(CONFIG_EVA) && ebase_pa < 0x20000000)
ebase = CKSEG0ADDR(ebase_pa);
else
ebase = (unsigned long)phys_to_virt(ebase_pa);
+ if (ebase_pa >= 0x20000000)
+ pr_warn("ebase(%pa) should better be in KSeg0",
+ &ebase_pa);
}
if (cpu_has_mmips) {
diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c
index f6d40e43f108..dda36fa26307 100644
--- a/arch/mips/kernel/vdso.c
+++ b/arch/mips/kernel/vdso.c
@@ -24,7 +24,7 @@
#include <vdso/vsyscall.h>
/* Kernel-provided data used by the VDSO. */
-static union mips_vdso_data mips_vdso_data __page_aligned_data;
+static union vdso_data_store mips_vdso_data __page_aligned_data;
struct vdso_data *vdso_data = mips_vdso_data.data;
/*
diff --git a/arch/mips/kernel/vpe-mt.c b/arch/mips/kernel/vpe-mt.c
index 667bc75f6420..84124ac2d2a5 100644
--- a/arch/mips/kernel/vpe-mt.c
+++ b/arch/mips/kernel/vpe-mt.c
@@ -95,8 +95,8 @@ int vpe_run(struct vpe *v)
* We don't pass the memsize here, so VPE programs need to be
* compiled with DFLT_STACK_SIZE and DFLT_HEAP_SIZE defined.
*/
- mttgpr(7, 0);
- mttgpr(6, v->ntcs);
+ mttgpr($7, 0);
+ mttgpr($6, v->ntcs);
/* set up VPE1 */
/*
diff --git a/arch/mips/kvm/Kconfig b/arch/mips/kvm/Kconfig
index 18e7a17d5115..ab57221fa4dd 100644
--- a/arch/mips/kvm/Kconfig
+++ b/arch/mips/kvm/Kconfig
@@ -17,7 +17,7 @@ if VIRTUALIZATION
config KVM
tristate "Kernel-based Virtual Machine (KVM) support"
- depends on HAVE_KVM
+ depends on CPU_SUPPORTS_VZ
depends on MIPS_FP_SUPPORT
select EXPORT_UASM
select KVM_COMMON
@@ -26,6 +26,7 @@ config KVM
select KVM_MMIO
select KVM_GENERIC_MMU_NOTIFIER
select KVM_GENERIC_HARDWARE_ENABLING
+ select HAVE_KVM_READONLY_MEM
help
Support for hosting Guest kernels.
diff --git a/arch/mips/kvm/entry.c b/arch/mips/kvm/entry.c
index aceed14aa1f7..ac8e074c6bb7 100644
--- a/arch/mips/kvm/entry.c
+++ b/arch/mips/kvm/entry.c
@@ -13,70 +13,17 @@
#include <linux/kvm_host.h>
#include <linux/log2.h>
+#include <asm/mipsregs.h>
#include <asm/mmu_context.h>
#include <asm/msa.h>
+#include <asm/regdef.h>
#include <asm/setup.h>
#include <asm/tlbex.h>
#include <asm/uasm.h>
-/* Register names */
-#define ZERO 0
-#define AT 1
-#define V0 2
-#define V1 3
-#define A0 4
-#define A1 5
-
-#if _MIPS_SIM == _MIPS_SIM_ABI32
-#define T0 8
-#define T1 9
-#define T2 10
-#define T3 11
-#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
-
-#if _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32
-#define T0 12
-#define T1 13
-#define T2 14
-#define T3 15
-#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32 */
-
-#define S0 16
-#define S1 17
-#define T9 25
-#define K0 26
-#define K1 27
-#define GP 28
-#define SP 29
-#define RA 31
-
-/* Some CP0 registers */
-#define C0_PWBASE 5, 5
-#define C0_HWRENA 7, 0
-#define C0_BADVADDR 8, 0
-#define C0_BADINSTR 8, 1
-#define C0_BADINSTRP 8, 2
-#define C0_PGD 9, 7
-#define C0_ENTRYHI 10, 0
-#define C0_GUESTCTL1 10, 4
-#define C0_STATUS 12, 0
-#define C0_GUESTCTL0 12, 6
-#define C0_CAUSE 13, 0
-#define C0_EPC 14, 0
-#define C0_EBASE 15, 1
-#define C0_CONFIG5 16, 5
-#define C0_DDATA_LO 28, 3
-#define C0_ERROREPC 30, 0
-
#define CALLFRAME_SIZ 32
-#ifdef CONFIG_64BIT
-#define ST0_KX_IF_64 ST0_KX
-#else
-#define ST0_KX_IF_64 0
-#endif
-
-static unsigned int scratch_vcpu[2] = { C0_DDATA_LO };
+static unsigned int scratch_vcpu[2] = { C0_DDATALO };
static unsigned int scratch_tmp[2] = { C0_ERROREPC };
enum label_id {
@@ -212,60 +159,60 @@ void *kvm_mips_build_vcpu_run(void *addr)
unsigned int i;
/*
- * A0: vcpu
+ * GPR_A0: vcpu
*/
/* k0/k1 not being used in host kernel context */
- UASM_i_ADDIU(&p, K1, SP, -(int)sizeof(struct pt_regs));
+ UASM_i_ADDIU(&p, GPR_K1, GPR_SP, -(int)sizeof(struct pt_regs));
for (i = 16; i < 32; ++i) {
if (i == 24)
i = 28;
- UASM_i_SW(&p, i, offsetof(struct pt_regs, regs[i]), K1);
+ UASM_i_SW(&p, i, offsetof(struct pt_regs, regs[i]), GPR_K1);
}
/* Save host status */
- uasm_i_mfc0(&p, V0, C0_STATUS);
- UASM_i_SW(&p, V0, offsetof(struct pt_regs, cp0_status), K1);
+ uasm_i_mfc0(&p, GPR_V0, C0_STATUS);
+ UASM_i_SW(&p, GPR_V0, offsetof(struct pt_regs, cp0_status), GPR_K1);
/* Save scratch registers, will be used to store pointer to vcpu etc */
- kvm_mips_build_save_scratch(&p, V1, K1);
+ kvm_mips_build_save_scratch(&p, GPR_V1, GPR_K1);
/* VCPU scratch register has pointer to vcpu */
- UASM_i_MTC0(&p, A0, scratch_vcpu[0], scratch_vcpu[1]);
+ UASM_i_MTC0(&p, GPR_A0, scratch_vcpu[0], scratch_vcpu[1]);
/* Offset into vcpu->arch */
- UASM_i_ADDIU(&p, K1, A0, offsetof(struct kvm_vcpu, arch));
+ UASM_i_ADDIU(&p, GPR_K1, GPR_A0, offsetof(struct kvm_vcpu, arch));
/*
* Save the host stack to VCPU, used for exception processing
* when we exit from the Guest
*/
- UASM_i_SW(&p, SP, offsetof(struct kvm_vcpu_arch, host_stack), K1);
+ UASM_i_SW(&p, GPR_SP, offsetof(struct kvm_vcpu_arch, host_stack), GPR_K1);
/* Save the kernel gp as well */
- UASM_i_SW(&p, GP, offsetof(struct kvm_vcpu_arch, host_gp), K1);
+ UASM_i_SW(&p, GPR_GP, offsetof(struct kvm_vcpu_arch, host_gp), GPR_K1);
/*
* Setup status register for running the guest in UM, interrupts
* are disabled
*/
- UASM_i_LA(&p, K0, ST0_EXL | KSU_USER | ST0_BEV | ST0_KX_IF_64);
- uasm_i_mtc0(&p, K0, C0_STATUS);
+ UASM_i_LA(&p, GPR_K0, ST0_EXL | KSU_USER | ST0_BEV | ST0_KX_IF_64);
+ uasm_i_mtc0(&p, GPR_K0, C0_STATUS);
uasm_i_ehb(&p);
/* load up the new EBASE */
- UASM_i_LW(&p, K0, offsetof(struct kvm_vcpu_arch, guest_ebase), K1);
- build_set_exc_base(&p, K0);
+ UASM_i_LW(&p, GPR_K0, offsetof(struct kvm_vcpu_arch, guest_ebase), GPR_K1);
+ build_set_exc_base(&p, GPR_K0);
/*
* Now that the new EBASE has been loaded, unset BEV, set
* interrupt mask as it was but make sure that timer interrupts
* are enabled
*/
- uasm_i_addiu(&p, K0, ZERO, ST0_EXL | KSU_USER | ST0_IE | ST0_KX_IF_64);
- uasm_i_andi(&p, V0, V0, ST0_IM);
- uasm_i_or(&p, K0, K0, V0);
- uasm_i_mtc0(&p, K0, C0_STATUS);
+ uasm_i_addiu(&p, GPR_K0, GPR_ZERO, ST0_EXL | KSU_USER | ST0_IE | ST0_KX_IF_64);
+ uasm_i_andi(&p, GPR_V0, GPR_V0, ST0_IM);
+ uasm_i_or(&p, GPR_K0, GPR_K0, GPR_V0);
+ uasm_i_mtc0(&p, GPR_K0, C0_STATUS);
uasm_i_ehb(&p);
p = kvm_mips_build_enter_guest(p);
@@ -296,15 +243,15 @@ static void *kvm_mips_build_enter_guest(void *addr)
memset(relocs, 0, sizeof(relocs));
/* Set Guest EPC */
- UASM_i_LW(&p, T0, offsetof(struct kvm_vcpu_arch, pc), K1);
- UASM_i_MTC0(&p, T0, C0_EPC);
+ UASM_i_LW(&p, GPR_T0, offsetof(struct kvm_vcpu_arch, pc), GPR_K1);
+ UASM_i_MTC0(&p, GPR_T0, C0_EPC);
/* Save normal linux process pgd (VZ guarantees pgd_reg is set) */
if (cpu_has_ldpte)
- UASM_i_MFC0(&p, K0, C0_PWBASE);
+ UASM_i_MFC0(&p, GPR_K0, C0_PWBASE);
else
- UASM_i_MFC0(&p, K0, c0_kscratch(), pgd_reg);
- UASM_i_SW(&p, K0, offsetof(struct kvm_vcpu_arch, host_pgd), K1);
+ UASM_i_MFC0(&p, GPR_K0, c0_kscratch(), pgd_reg);
+ UASM_i_SW(&p, GPR_K0, offsetof(struct kvm_vcpu_arch, host_pgd), GPR_K1);
/*
* Set up KVM GPA pgd.
@@ -312,24 +259,24 @@ static void *kvm_mips_build_enter_guest(void *addr)
* - call tlbmiss_handler_setup_pgd(mm->pgd)
* - write mm->pgd into CP0_PWBase
*
- * We keep S0 pointing at struct kvm so we can load the ASID below.
+ * We keep GPR_S0 pointing at struct kvm so we can load the ASID below.
*/
- UASM_i_LW(&p, S0, (int)offsetof(struct kvm_vcpu, kvm) -
- (int)offsetof(struct kvm_vcpu, arch), K1);
- UASM_i_LW(&p, A0, offsetof(struct kvm, arch.gpa_mm.pgd), S0);
- UASM_i_LA(&p, T9, (unsigned long)tlbmiss_handler_setup_pgd);
- uasm_i_jalr(&p, RA, T9);
+ UASM_i_LW(&p, GPR_S0, (int)offsetof(struct kvm_vcpu, kvm) -
+ (int)offsetof(struct kvm_vcpu, arch), GPR_K1);
+ UASM_i_LW(&p, GPR_A0, offsetof(struct kvm, arch.gpa_mm.pgd), GPR_S0);
+ UASM_i_LA(&p, GPR_T9, (unsigned long)tlbmiss_handler_setup_pgd);
+ uasm_i_jalr(&p, GPR_RA, GPR_T9);
/* delay slot */
if (cpu_has_htw)
- UASM_i_MTC0(&p, A0, C0_PWBASE);
+ UASM_i_MTC0(&p, GPR_A0, C0_PWBASE);
else
uasm_i_nop(&p);
/* Set GM bit to setup eret to VZ guest context */
- uasm_i_addiu(&p, V1, ZERO, 1);
- uasm_i_mfc0(&p, K0, C0_GUESTCTL0);
- uasm_i_ins(&p, K0, V1, MIPS_GCTL0_GM_SHIFT, 1);
- uasm_i_mtc0(&p, K0, C0_GUESTCTL0);
+ uasm_i_addiu(&p, GPR_V1, GPR_ZERO, 1);
+ uasm_i_mfc0(&p, GPR_K0, C0_GUESTCTL0);
+ uasm_i_ins(&p, GPR_K0, GPR_V1, MIPS_GCTL0_GM_SHIFT, 1);
+ uasm_i_mtc0(&p, GPR_K0, C0_GUESTCTL0);
if (cpu_has_guestid) {
/*
@@ -338,13 +285,13 @@ static void *kvm_mips_build_enter_guest(void *addr)
*/
/* Get current GuestID */
- uasm_i_mfc0(&p, T0, C0_GUESTCTL1);
+ uasm_i_mfc0(&p, GPR_T0, C0_GUESTCTL1);
/* Set GuestCtl1.RID = GuestCtl1.ID */
- uasm_i_ext(&p, T1, T0, MIPS_GCTL1_ID_SHIFT,
+ uasm_i_ext(&p, GPR_T1, GPR_T0, MIPS_GCTL1_ID_SHIFT,
MIPS_GCTL1_ID_WIDTH);
- uasm_i_ins(&p, T0, T1, MIPS_GCTL1_RID_SHIFT,
+ uasm_i_ins(&p, GPR_T0, GPR_T1, MIPS_GCTL1_RID_SHIFT,
MIPS_GCTL1_RID_WIDTH);
- uasm_i_mtc0(&p, T0, C0_GUESTCTL1);
+ uasm_i_mtc0(&p, GPR_T0, C0_GUESTCTL1);
/* GuestID handles dealiasing so we don't need to touch ASID */
goto skip_asid_restore;
@@ -353,65 +300,65 @@ static void *kvm_mips_build_enter_guest(void *addr)
/* Root ASID Dealias (RAD) */
/* Save host ASID */
- UASM_i_MFC0(&p, K0, C0_ENTRYHI);
- UASM_i_SW(&p, K0, offsetof(struct kvm_vcpu_arch, host_entryhi),
- K1);
+ UASM_i_MFC0(&p, GPR_K0, C0_ENTRYHI);
+ UASM_i_SW(&p, GPR_K0, offsetof(struct kvm_vcpu_arch, host_entryhi),
+ GPR_K1);
/* Set the root ASID for the Guest */
- UASM_i_ADDIU(&p, T1, S0,
+ UASM_i_ADDIU(&p, GPR_T1, GPR_S0,
offsetof(struct kvm, arch.gpa_mm.context.asid));
/* t1: contains the base of the ASID array, need to get the cpu id */
/* smp_processor_id */
- uasm_i_lw(&p, T2, offsetof(struct thread_info, cpu), GP);
+ uasm_i_lw(&p, GPR_T2, offsetof(struct thread_info, cpu), GPR_GP);
/* index the ASID array */
- uasm_i_sll(&p, T2, T2, ilog2(sizeof(long)));
- UASM_i_ADDU(&p, T3, T1, T2);
- UASM_i_LW(&p, K0, 0, T3);
+ uasm_i_sll(&p, GPR_T2, GPR_T2, ilog2(sizeof(long)));
+ UASM_i_ADDU(&p, GPR_T3, GPR_T1, GPR_T2);
+ UASM_i_LW(&p, GPR_K0, 0, GPR_T3);
#ifdef CONFIG_MIPS_ASID_BITS_VARIABLE
/*
* reuse ASID array offset
* cpuinfo_mips is a multiple of sizeof(long)
*/
- uasm_i_addiu(&p, T3, ZERO, sizeof(struct cpuinfo_mips)/sizeof(long));
- uasm_i_mul(&p, T2, T2, T3);
+ uasm_i_addiu(&p, GPR_T3, GPR_ZERO, sizeof(struct cpuinfo_mips)/sizeof(long));
+ uasm_i_mul(&p, GPR_T2, GPR_T2, GPR_T3);
- UASM_i_LA_mostly(&p, AT, (long)&cpu_data[0].asid_mask);
- UASM_i_ADDU(&p, AT, AT, T2);
- UASM_i_LW(&p, T2, uasm_rel_lo((long)&cpu_data[0].asid_mask), AT);
- uasm_i_and(&p, K0, K0, T2);
+ UASM_i_LA_mostly(&p, GPR_AT, (long)&cpu_data[0].asid_mask);
+ UASM_i_ADDU(&p, GPR_AT, GPR_AT, GPR_T2);
+ UASM_i_LW(&p, GPR_T2, uasm_rel_lo((long)&cpu_data[0].asid_mask), GPR_AT);
+ uasm_i_and(&p, GPR_K0, GPR_K0, GPR_T2);
#else
- uasm_i_andi(&p, K0, K0, MIPS_ENTRYHI_ASID);
+ uasm_i_andi(&p, GPR_K0, GPR_K0, MIPS_ENTRYHI_ASID);
#endif
/* Set up KVM VZ root ASID (!guestid) */
- uasm_i_mtc0(&p, K0, C0_ENTRYHI);
+ uasm_i_mtc0(&p, GPR_K0, C0_ENTRYHI);
skip_asid_restore:
uasm_i_ehb(&p);
/* Disable RDHWR access */
- uasm_i_mtc0(&p, ZERO, C0_HWRENA);
+ uasm_i_mtc0(&p, GPR_ZERO, C0_HWRENA);
/* load the guest context from VCPU and return */
for (i = 1; i < 32; ++i) {
/* Guest k0/k1 loaded later */
- if (i == K0 || i == K1)
+ if (i == GPR_K0 || i == GPR_K1)
continue;
- UASM_i_LW(&p, i, offsetof(struct kvm_vcpu_arch, gprs[i]), K1);
+ UASM_i_LW(&p, i, offsetof(struct kvm_vcpu_arch, gprs[i]), GPR_K1);
}
#ifndef CONFIG_CPU_MIPSR6
/* Restore hi/lo */
- UASM_i_LW(&p, K0, offsetof(struct kvm_vcpu_arch, hi), K1);
- uasm_i_mthi(&p, K0);
+ UASM_i_LW(&p, GPR_K0, offsetof(struct kvm_vcpu_arch, hi), GPR_K1);
+ uasm_i_mthi(&p, GPR_K0);
- UASM_i_LW(&p, K0, offsetof(struct kvm_vcpu_arch, lo), K1);
- uasm_i_mtlo(&p, K0);
+ UASM_i_LW(&p, GPR_K0, offsetof(struct kvm_vcpu_arch, lo), GPR_K1);
+ uasm_i_mtlo(&p, GPR_K0);
#endif
/* Restore the guest's k0/k1 registers */
- UASM_i_LW(&p, K0, offsetof(struct kvm_vcpu_arch, gprs[K0]), K1);
- UASM_i_LW(&p, K1, offsetof(struct kvm_vcpu_arch, gprs[K1]), K1);
+ UASM_i_LW(&p, GPR_K0, offsetof(struct kvm_vcpu_arch, gprs[GPR_K0]), GPR_K1);
+ UASM_i_LW(&p, GPR_K1, offsetof(struct kvm_vcpu_arch, gprs[GPR_K1]), GPR_K1);
/* Jump to guest */
uasm_i_eret(&p);
@@ -444,13 +391,13 @@ void *kvm_mips_build_tlb_refill_exception(void *addr, void *handler)
memset(relocs, 0, sizeof(relocs));
/* Save guest k1 into scratch register */
- UASM_i_MTC0(&p, K1, scratch_tmp[0], scratch_tmp[1]);
+ UASM_i_MTC0(&p, GPR_K1, scratch_tmp[0], scratch_tmp[1]);
/* Get the VCPU pointer from the VCPU scratch register */
- UASM_i_MFC0(&p, K1, scratch_vcpu[0], scratch_vcpu[1]);
+ UASM_i_MFC0(&p, GPR_K1, scratch_vcpu[0], scratch_vcpu[1]);
/* Save guest k0 into VCPU structure */
- UASM_i_SW(&p, K0, offsetof(struct kvm_vcpu, arch.gprs[K0]), K1);
+ UASM_i_SW(&p, GPR_K0, offsetof(struct kvm_vcpu, arch.gprs[GPR_K0]), GPR_K1);
/*
* Some of the common tlbex code uses current_cpu_type(). For KVM we
@@ -459,13 +406,13 @@ void *kvm_mips_build_tlb_refill_exception(void *addr, void *handler)
preempt_disable();
#ifdef CONFIG_CPU_LOONGSON64
- UASM_i_MFC0(&p, K1, C0_PGD);
- uasm_i_lddir(&p, K0, K1, 3); /* global page dir */
+ UASM_i_MFC0(&p, GPR_K1, C0_PGD);
+ uasm_i_lddir(&p, GPR_K0, GPR_K1, 3); /* global page dir */
#ifndef __PAGETABLE_PMD_FOLDED
- uasm_i_lddir(&p, K1, K0, 1); /* middle page dir */
+ uasm_i_lddir(&p, GPR_K1, GPR_K0, 1); /* middle page dir */
#endif
- uasm_i_ldpte(&p, K1, 0); /* even */
- uasm_i_ldpte(&p, K1, 1); /* odd */
+ uasm_i_ldpte(&p, GPR_K1, 0); /* even */
+ uasm_i_ldpte(&p, GPR_K1, 1); /* odd */
uasm_i_tlbwr(&p);
#else
/*
@@ -480,27 +427,27 @@ void *kvm_mips_build_tlb_refill_exception(void *addr, void *handler)
*/
#ifdef CONFIG_64BIT
- build_get_pmde64(&p, &l, &r, K0, K1); /* get pmd in K1 */
+ build_get_pmde64(&p, &l, &r, GPR_K0, GPR_K1); /* get pmd in GPR_K1 */
#else
- build_get_pgde32(&p, K0, K1); /* get pgd in K1 */
+ build_get_pgde32(&p, GPR_K0, GPR_K1); /* get pgd in GPR_K1 */
#endif
/* we don't support huge pages yet */
- build_get_ptep(&p, K0, K1);
- build_update_entries(&p, K0, K1);
+ build_get_ptep(&p, GPR_K0, GPR_K1);
+ build_update_entries(&p, GPR_K0, GPR_K1);
build_tlb_write_entry(&p, &l, &r, tlb_random);
#endif
preempt_enable();
/* Get the VCPU pointer from the VCPU scratch register again */
- UASM_i_MFC0(&p, K1, scratch_vcpu[0], scratch_vcpu[1]);
+ UASM_i_MFC0(&p, GPR_K1, scratch_vcpu[0], scratch_vcpu[1]);
/* Restore the guest's k0/k1 registers */
- UASM_i_LW(&p, K0, offsetof(struct kvm_vcpu, arch.gprs[K0]), K1);
+ UASM_i_LW(&p, GPR_K0, offsetof(struct kvm_vcpu, arch.gprs[GPR_K0]), GPR_K1);
uasm_i_ehb(&p);
- UASM_i_MFC0(&p, K1, scratch_tmp[0], scratch_tmp[1]);
+ UASM_i_MFC0(&p, GPR_K1, scratch_tmp[0], scratch_tmp[1]);
/* Jump to guest */
uasm_i_eret(&p);
@@ -530,14 +477,14 @@ void *kvm_mips_build_exception(void *addr, void *handler)
memset(relocs, 0, sizeof(relocs));
/* Save guest k1 into scratch register */
- UASM_i_MTC0(&p, K1, scratch_tmp[0], scratch_tmp[1]);
+ UASM_i_MTC0(&p, GPR_K1, scratch_tmp[0], scratch_tmp[1]);
/* Get the VCPU pointer from the VCPU scratch register */
- UASM_i_MFC0(&p, K1, scratch_vcpu[0], scratch_vcpu[1]);
- UASM_i_ADDIU(&p, K1, K1, offsetof(struct kvm_vcpu, arch));
+ UASM_i_MFC0(&p, GPR_K1, scratch_vcpu[0], scratch_vcpu[1]);
+ UASM_i_ADDIU(&p, GPR_K1, GPR_K1, offsetof(struct kvm_vcpu, arch));
/* Save guest k0 into VCPU structure */
- UASM_i_SW(&p, K0, offsetof(struct kvm_vcpu_arch, gprs[K0]), K1);
+ UASM_i_SW(&p, GPR_K0, offsetof(struct kvm_vcpu_arch, gprs[GPR_K0]), GPR_K1);
/* Branch to the common handler */
uasm_il_b(&p, &r, label_exit_common);
@@ -585,85 +532,85 @@ void *kvm_mips_build_exit(void *addr)
/* Start saving Guest context to VCPU */
for (i = 0; i < 32; ++i) {
/* Guest k0/k1 saved later */
- if (i == K0 || i == K1)
+ if (i == GPR_K0 || i == GPR_K1)
continue;
- UASM_i_SW(&p, i, offsetof(struct kvm_vcpu_arch, gprs[i]), K1);
+ UASM_i_SW(&p, i, offsetof(struct kvm_vcpu_arch, gprs[i]), GPR_K1);
}
#ifndef CONFIG_CPU_MIPSR6
/* We need to save hi/lo and restore them on the way out */
- uasm_i_mfhi(&p, T0);
- UASM_i_SW(&p, T0, offsetof(struct kvm_vcpu_arch, hi), K1);
+ uasm_i_mfhi(&p, GPR_T0);
+ UASM_i_SW(&p, GPR_T0, offsetof(struct kvm_vcpu_arch, hi), GPR_K1);
- uasm_i_mflo(&p, T0);
- UASM_i_SW(&p, T0, offsetof(struct kvm_vcpu_arch, lo), K1);
+ uasm_i_mflo(&p, GPR_T0);
+ UASM_i_SW(&p, GPR_T0, offsetof(struct kvm_vcpu_arch, lo), GPR_K1);
#endif
/* Finally save guest k1 to VCPU */
uasm_i_ehb(&p);
- UASM_i_MFC0(&p, T0, scratch_tmp[0], scratch_tmp[1]);
- UASM_i_SW(&p, T0, offsetof(struct kvm_vcpu_arch, gprs[K1]), K1);
+ UASM_i_MFC0(&p, GPR_T0, scratch_tmp[0], scratch_tmp[1]);
+ UASM_i_SW(&p, GPR_T0, offsetof(struct kvm_vcpu_arch, gprs[GPR_K1]), GPR_K1);
/* Now that context has been saved, we can use other registers */
/* Restore vcpu */
- UASM_i_MFC0(&p, S0, scratch_vcpu[0], scratch_vcpu[1]);
+ UASM_i_MFC0(&p, GPR_S0, scratch_vcpu[0], scratch_vcpu[1]);
/*
* Save Host level EPC, BadVaddr and Cause to VCPU, useful to process
* the exception
*/
- UASM_i_MFC0(&p, K0, C0_EPC);
- UASM_i_SW(&p, K0, offsetof(struct kvm_vcpu_arch, pc), K1);
+ UASM_i_MFC0(&p, GPR_K0, C0_EPC);
+ UASM_i_SW(&p, GPR_K0, offsetof(struct kvm_vcpu_arch, pc), GPR_K1);
- UASM_i_MFC0(&p, K0, C0_BADVADDR);
- UASM_i_SW(&p, K0, offsetof(struct kvm_vcpu_arch, host_cp0_badvaddr),
- K1);
+ UASM_i_MFC0(&p, GPR_K0, C0_BADVADDR);
+ UASM_i_SW(&p, GPR_K0, offsetof(struct kvm_vcpu_arch, host_cp0_badvaddr),
+ GPR_K1);
- uasm_i_mfc0(&p, K0, C0_CAUSE);
- uasm_i_sw(&p, K0, offsetof(struct kvm_vcpu_arch, host_cp0_cause), K1);
+ uasm_i_mfc0(&p, GPR_K0, C0_CAUSE);
+ uasm_i_sw(&p, GPR_K0, offsetof(struct kvm_vcpu_arch, host_cp0_cause), GPR_K1);
if (cpu_has_badinstr) {
- uasm_i_mfc0(&p, K0, C0_BADINSTR);
- uasm_i_sw(&p, K0, offsetof(struct kvm_vcpu_arch,
- host_cp0_badinstr), K1);
+ uasm_i_mfc0(&p, GPR_K0, C0_BADINSTR);
+ uasm_i_sw(&p, GPR_K0, offsetof(struct kvm_vcpu_arch,
+ host_cp0_badinstr), GPR_K1);
}
if (cpu_has_badinstrp) {
- uasm_i_mfc0(&p, K0, C0_BADINSTRP);
- uasm_i_sw(&p, K0, offsetof(struct kvm_vcpu_arch,
- host_cp0_badinstrp), K1);
+ uasm_i_mfc0(&p, GPR_K0, C0_BADINSTRP);
+ uasm_i_sw(&p, GPR_K0, offsetof(struct kvm_vcpu_arch,
+ host_cp0_badinstrp), GPR_K1);
}
/* Now restore the host state just enough to run the handlers */
/* Switch EBASE to the one used by Linux */
/* load up the host EBASE */
- uasm_i_mfc0(&p, V0, C0_STATUS);
+ uasm_i_mfc0(&p, GPR_V0, C0_STATUS);
- uasm_i_lui(&p, AT, ST0_BEV >> 16);
- uasm_i_or(&p, K0, V0, AT);
+ uasm_i_lui(&p, GPR_AT, ST0_BEV >> 16);
+ uasm_i_or(&p, GPR_K0, GPR_V0, GPR_AT);
- uasm_i_mtc0(&p, K0, C0_STATUS);
+ uasm_i_mtc0(&p, GPR_K0, C0_STATUS);
uasm_i_ehb(&p);
- UASM_i_LA_mostly(&p, K0, (long)&ebase);
- UASM_i_LW(&p, K0, uasm_rel_lo((long)&ebase), K0);
- build_set_exc_base(&p, K0);
+ UASM_i_LA_mostly(&p, GPR_K0, (long)&ebase);
+ UASM_i_LW(&p, GPR_K0, uasm_rel_lo((long)&ebase), GPR_K0);
+ build_set_exc_base(&p, GPR_K0);
if (raw_cpu_has_fpu) {
/*
* If FPU is enabled, save FCR31 and clear it so that later
* ctc1's don't trigger FPE for pending exceptions.
*/
- uasm_i_lui(&p, AT, ST0_CU1 >> 16);
- uasm_i_and(&p, V1, V0, AT);
- uasm_il_beqz(&p, &r, V1, label_fpu_1);
+ uasm_i_lui(&p, GPR_AT, ST0_CU1 >> 16);
+ uasm_i_and(&p, GPR_V1, GPR_V0, GPR_AT);
+ uasm_il_beqz(&p, &r, GPR_V1, label_fpu_1);
uasm_i_nop(&p);
- uasm_i_cfc1(&p, T0, 31);
- uasm_i_sw(&p, T0, offsetof(struct kvm_vcpu_arch, fpu.fcr31),
- K1);
- uasm_i_ctc1(&p, ZERO, 31);
+ uasm_i_cfc1(&p, GPR_T0, 31);
+ uasm_i_sw(&p, GPR_T0, offsetof(struct kvm_vcpu_arch, fpu.fcr31),
+ GPR_K1);
+ uasm_i_ctc1(&p, GPR_ZERO, 31);
uasm_l_fpu_1(&l, p);
}
@@ -672,22 +619,22 @@ void *kvm_mips_build_exit(void *addr)
* If MSA is enabled, save MSACSR and clear it so that later
* instructions don't trigger MSAFPE for pending exceptions.
*/
- uasm_i_mfc0(&p, T0, C0_CONFIG5);
- uasm_i_ext(&p, T0, T0, 27, 1); /* MIPS_CONF5_MSAEN */
- uasm_il_beqz(&p, &r, T0, label_msa_1);
+ uasm_i_mfc0(&p, GPR_T0, C0_CONFIG5);
+ uasm_i_ext(&p, GPR_T0, GPR_T0, 27, 1); /* MIPS_CONF5_MSAEN */
+ uasm_il_beqz(&p, &r, GPR_T0, label_msa_1);
uasm_i_nop(&p);
- uasm_i_cfcmsa(&p, T0, MSA_CSR);
- uasm_i_sw(&p, T0, offsetof(struct kvm_vcpu_arch, fpu.msacsr),
- K1);
- uasm_i_ctcmsa(&p, MSA_CSR, ZERO);
+ uasm_i_cfcmsa(&p, GPR_T0, MSA_CSR);
+ uasm_i_sw(&p, GPR_T0, offsetof(struct kvm_vcpu_arch, fpu.msacsr),
+ GPR_K1);
+ uasm_i_ctcmsa(&p, MSA_CSR, GPR_ZERO);
uasm_l_msa_1(&l, p);
}
/* Restore host ASID */
if (!cpu_has_guestid) {
- UASM_i_LW(&p, K0, offsetof(struct kvm_vcpu_arch, host_entryhi),
- K1);
- UASM_i_MTC0(&p, K0, C0_ENTRYHI);
+ UASM_i_LW(&p, GPR_K0, offsetof(struct kvm_vcpu_arch, host_entryhi),
+ GPR_K1);
+ UASM_i_MTC0(&p, GPR_K0, C0_ENTRYHI);
}
/*
@@ -696,56 +643,56 @@ void *kvm_mips_build_exit(void *addr)
* - call tlbmiss_handler_setup_pgd(mm->pgd)
* - write mm->pgd into CP0_PWBase
*/
- UASM_i_LW(&p, A0,
- offsetof(struct kvm_vcpu_arch, host_pgd), K1);
- UASM_i_LA(&p, T9, (unsigned long)tlbmiss_handler_setup_pgd);
- uasm_i_jalr(&p, RA, T9);
+ UASM_i_LW(&p, GPR_A0,
+ offsetof(struct kvm_vcpu_arch, host_pgd), GPR_K1);
+ UASM_i_LA(&p, GPR_T9, (unsigned long)tlbmiss_handler_setup_pgd);
+ uasm_i_jalr(&p, GPR_RA, GPR_T9);
/* delay slot */
if (cpu_has_htw)
- UASM_i_MTC0(&p, A0, C0_PWBASE);
+ UASM_i_MTC0(&p, GPR_A0, C0_PWBASE);
else
uasm_i_nop(&p);
/* Clear GM bit so we don't enter guest mode when EXL is cleared */
- uasm_i_mfc0(&p, K0, C0_GUESTCTL0);
- uasm_i_ins(&p, K0, ZERO, MIPS_GCTL0_GM_SHIFT, 1);
- uasm_i_mtc0(&p, K0, C0_GUESTCTL0);
+ uasm_i_mfc0(&p, GPR_K0, C0_GUESTCTL0);
+ uasm_i_ins(&p, GPR_K0, GPR_ZERO, MIPS_GCTL0_GM_SHIFT, 1);
+ uasm_i_mtc0(&p, GPR_K0, C0_GUESTCTL0);
/* Save GuestCtl0 so we can access GExcCode after CPU migration */
- uasm_i_sw(&p, K0,
- offsetof(struct kvm_vcpu_arch, host_cp0_guestctl0), K1);
+ uasm_i_sw(&p, GPR_K0,
+ offsetof(struct kvm_vcpu_arch, host_cp0_guestctl0), GPR_K1);
if (cpu_has_guestid) {
/*
* Clear root mode GuestID, so that root TLB operations use the
* root GuestID in the root TLB.
*/
- uasm_i_mfc0(&p, T0, C0_GUESTCTL1);
+ uasm_i_mfc0(&p, GPR_T0, C0_GUESTCTL1);
/* Set GuestCtl1.RID = MIPS_GCTL1_ROOT_GUESTID (i.e. 0) */
- uasm_i_ins(&p, T0, ZERO, MIPS_GCTL1_RID_SHIFT,
+ uasm_i_ins(&p, GPR_T0, GPR_ZERO, MIPS_GCTL1_RID_SHIFT,
MIPS_GCTL1_RID_WIDTH);
- uasm_i_mtc0(&p, T0, C0_GUESTCTL1);
+ uasm_i_mtc0(&p, GPR_T0, C0_GUESTCTL1);
}
/* Now that the new EBASE has been loaded, unset BEV and KSU_USER */
- uasm_i_addiu(&p, AT, ZERO, ~(ST0_EXL | KSU_USER | ST0_IE));
- uasm_i_and(&p, V0, V0, AT);
- uasm_i_lui(&p, AT, ST0_CU0 >> 16);
- uasm_i_or(&p, V0, V0, AT);
+ uasm_i_addiu(&p, GPR_AT, GPR_ZERO, ~(ST0_EXL | KSU_USER | ST0_IE));
+ uasm_i_and(&p, GPR_V0, GPR_V0, GPR_AT);
+ uasm_i_lui(&p, GPR_AT, ST0_CU0 >> 16);
+ uasm_i_or(&p, GPR_V0, GPR_V0, GPR_AT);
#ifdef CONFIG_64BIT
- uasm_i_ori(&p, V0, V0, ST0_SX | ST0_UX);
+ uasm_i_ori(&p, GPR_V0, GPR_V0, ST0_SX | ST0_UX);
#endif
- uasm_i_mtc0(&p, V0, C0_STATUS);
+ uasm_i_mtc0(&p, GPR_V0, C0_STATUS);
uasm_i_ehb(&p);
- /* Load up host GP */
- UASM_i_LW(&p, GP, offsetof(struct kvm_vcpu_arch, host_gp), K1);
+ /* Load up host GPR_GP */
+ UASM_i_LW(&p, GPR_GP, offsetof(struct kvm_vcpu_arch, host_gp), GPR_K1);
/* Need a stack before we can jump to "C" */
- UASM_i_LW(&p, SP, offsetof(struct kvm_vcpu_arch, host_stack), K1);
+ UASM_i_LW(&p, GPR_SP, offsetof(struct kvm_vcpu_arch, host_stack), GPR_K1);
/* Saved host state */
- UASM_i_ADDIU(&p, SP, SP, -(int)sizeof(struct pt_regs));
+ UASM_i_ADDIU(&p, GPR_SP, GPR_SP, -(int)sizeof(struct pt_regs));
/*
* XXXKYMA do we need to load the host ASID, maybe not because the
@@ -753,12 +700,12 @@ void *kvm_mips_build_exit(void *addr)
*/
/* Restore host scratch registers, as we'll have clobbered them */
- kvm_mips_build_restore_scratch(&p, K0, SP);
+ kvm_mips_build_restore_scratch(&p, GPR_K0, GPR_SP);
/* Restore RDHWR access */
- UASM_i_LA_mostly(&p, K0, (long)&hwrena);
- uasm_i_lw(&p, K0, uasm_rel_lo((long)&hwrena), K0);
- uasm_i_mtc0(&p, K0, C0_HWRENA);
+ UASM_i_LA_mostly(&p, GPR_K0, (long)&hwrena);
+ uasm_i_lw(&p, GPR_K0, uasm_rel_lo((long)&hwrena), GPR_K0);
+ uasm_i_mtc0(&p, GPR_K0, C0_HWRENA);
/* Jump to handler */
/*
@@ -766,10 +713,10 @@ void *kvm_mips_build_exit(void *addr)
* Now jump to the kvm_mips_handle_exit() to see if we can deal
* with this in the kernel
*/
- uasm_i_move(&p, A0, S0);
- UASM_i_LA(&p, T9, (unsigned long)kvm_mips_handle_exit);
- uasm_i_jalr(&p, RA, T9);
- UASM_i_ADDIU(&p, SP, SP, -CALLFRAME_SIZ);
+ uasm_i_move(&p, GPR_A0, GPR_S0);
+ UASM_i_LA(&p, GPR_T9, (unsigned long)kvm_mips_handle_exit);
+ uasm_i_jalr(&p, GPR_RA, GPR_T9);
+ UASM_i_ADDIU(&p, GPR_SP, GPR_SP, -CALLFRAME_SIZ);
uasm_resolve_relocs(relocs, labels);
@@ -799,7 +746,7 @@ static void *kvm_mips_build_ret_from_exit(void *addr)
memset(relocs, 0, sizeof(relocs));
/* Return from handler Make sure interrupts are disabled */
- uasm_i_di(&p, ZERO);
+ uasm_i_di(&p, GPR_ZERO);
uasm_i_ehb(&p);
/*
@@ -808,15 +755,15 @@ static void *kvm_mips_build_ret_from_exit(void *addr)
* guest, reload k1
*/
- uasm_i_move(&p, K1, S0);
- UASM_i_ADDIU(&p, K1, K1, offsetof(struct kvm_vcpu, arch));
+ uasm_i_move(&p, GPR_K1, GPR_S0);
+ UASM_i_ADDIU(&p, GPR_K1, GPR_K1, offsetof(struct kvm_vcpu, arch));
/*
* Check return value, should tell us if we are returning to the
* host (handle I/O etc)or resuming the guest
*/
- uasm_i_andi(&p, T0, V0, RESUME_HOST);
- uasm_il_bnez(&p, &r, T0, label_return_to_host);
+ uasm_i_andi(&p, GPR_T0, GPR_V0, RESUME_HOST);
+ uasm_il_bnez(&p, &r, GPR_T0, label_return_to_host);
uasm_i_nop(&p);
p = kvm_mips_build_ret_to_guest(p);
@@ -843,24 +790,24 @@ static void *kvm_mips_build_ret_to_guest(void *addr)
u32 *p = addr;
/* Put the saved pointer to vcpu (s0) back into the scratch register */
- UASM_i_MTC0(&p, S0, scratch_vcpu[0], scratch_vcpu[1]);
+ UASM_i_MTC0(&p, GPR_S0, scratch_vcpu[0], scratch_vcpu[1]);
/* Load up the Guest EBASE to minimize the window where BEV is set */
- UASM_i_LW(&p, T0, offsetof(struct kvm_vcpu_arch, guest_ebase), K1);
+ UASM_i_LW(&p, GPR_T0, offsetof(struct kvm_vcpu_arch, guest_ebase), GPR_K1);
/* Switch EBASE back to the one used by KVM */
- uasm_i_mfc0(&p, V1, C0_STATUS);
- uasm_i_lui(&p, AT, ST0_BEV >> 16);
- uasm_i_or(&p, K0, V1, AT);
- uasm_i_mtc0(&p, K0, C0_STATUS);
+ uasm_i_mfc0(&p, GPR_V1, C0_STATUS);
+ uasm_i_lui(&p, GPR_AT, ST0_BEV >> 16);
+ uasm_i_or(&p, GPR_K0, GPR_V1, GPR_AT);
+ uasm_i_mtc0(&p, GPR_K0, C0_STATUS);
uasm_i_ehb(&p);
- build_set_exc_base(&p, T0);
+ build_set_exc_base(&p, GPR_T0);
/* Setup status register for running guest in UM */
- uasm_i_ori(&p, V1, V1, ST0_EXL | KSU_USER | ST0_IE);
- UASM_i_LA(&p, AT, ~(ST0_CU0 | ST0_MX | ST0_SX | ST0_UX));
- uasm_i_and(&p, V1, V1, AT);
- uasm_i_mtc0(&p, V1, C0_STATUS);
+ uasm_i_ori(&p, GPR_V1, GPR_V1, ST0_EXL | KSU_USER | ST0_IE);
+ UASM_i_LA(&p, GPR_AT, ~(ST0_CU0 | ST0_MX | ST0_SX | ST0_UX));
+ uasm_i_and(&p, GPR_V1, GPR_V1, GPR_AT);
+ uasm_i_mtc0(&p, GPR_V1, C0_STATUS);
uasm_i_ehb(&p);
p = kvm_mips_build_enter_guest(p);
@@ -884,31 +831,31 @@ static void *kvm_mips_build_ret_to_host(void *addr)
unsigned int i;
/* EBASE is already pointing to Linux */
- UASM_i_LW(&p, K1, offsetof(struct kvm_vcpu_arch, host_stack), K1);
- UASM_i_ADDIU(&p, K1, K1, -(int)sizeof(struct pt_regs));
+ UASM_i_LW(&p, GPR_K1, offsetof(struct kvm_vcpu_arch, host_stack), GPR_K1);
+ UASM_i_ADDIU(&p, GPR_K1, GPR_K1, -(int)sizeof(struct pt_regs));
/*
* r2/v0 is the return code, shift it down by 2 (arithmetic)
* to recover the err code
*/
- uasm_i_sra(&p, K0, V0, 2);
- uasm_i_move(&p, V0, K0);
+ uasm_i_sra(&p, GPR_K0, GPR_V0, 2);
+ uasm_i_move(&p, GPR_V0, GPR_K0);
/* Load context saved on the host stack */
for (i = 16; i < 31; ++i) {
if (i == 24)
i = 28;
- UASM_i_LW(&p, i, offsetof(struct pt_regs, regs[i]), K1);
+ UASM_i_LW(&p, i, offsetof(struct pt_regs, regs[i]), GPR_K1);
}
/* Restore RDHWR access */
- UASM_i_LA_mostly(&p, K0, (long)&hwrena);
- uasm_i_lw(&p, K0, uasm_rel_lo((long)&hwrena), K0);
- uasm_i_mtc0(&p, K0, C0_HWRENA);
+ UASM_i_LA_mostly(&p, GPR_K0, (long)&hwrena);
+ uasm_i_lw(&p, GPR_K0, uasm_rel_lo((long)&hwrena), GPR_K0);
+ uasm_i_mtc0(&p, GPR_K0, C0_HWRENA);
- /* Restore RA, which is the address we will return to */
- UASM_i_LW(&p, RA, offsetof(struct pt_regs, regs[RA]), K1);
- uasm_i_jr(&p, RA);
+ /* Restore GPR_RA, which is the address we will return to */
+ UASM_i_LW(&p, GPR_RA, offsetof(struct pt_regs, regs[GPR_RA]), GPR_K1);
+ uasm_i_jr(&p, GPR_RA);
uasm_i_nop(&p);
return p;
diff --git a/arch/mips/loongson64/init.c b/arch/mips/loongson64/init.c
index 553142c1f14f..a35dd7311795 100644
--- a/arch/mips/loongson64/init.c
+++ b/arch/mips/loongson64/init.c
@@ -180,7 +180,7 @@ static int __init add_legacy_isa_io(struct fwnode_handle *fwnode, resource_size_
vaddr = PCI_IOBASE + range->io_start;
- ioremap_page_range(vaddr, vaddr + size, hw_start, pgprot_device(PAGE_KERNEL));
+ vmap_page_range(vaddr, vaddr + size, hw_start, pgprot_device(PAGE_KERNEL));
return 0;
}
diff --git a/arch/mips/mm/page.c b/arch/mips/mm/page.c
index d3b4459d0fe8..1df237bd4a72 100644
--- a/arch/mips/mm/page.c
+++ b/arch/mips/mm/page.c
@@ -24,6 +24,7 @@
#include <asm/bootinfo.h>
#include <asm/mipsregs.h>
#include <asm/mmu_context.h>
+#include <asm/regdef.h>
#include <asm/cpu.h>
#ifdef CONFIG_SIBYTE_DMA_PAGEOPS
@@ -34,19 +35,6 @@
#include <asm/uasm.h>
-/* Registers used in the assembled routines. */
-#define ZERO 0
-#define AT 2
-#define A0 4
-#define A1 5
-#define A2 6
-#define T0 8
-#define T1 9
-#define T2 10
-#define T3 11
-#define T9 25
-#define RA 31
-
/* Handle labels (which must be positive integers). */
enum label_id {
label_clear_nopref = 1,
@@ -106,16 +94,16 @@ pg_addiu(u32 **buf, unsigned int reg1, unsigned int reg2, unsigned int off)
IS_ENABLED(CONFIG_CPU_DADDI_WORKAROUNDS) &&
r4k_daddiu_bug()) {
if (off > 0x7fff) {
- uasm_i_lui(buf, T9, uasm_rel_hi(off));
- uasm_i_addiu(buf, T9, T9, uasm_rel_lo(off));
+ uasm_i_lui(buf, GPR_T9, uasm_rel_hi(off));
+ uasm_i_addiu(buf, GPR_T9, GPR_T9, uasm_rel_lo(off));
} else
- uasm_i_addiu(buf, T9, ZERO, off);
- uasm_i_daddu(buf, reg1, reg2, T9);
+ uasm_i_addiu(buf, GPR_T9, GPR_ZERO, off);
+ uasm_i_daddu(buf, reg1, reg2, GPR_T9);
} else {
if (off > 0x7fff) {
- uasm_i_lui(buf, T9, uasm_rel_hi(off));
- uasm_i_addiu(buf, T9, T9, uasm_rel_lo(off));
- UASM_i_ADDU(buf, reg1, reg2, T9);
+ uasm_i_lui(buf, GPR_T9, uasm_rel_hi(off));
+ uasm_i_addiu(buf, GPR_T9, GPR_T9, uasm_rel_lo(off));
+ UASM_i_ADDU(buf, reg1, reg2, GPR_T9);
} else
UASM_i_ADDIU(buf, reg1, reg2, off);
}
@@ -233,9 +221,9 @@ static void set_prefetch_parameters(void)
static void build_clear_store(u32 **buf, int off)
{
if (cpu_has_64bit_gp_regs || cpu_has_64bit_zero_reg) {
- uasm_i_sd(buf, ZERO, off, A0);
+ uasm_i_sd(buf, GPR_ZERO, off, GPR_A0);
} else {
- uasm_i_sw(buf, ZERO, off, A0);
+ uasm_i_sw(buf, GPR_ZERO, off, GPR_A0);
}
}
@@ -246,10 +234,10 @@ static inline void build_clear_pref(u32 **buf, int off)
if (pref_bias_clear_store) {
_uasm_i_pref(buf, pref_dst_mode, pref_bias_clear_store + off,
- A0);
+ GPR_A0);
} else if (cache_line_size == (half_clear_loop_size << 1)) {
if (cpu_has_cache_cdex_s) {
- uasm_i_cache(buf, Create_Dirty_Excl_SD, off, A0);
+ uasm_i_cache(buf, Create_Dirty_Excl_SD, off, GPR_A0);
} else if (cpu_has_cache_cdex_p) {
if (IS_ENABLED(CONFIG_WAR_R4600_V1_HIT_CACHEOP) &&
cpu_is_r4600_v1_x()) {
@@ -261,9 +249,9 @@ static inline void build_clear_pref(u32 **buf, int off)
if (IS_ENABLED(CONFIG_WAR_R4600_V2_HIT_CACHEOP) &&
cpu_is_r4600_v2_x())
- uasm_i_lw(buf, ZERO, ZERO, AT);
+ uasm_i_lw(buf, GPR_ZERO, GPR_ZERO, GPR_AT);
- uasm_i_cache(buf, Create_Dirty_Excl_D, off, A0);
+ uasm_i_cache(buf, Create_Dirty_Excl_D, off, GPR_A0);
}
}
}
@@ -301,12 +289,12 @@ void build_clear_page(void)
off = PAGE_SIZE - pref_bias_clear_store;
if (off > 0xffff || !pref_bias_clear_store)
- pg_addiu(&buf, A2, A0, off);
+ pg_addiu(&buf, GPR_A2, GPR_A0, off);
else
- uasm_i_ori(&buf, A2, A0, off);
+ uasm_i_ori(&buf, GPR_A2, GPR_A0, off);
if (IS_ENABLED(CONFIG_WAR_R4600_V2_HIT_CACHEOP) && cpu_is_r4600_v2_x())
- uasm_i_lui(&buf, AT, uasm_rel_hi(0xa0000000));
+ uasm_i_lui(&buf, GPR_AT, uasm_rel_hi(0xa0000000));
off = cache_line_size ? min(8, pref_bias_clear_store / cache_line_size)
* cache_line_size : 0;
@@ -320,36 +308,36 @@ void build_clear_page(void)
build_clear_store(&buf, off);
off += clear_word_size;
} while (off < half_clear_loop_size);
- pg_addiu(&buf, A0, A0, 2 * off);
+ pg_addiu(&buf, GPR_A0, GPR_A0, 2 * off);
off = -off;
do {
build_clear_pref(&buf, off);
if (off == -clear_word_size)
- uasm_il_bne(&buf, &r, A0, A2, label_clear_pref);
+ uasm_il_bne(&buf, &r, GPR_A0, GPR_A2, label_clear_pref);
build_clear_store(&buf, off);
off += clear_word_size;
} while (off < 0);
if (pref_bias_clear_store) {
- pg_addiu(&buf, A2, A0, pref_bias_clear_store);
+ pg_addiu(&buf, GPR_A2, GPR_A0, pref_bias_clear_store);
uasm_l_clear_nopref(&l, buf);
off = 0;
do {
build_clear_store(&buf, off);
off += clear_word_size;
} while (off < half_clear_loop_size);
- pg_addiu(&buf, A0, A0, 2 * off);
+ pg_addiu(&buf, GPR_A0, GPR_A0, 2 * off);
off = -off;
do {
if (off == -clear_word_size)
- uasm_il_bne(&buf, &r, A0, A2,
+ uasm_il_bne(&buf, &r, GPR_A0, GPR_A2,
label_clear_nopref);
build_clear_store(&buf, off);
off += clear_word_size;
} while (off < 0);
}
- uasm_i_jr(&buf, RA);
+ uasm_i_jr(&buf, GPR_RA);
uasm_i_nop(&buf);
BUG_ON(buf > &__clear_page_end);
@@ -369,18 +357,18 @@ void build_clear_page(void)
static void build_copy_load(u32 **buf, int reg, int off)
{
if (cpu_has_64bit_gp_regs) {
- uasm_i_ld(buf, reg, off, A1);
+ uasm_i_ld(buf, reg, off, GPR_A1);
} else {
- uasm_i_lw(buf, reg, off, A1);
+ uasm_i_lw(buf, reg, off, GPR_A1);
}
}
static void build_copy_store(u32 **buf, int reg, int off)
{
if (cpu_has_64bit_gp_regs) {
- uasm_i_sd(buf, reg, off, A0);
+ uasm_i_sd(buf, reg, off, GPR_A0);
} else {
- uasm_i_sw(buf, reg, off, A0);
+ uasm_i_sw(buf, reg, off, GPR_A0);
}
}
@@ -390,7 +378,7 @@ static inline void build_copy_load_pref(u32 **buf, int off)
return;
if (pref_bias_copy_load)
- _uasm_i_pref(buf, pref_src_mode, pref_bias_copy_load + off, A1);
+ _uasm_i_pref(buf, pref_src_mode, pref_bias_copy_load + off, GPR_A1);
}
static inline void build_copy_store_pref(u32 **buf, int off)
@@ -400,10 +388,10 @@ static inline void build_copy_store_pref(u32 **buf, int off)
if (pref_bias_copy_store) {
_uasm_i_pref(buf, pref_dst_mode, pref_bias_copy_store + off,
- A0);
+ GPR_A0);
} else if (cache_line_size == (half_copy_loop_size << 1)) {
if (cpu_has_cache_cdex_s) {
- uasm_i_cache(buf, Create_Dirty_Excl_SD, off, A0);
+ uasm_i_cache(buf, Create_Dirty_Excl_SD, off, GPR_A0);
} else if (cpu_has_cache_cdex_p) {
if (IS_ENABLED(CONFIG_WAR_R4600_V1_HIT_CACHEOP) &&
cpu_is_r4600_v1_x()) {
@@ -415,9 +403,9 @@ static inline void build_copy_store_pref(u32 **buf, int off)
if (IS_ENABLED(CONFIG_WAR_R4600_V2_HIT_CACHEOP) &&
cpu_is_r4600_v2_x())
- uasm_i_lw(buf, ZERO, ZERO, AT);
+ uasm_i_lw(buf, GPR_ZERO, GPR_ZERO, GPR_AT);
- uasm_i_cache(buf, Create_Dirty_Excl_D, off, A0);
+ uasm_i_cache(buf, Create_Dirty_Excl_D, off, GPR_A0);
}
}
}
@@ -454,12 +442,12 @@ void build_copy_page(void)
off = PAGE_SIZE - pref_bias_copy_load;
if (off > 0xffff || !pref_bias_copy_load)
- pg_addiu(&buf, A2, A0, off);
+ pg_addiu(&buf, GPR_A2, GPR_A0, off);
else
- uasm_i_ori(&buf, A2, A0, off);
+ uasm_i_ori(&buf, GPR_A2, GPR_A0, off);
if (IS_ENABLED(CONFIG_WAR_R4600_V2_HIT_CACHEOP) && cpu_is_r4600_v2_x())
- uasm_i_lui(&buf, AT, uasm_rel_hi(0xa0000000));
+ uasm_i_lui(&buf, GPR_AT, uasm_rel_hi(0xa0000000));
off = cache_line_size ? min(8, pref_bias_copy_load / cache_line_size) *
cache_line_size : 0;
@@ -476,126 +464,126 @@ void build_copy_page(void)
uasm_l_copy_pref_both(&l, buf);
do {
build_copy_load_pref(&buf, off);
- build_copy_load(&buf, T0, off);
+ build_copy_load(&buf, GPR_T0, off);
build_copy_load_pref(&buf, off + copy_word_size);
- build_copy_load(&buf, T1, off + copy_word_size);
+ build_copy_load(&buf, GPR_T1, off + copy_word_size);
build_copy_load_pref(&buf, off + 2 * copy_word_size);
- build_copy_load(&buf, T2, off + 2 * copy_word_size);
+ build_copy_load(&buf, GPR_T2, off + 2 * copy_word_size);
build_copy_load_pref(&buf, off + 3 * copy_word_size);
- build_copy_load(&buf, T3, off + 3 * copy_word_size);
+ build_copy_load(&buf, GPR_T3, off + 3 * copy_word_size);
build_copy_store_pref(&buf, off);
- build_copy_store(&buf, T0, off);
+ build_copy_store(&buf, GPR_T0, off);
build_copy_store_pref(&buf, off + copy_word_size);
- build_copy_store(&buf, T1, off + copy_word_size);
+ build_copy_store(&buf, GPR_T1, off + copy_word_size);
build_copy_store_pref(&buf, off + 2 * copy_word_size);
- build_copy_store(&buf, T2, off + 2 * copy_word_size);
+ build_copy_store(&buf, GPR_T2, off + 2 * copy_word_size);
build_copy_store_pref(&buf, off + 3 * copy_word_size);
- build_copy_store(&buf, T3, off + 3 * copy_word_size);
+ build_copy_store(&buf, GPR_T3, off + 3 * copy_word_size);
off += 4 * copy_word_size;
} while (off < half_copy_loop_size);
- pg_addiu(&buf, A1, A1, 2 * off);
- pg_addiu(&buf, A0, A0, 2 * off);
+ pg_addiu(&buf, GPR_A1, GPR_A1, 2 * off);
+ pg_addiu(&buf, GPR_A0, GPR_A0, 2 * off);
off = -off;
do {
build_copy_load_pref(&buf, off);
- build_copy_load(&buf, T0, off);
+ build_copy_load(&buf, GPR_T0, off);
build_copy_load_pref(&buf, off + copy_word_size);
- build_copy_load(&buf, T1, off + copy_word_size);
+ build_copy_load(&buf, GPR_T1, off + copy_word_size);
build_copy_load_pref(&buf, off + 2 * copy_word_size);
- build_copy_load(&buf, T2, off + 2 * copy_word_size);
+ build_copy_load(&buf, GPR_T2, off + 2 * copy_word_size);
build_copy_load_pref(&buf, off + 3 * copy_word_size);
- build_copy_load(&buf, T3, off + 3 * copy_word_size);
+ build_copy_load(&buf, GPR_T3, off + 3 * copy_word_size);
build_copy_store_pref(&buf, off);
- build_copy_store(&buf, T0, off);
+ build_copy_store(&buf, GPR_T0, off);
build_copy_store_pref(&buf, off + copy_word_size);
- build_copy_store(&buf, T1, off + copy_word_size);
+ build_copy_store(&buf, GPR_T1, off + copy_word_size);
build_copy_store_pref(&buf, off + 2 * copy_word_size);
- build_copy_store(&buf, T2, off + 2 * copy_word_size);
+ build_copy_store(&buf, GPR_T2, off + 2 * copy_word_size);
build_copy_store_pref(&buf, off + 3 * copy_word_size);
if (off == -(4 * copy_word_size))
- uasm_il_bne(&buf, &r, A2, A0, label_copy_pref_both);
- build_copy_store(&buf, T3, off + 3 * copy_word_size);
+ uasm_il_bne(&buf, &r, GPR_A2, GPR_A0, label_copy_pref_both);
+ build_copy_store(&buf, GPR_T3, off + 3 * copy_word_size);
off += 4 * copy_word_size;
} while (off < 0);
if (pref_bias_copy_load - pref_bias_copy_store) {
- pg_addiu(&buf, A2, A0,
+ pg_addiu(&buf, GPR_A2, GPR_A0,
pref_bias_copy_load - pref_bias_copy_store);
uasm_l_copy_pref_store(&l, buf);
off = 0;
do {
- build_copy_load(&buf, T0, off);
- build_copy_load(&buf, T1, off + copy_word_size);
- build_copy_load(&buf, T2, off + 2 * copy_word_size);
- build_copy_load(&buf, T3, off + 3 * copy_word_size);
+ build_copy_load(&buf, GPR_T0, off);
+ build_copy_load(&buf, GPR_T1, off + copy_word_size);
+ build_copy_load(&buf, GPR_T2, off + 2 * copy_word_size);
+ build_copy_load(&buf, GPR_T3, off + 3 * copy_word_size);
build_copy_store_pref(&buf, off);
- build_copy_store(&buf, T0, off);
+ build_copy_store(&buf, GPR_T0, off);
build_copy_store_pref(&buf, off + copy_word_size);
- build_copy_store(&buf, T1, off + copy_word_size);
+ build_copy_store(&buf, GPR_T1, off + copy_word_size);
build_copy_store_pref(&buf, off + 2 * copy_word_size);
- build_copy_store(&buf, T2, off + 2 * copy_word_size);
+ build_copy_store(&buf, GPR_T2, off + 2 * copy_word_size);
build_copy_store_pref(&buf, off + 3 * copy_word_size);
- build_copy_store(&buf, T3, off + 3 * copy_word_size);
+ build_copy_store(&buf, GPR_T3, off + 3 * copy_word_size);
off += 4 * copy_word_size;
} while (off < half_copy_loop_size);
- pg_addiu(&buf, A1, A1, 2 * off);
- pg_addiu(&buf, A0, A0, 2 * off);
+ pg_addiu(&buf, GPR_A1, GPR_A1, 2 * off);
+ pg_addiu(&buf, GPR_A0, GPR_A0, 2 * off);
off = -off;
do {
- build_copy_load(&buf, T0, off);
- build_copy_load(&buf, T1, off + copy_word_size);
- build_copy_load(&buf, T2, off + 2 * copy_word_size);
- build_copy_load(&buf, T3, off + 3 * copy_word_size);
+ build_copy_load(&buf, GPR_T0, off);
+ build_copy_load(&buf, GPR_T1, off + copy_word_size);
+ build_copy_load(&buf, GPR_T2, off + 2 * copy_word_size);
+ build_copy_load(&buf, GPR_T3, off + 3 * copy_word_size);
build_copy_store_pref(&buf, off);
- build_copy_store(&buf, T0, off);
+ build_copy_store(&buf, GPR_T0, off);
build_copy_store_pref(&buf, off + copy_word_size);
- build_copy_store(&buf, T1, off + copy_word_size);
+ build_copy_store(&buf, GPR_T1, off + copy_word_size);
build_copy_store_pref(&buf, off + 2 * copy_word_size);
- build_copy_store(&buf, T2, off + 2 * copy_word_size);
+ build_copy_store(&buf, GPR_T2, off + 2 * copy_word_size);
build_copy_store_pref(&buf, off + 3 * copy_word_size);
if (off == -(4 * copy_word_size))
- uasm_il_bne(&buf, &r, A2, A0,
+ uasm_il_bne(&buf, &r, GPR_A2, GPR_A0,
label_copy_pref_store);
- build_copy_store(&buf, T3, off + 3 * copy_word_size);
+ build_copy_store(&buf, GPR_T3, off + 3 * copy_word_size);
off += 4 * copy_word_size;
} while (off < 0);
}
if (pref_bias_copy_store) {
- pg_addiu(&buf, A2, A0, pref_bias_copy_store);
+ pg_addiu(&buf, GPR_A2, GPR_A0, pref_bias_copy_store);
uasm_l_copy_nopref(&l, buf);
off = 0;
do {
- build_copy_load(&buf, T0, off);
- build_copy_load(&buf, T1, off + copy_word_size);
- build_copy_load(&buf, T2, off + 2 * copy_word_size);
- build_copy_load(&buf, T3, off + 3 * copy_word_size);
- build_copy_store(&buf, T0, off);
- build_copy_store(&buf, T1, off + copy_word_size);
- build_copy_store(&buf, T2, off + 2 * copy_word_size);
- build_copy_store(&buf, T3, off + 3 * copy_word_size);
+ build_copy_load(&buf, GPR_T0, off);
+ build_copy_load(&buf, GPR_T1, off + copy_word_size);
+ build_copy_load(&buf, GPR_T2, off + 2 * copy_word_size);
+ build_copy_load(&buf, GPR_T3, off + 3 * copy_word_size);
+ build_copy_store(&buf, GPR_T0, off);
+ build_copy_store(&buf, GPR_T1, off + copy_word_size);
+ build_copy_store(&buf, GPR_T2, off + 2 * copy_word_size);
+ build_copy_store(&buf, GPR_T3, off + 3 * copy_word_size);
off += 4 * copy_word_size;
} while (off < half_copy_loop_size);
- pg_addiu(&buf, A1, A1, 2 * off);
- pg_addiu(&buf, A0, A0, 2 * off);
+ pg_addiu(&buf, GPR_A1, GPR_A1, 2 * off);
+ pg_addiu(&buf, GPR_A0, GPR_A0, 2 * off);
off = -off;
do {
- build_copy_load(&buf, T0, off);
- build_copy_load(&buf, T1, off + copy_word_size);
- build_copy_load(&buf, T2, off + 2 * copy_word_size);
- build_copy_load(&buf, T3, off + 3 * copy_word_size);
- build_copy_store(&buf, T0, off);
- build_copy_store(&buf, T1, off + copy_word_size);
- build_copy_store(&buf, T2, off + 2 * copy_word_size);
+ build_copy_load(&buf, GPR_T0, off);
+ build_copy_load(&buf, GPR_T1, off + copy_word_size);
+ build_copy_load(&buf, GPR_T2, off + 2 * copy_word_size);
+ build_copy_load(&buf, GPR_T3, off + 3 * copy_word_size);
+ build_copy_store(&buf, GPR_T0, off);
+ build_copy_store(&buf, GPR_T1, off + copy_word_size);
+ build_copy_store(&buf, GPR_T2, off + 2 * copy_word_size);
if (off == -(4 * copy_word_size))
- uasm_il_bne(&buf, &r, A2, A0,
+ uasm_il_bne(&buf, &r, GPR_A2, GPR_A0,
label_copy_nopref);
- build_copy_store(&buf, T3, off + 3 * copy_word_size);
+ build_copy_store(&buf, GPR_T3, off + 3 * copy_word_size);
off += 4 * copy_word_size;
} while (off < 0);
}
- uasm_i_jr(&buf, RA);
+ uasm_i_jr(&buf, GPR_RA);
uasm_i_nop(&buf);
BUG_ON(buf > &__copy_page_end);
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 4017fa0e2f68..69ea54bdc0c3 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -32,7 +32,9 @@
#include <asm/cacheflush.h>
#include <asm/cpu-type.h>
+#include <asm/mipsregs.h>
#include <asm/mmu_context.h>
+#include <asm/regdef.h>
#include <asm/uasm.h>
#include <asm/setup.h>
#include <asm/tlbex.h>
@@ -276,27 +278,6 @@ static inline void dump_handler(const char *symbol, const void *start, const voi
pr_debug("\tEND(%s)\n", symbol);
}
-/* The only general purpose registers allowed in TLB handlers. */
-#define K0 26
-#define K1 27
-
-/* Some CP0 registers */
-#define C0_INDEX 0, 0
-#define C0_ENTRYLO0 2, 0
-#define C0_TCBIND 2, 2
-#define C0_ENTRYLO1 3, 0
-#define C0_CONTEXT 4, 0
-#define C0_PAGEMASK 5, 0
-#define C0_PWBASE 5, 5
-#define C0_PWFIELD 5, 6
-#define C0_PWSIZE 5, 7
-#define C0_PWCTL 6, 6
-#define C0_BADVADDR 8, 0
-#define C0_PGD 9, 7
-#define C0_ENTRYHI 10, 0
-#define C0_EPC 14, 0
-#define C0_XCONTEXT 20, 0
-
#ifdef CONFIG_64BIT
# define GET_CONTEXT(buf, reg) UASM_i_MFC0(buf, reg, C0_XCONTEXT)
#else
@@ -356,30 +337,30 @@ static struct work_registers build_get_work_registers(u32 **p)
if (scratch_reg >= 0) {
/* Save in CPU local C0_KScratch? */
UASM_i_MTC0(p, 1, c0_kscratch(), scratch_reg);
- r.r1 = K0;
- r.r2 = K1;
- r.r3 = 1;
+ r.r1 = GPR_K0;
+ r.r2 = GPR_K1;
+ r.r3 = GPR_AT;
return r;
}
if (num_possible_cpus() > 1) {
/* Get smp_processor_id */
- UASM_i_CPUID_MFC0(p, K0, SMP_CPUID_REG);
- UASM_i_SRL_SAFE(p, K0, K0, SMP_CPUID_REGSHIFT);
+ UASM_i_CPUID_MFC0(p, GPR_K0, SMP_CPUID_REG);
+ UASM_i_SRL_SAFE(p, GPR_K0, GPR_K0, SMP_CPUID_REGSHIFT);
- /* handler_reg_save index in K0 */
- UASM_i_SLL(p, K0, K0, ilog2(sizeof(struct tlb_reg_save)));
+ /* handler_reg_save index in GPR_K0 */
+ UASM_i_SLL(p, GPR_K0, GPR_K0, ilog2(sizeof(struct tlb_reg_save)));
- UASM_i_LA(p, K1, (long)&handler_reg_save);
- UASM_i_ADDU(p, K0, K0, K1);
+ UASM_i_LA(p, GPR_K1, (long)&handler_reg_save);
+ UASM_i_ADDU(p, GPR_K0, GPR_K0, GPR_K1);
} else {
- UASM_i_LA(p, K0, (long)&handler_reg_save);
+ UASM_i_LA(p, GPR_K0, (long)&handler_reg_save);
}
- /* K0 now points to save area, save $1 and $2 */
- UASM_i_SW(p, 1, offsetof(struct tlb_reg_save, a), K0);
- UASM_i_SW(p, 2, offsetof(struct tlb_reg_save, b), K0);
+ /* GPR_K0 now points to save area, save $1 and $2 */
+ UASM_i_SW(p, 1, offsetof(struct tlb_reg_save, a), GPR_K0);
+ UASM_i_SW(p, 2, offsetof(struct tlb_reg_save, b), GPR_K0);
- r.r1 = K1;
+ r.r1 = GPR_K1;
r.r2 = 1;
r.r3 = 2;
return r;
@@ -392,9 +373,9 @@ static void build_restore_work_registers(u32 **p)
UASM_i_MFC0(p, 1, c0_kscratch(), scratch_reg);
return;
}
- /* K0 already points to save area, restore $1 and $2 */
- UASM_i_LW(p, 1, offsetof(struct tlb_reg_save, a), K0);
- UASM_i_LW(p, 2, offsetof(struct tlb_reg_save, b), K0);
+ /* GPR_K0 already points to save area, restore $1 and $2 */
+ UASM_i_LW(p, 1, offsetof(struct tlb_reg_save, a), GPR_K0);
+ UASM_i_LW(p, 2, offsetof(struct tlb_reg_save, b), GPR_K0);
}
#ifndef CONFIG_MIPS_PGD_C0_CONTEXT
@@ -413,22 +394,22 @@ static void build_r3000_tlb_refill_handler(void)
memset(tlb_handler, 0, sizeof(tlb_handler));
p = tlb_handler;
- uasm_i_mfc0(&p, K0, C0_BADVADDR);
- uasm_i_lui(&p, K1, uasm_rel_hi(pgdc)); /* cp0 delay */
- uasm_i_lw(&p, K1, uasm_rel_lo(pgdc), K1);
- uasm_i_srl(&p, K0, K0, 22); /* load delay */
- uasm_i_sll(&p, K0, K0, 2);
- uasm_i_addu(&p, K1, K1, K0);
- uasm_i_mfc0(&p, K0, C0_CONTEXT);
- uasm_i_lw(&p, K1, 0, K1); /* cp0 delay */
- uasm_i_andi(&p, K0, K0, 0xffc); /* load delay */
- uasm_i_addu(&p, K1, K1, K0);
- uasm_i_lw(&p, K0, 0, K1);
+ uasm_i_mfc0(&p, GPR_K0, C0_BADVADDR);
+ uasm_i_lui(&p, GPR_K1, uasm_rel_hi(pgdc)); /* cp0 delay */
+ uasm_i_lw(&p, GPR_K1, uasm_rel_lo(pgdc), GPR_K1);
+ uasm_i_srl(&p, GPR_K0, GPR_K0, 22); /* load delay */
+ uasm_i_sll(&p, GPR_K0, GPR_K0, 2);
+ uasm_i_addu(&p, GPR_K1, GPR_K1, GPR_K0);
+ uasm_i_mfc0(&p, GPR_K0, C0_CONTEXT);
+ uasm_i_lw(&p, GPR_K1, 0, GPR_K1); /* cp0 delay */
+ uasm_i_andi(&p, GPR_K0, GPR_K0, 0xffc); /* load delay */
+ uasm_i_addu(&p, GPR_K1, GPR_K1, GPR_K0);
+ uasm_i_lw(&p, GPR_K0, 0, GPR_K1);
uasm_i_nop(&p); /* load delay */
- uasm_i_mtc0(&p, K0, C0_ENTRYLO0);
- uasm_i_mfc0(&p, K1, C0_EPC); /* cp0 delay */
+ uasm_i_mtc0(&p, GPR_K0, C0_ENTRYLO0);
+ uasm_i_mfc0(&p, GPR_K1, C0_EPC); /* cp0 delay */
uasm_i_tlbwr(&p); /* cp0 delay */
- uasm_i_jr(&p, K1);
+ uasm_i_jr(&p, GPR_K1);
uasm_i_rfe(&p); /* branch delay */
if (p > tlb_handler + 32)
@@ -1276,11 +1257,11 @@ static void build_r4000_tlb_refill_handler(void)
memset(final_handler, 0, sizeof(final_handler));
if (IS_ENABLED(CONFIG_64BIT) && (scratch_reg >= 0 || scratchpad_available()) && use_bbit_insns()) {
- htlb_info = build_fast_tlb_refill_handler(&p, &l, &r, K0, K1,
+ htlb_info = build_fast_tlb_refill_handler(&p, &l, &r, GPR_K0, GPR_K1,
scratch_reg);
vmalloc_mode = refill_scratch;
} else {
- htlb_info.huge_pte = K0;
+ htlb_info.huge_pte = GPR_K0;
htlb_info.restore_scratch = 0;
htlb_info.need_reload_pte = true;
vmalloc_mode = refill_noscratch;
@@ -1290,29 +1271,29 @@ static void build_r4000_tlb_refill_handler(void)
if (bcm1250_m3_war()) {
unsigned int segbits = 44;
- uasm_i_dmfc0(&p, K0, C0_BADVADDR);
- uasm_i_dmfc0(&p, K1, C0_ENTRYHI);
- uasm_i_xor(&p, K0, K0, K1);
- uasm_i_dsrl_safe(&p, K1, K0, 62);
- uasm_i_dsrl_safe(&p, K0, K0, 12 + 1);
- uasm_i_dsll_safe(&p, K0, K0, 64 + 12 + 1 - segbits);
- uasm_i_or(&p, K0, K0, K1);
- uasm_il_bnez(&p, &r, K0, label_leave);
+ uasm_i_dmfc0(&p, GPR_K0, C0_BADVADDR);
+ uasm_i_dmfc0(&p, GPR_K1, C0_ENTRYHI);
+ uasm_i_xor(&p, GPR_K0, GPR_K0, GPR_K1);
+ uasm_i_dsrl_safe(&p, GPR_K1, GPR_K0, 62);
+ uasm_i_dsrl_safe(&p, GPR_K0, GPR_K0, 12 + 1);
+ uasm_i_dsll_safe(&p, GPR_K0, GPR_K0, 64 + 12 + 1 - segbits);
+ uasm_i_or(&p, GPR_K0, GPR_K0, GPR_K1);
+ uasm_il_bnez(&p, &r, GPR_K0, label_leave);
/* No need for uasm_i_nop */
}
#ifdef CONFIG_64BIT
- build_get_pmde64(&p, &l, &r, K0, K1); /* get pmd in K1 */
+ build_get_pmde64(&p, &l, &r, GPR_K0, GPR_K1); /* get pmd in GPR_K1 */
#else
- build_get_pgde32(&p, K0, K1); /* get pgd in K1 */
+ build_get_pgde32(&p, GPR_K0, GPR_K1); /* get pgd in GPR_K1 */
#endif
#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
- build_is_huge_pte(&p, &r, K0, K1, label_tlb_huge_update);
+ build_is_huge_pte(&p, &r, GPR_K0, GPR_K1, label_tlb_huge_update);
#endif
- build_get_ptep(&p, K0, K1);
- build_update_entries(&p, K0, K1);
+ build_get_ptep(&p, GPR_K0, GPR_K1);
+ build_update_entries(&p, GPR_K0, GPR_K1);
build_tlb_write_entry(&p, &l, &r, tlb_random);
uasm_l_leave(&l, p);
uasm_i_eret(&p); /* return from trap */
@@ -1320,14 +1301,14 @@ static void build_r4000_tlb_refill_handler(void)
#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
uasm_l_tlb_huge_update(&l, p);
if (htlb_info.need_reload_pte)
- UASM_i_LW(&p, htlb_info.huge_pte, 0, K1);
- build_huge_update_entries(&p, htlb_info.huge_pte, K1);
- build_huge_tlb_write_entry(&p, &l, &r, K0, tlb_random,
+ UASM_i_LW(&p, htlb_info.huge_pte, 0, GPR_K1);
+ build_huge_update_entries(&p, htlb_info.huge_pte, GPR_K1);
+ build_huge_tlb_write_entry(&p, &l, &r, GPR_K0, tlb_random,
htlb_info.restore_scratch);
#endif
#ifdef CONFIG_64BIT
- build_get_pgd_vmalloc64(&p, &l, &r, K0, K1, vmalloc_mode);
+ build_get_pgd_vmalloc64(&p, &l, &r, GPR_K0, GPR_K1, vmalloc_mode);
#endif
/*
@@ -1500,34 +1481,35 @@ static void build_loongson3_tlb_refill_handler(void)
memset(tlb_handler, 0, sizeof(tlb_handler));
if (check_for_high_segbits) {
- uasm_i_dmfc0(&p, K0, C0_BADVADDR);
- uasm_i_dsrl_safe(&p, K1, K0, PGDIR_SHIFT + PGD_TABLE_ORDER + PAGE_SHIFT - 3);
- uasm_il_beqz(&p, &r, K1, label_vmalloc);
+ uasm_i_dmfc0(&p, GPR_K0, C0_BADVADDR);
+ uasm_i_dsrl_safe(&p, GPR_K1, GPR_K0,
+ PGDIR_SHIFT + PGD_TABLE_ORDER + PAGE_SHIFT - 3);
+ uasm_il_beqz(&p, &r, GPR_K1, label_vmalloc);
uasm_i_nop(&p);
- uasm_il_bgez(&p, &r, K0, label_large_segbits_fault);
+ uasm_il_bgez(&p, &r, GPR_K0, label_large_segbits_fault);
uasm_i_nop(&p);
uasm_l_vmalloc(&l, p);
}
- uasm_i_dmfc0(&p, K1, C0_PGD);
+ uasm_i_dmfc0(&p, GPR_K1, C0_PGD);
- uasm_i_lddir(&p, K0, K1, 3); /* global page dir */
+ uasm_i_lddir(&p, GPR_K0, GPR_K1, 3); /* global page dir */
#ifndef __PAGETABLE_PMD_FOLDED
- uasm_i_lddir(&p, K1, K0, 1); /* middle page dir */
+ uasm_i_lddir(&p, GPR_K1, GPR_K0, 1); /* middle page dir */
#endif
- uasm_i_ldpte(&p, K1, 0); /* even */
- uasm_i_ldpte(&p, K1, 1); /* odd */
+ uasm_i_ldpte(&p, GPR_K1, 0); /* even */
+ uasm_i_ldpte(&p, GPR_K1, 1); /* odd */
uasm_i_tlbwr(&p);
/* restore page mask */
if (PM_DEFAULT_MASK >> 16) {
- uasm_i_lui(&p, K0, PM_DEFAULT_MASK >> 16);
- uasm_i_ori(&p, K0, K0, PM_DEFAULT_MASK & 0xffff);
- uasm_i_mtc0(&p, K0, C0_PAGEMASK);
+ uasm_i_lui(&p, GPR_K0, PM_DEFAULT_MASK >> 16);
+ uasm_i_ori(&p, GPR_K0, GPR_K0, PM_DEFAULT_MASK & 0xffff);
+ uasm_i_mtc0(&p, GPR_K0, C0_PAGEMASK);
} else if (PM_DEFAULT_MASK) {
- uasm_i_ori(&p, K0, 0, PM_DEFAULT_MASK);
- uasm_i_mtc0(&p, K0, C0_PAGEMASK);
+ uasm_i_ori(&p, GPR_K0, 0, PM_DEFAULT_MASK);
+ uasm_i_mtc0(&p, GPR_K0, C0_PAGEMASK);
} else {
uasm_i_mtc0(&p, 0, C0_PAGEMASK);
}
@@ -1536,8 +1518,8 @@ static void build_loongson3_tlb_refill_handler(void)
if (check_for_high_segbits) {
uasm_l_large_segbits_fault(&l, p);
- UASM_i_LA(&p, K1, (unsigned long)tlb_do_page_fault_0);
- uasm_i_jr(&p, K1);
+ UASM_i_LA(&p, GPR_K1, (unsigned long)tlb_do_page_fault_0);
+ uasm_i_jr(&p, GPR_K1);
uasm_i_nop(&p);
}
@@ -1903,11 +1885,11 @@ static void build_r3000_tlb_load_handler(void)
memset(labels, 0, sizeof(labels));
memset(relocs, 0, sizeof(relocs));
- build_r3000_tlbchange_handler_head(&p, K0, K1);
- build_pte_present(&p, &r, K0, K1, -1, label_nopage_tlbl);
+ build_r3000_tlbchange_handler_head(&p, GPR_K0, GPR_K1);
+ build_pte_present(&p, &r, GPR_K0, GPR_K1, -1, label_nopage_tlbl);
uasm_i_nop(&p); /* load delay */
- build_make_valid(&p, &r, K0, K1, -1);
- build_r3000_tlb_reload_write(&p, &l, &r, K0, K1);
+ build_make_valid(&p, &r, GPR_K0, GPR_K1, -1);
+ build_r3000_tlb_reload_write(&p, &l, &r, GPR_K0, GPR_K1);
uasm_l_nopage_tlbl(&l, p);
uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
@@ -1933,11 +1915,11 @@ static void build_r3000_tlb_store_handler(void)
memset(labels, 0, sizeof(labels));
memset(relocs, 0, sizeof(relocs));
- build_r3000_tlbchange_handler_head(&p, K0, K1);
- build_pte_writable(&p, &r, K0, K1, -1, label_nopage_tlbs);
+ build_r3000_tlbchange_handler_head(&p, GPR_K0, GPR_K1);
+ build_pte_writable(&p, &r, GPR_K0, GPR_K1, -1, label_nopage_tlbs);
uasm_i_nop(&p); /* load delay */
- build_make_write(&p, &r, K0, K1, -1);
- build_r3000_tlb_reload_write(&p, &l, &r, K0, K1);
+ build_make_write(&p, &r, GPR_K0, GPR_K1, -1);
+ build_r3000_tlb_reload_write(&p, &l, &r, GPR_K0, GPR_K1);
uasm_l_nopage_tlbs(&l, p);
uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
@@ -1963,11 +1945,11 @@ static void build_r3000_tlb_modify_handler(void)
memset(labels, 0, sizeof(labels));
memset(relocs, 0, sizeof(relocs));
- build_r3000_tlbchange_handler_head(&p, K0, K1);
- build_pte_modifiable(&p, &r, K0, K1, -1, label_nopage_tlbm);
+ build_r3000_tlbchange_handler_head(&p, GPR_K0, GPR_K1);
+ build_pte_modifiable(&p, &r, GPR_K0, GPR_K1, -1, label_nopage_tlbm);
uasm_i_nop(&p); /* load delay */
- build_make_write(&p, &r, K0, K1, -1);
- build_r3000_pte_reload_tlbwi(&p, K0, K1);
+ build_make_write(&p, &r, GPR_K0, GPR_K1, -1);
+ build_r3000_pte_reload_tlbwi(&p, GPR_K0, GPR_K1);
uasm_l_nopage_tlbm(&l, p);
uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
@@ -2083,14 +2065,14 @@ static void build_r4000_tlb_load_handler(void)
if (bcm1250_m3_war()) {
unsigned int segbits = 44;
- uasm_i_dmfc0(&p, K0, C0_BADVADDR);
- uasm_i_dmfc0(&p, K1, C0_ENTRYHI);
- uasm_i_xor(&p, K0, K0, K1);
- uasm_i_dsrl_safe(&p, K1, K0, 62);
- uasm_i_dsrl_safe(&p, K0, K0, 12 + 1);
- uasm_i_dsll_safe(&p, K0, K0, 64 + 12 + 1 - segbits);
- uasm_i_or(&p, K0, K0, K1);
- uasm_il_bnez(&p, &r, K0, label_leave);
+ uasm_i_dmfc0(&p, GPR_K0, C0_BADVADDR);
+ uasm_i_dmfc0(&p, GPR_K1, C0_ENTRYHI);
+ uasm_i_xor(&p, GPR_K0, GPR_K0, GPR_K1);
+ uasm_i_dsrl_safe(&p, GPR_K1, GPR_K0, 62);
+ uasm_i_dsrl_safe(&p, GPR_K0, GPR_K0, 12 + 1);
+ uasm_i_dsll_safe(&p, GPR_K0, GPR_K0, 64 + 12 + 1 - segbits);
+ uasm_i_or(&p, GPR_K0, GPR_K0, GPR_K1);
+ uasm_il_bnez(&p, &r, GPR_K0, label_leave);
/* No need for uasm_i_nop */
}
@@ -2233,9 +2215,9 @@ static void build_r4000_tlb_load_handler(void)
build_restore_work_registers(&p);
#ifdef CONFIG_CPU_MICROMIPS
if ((unsigned long)tlb_do_page_fault_0 & 1) {
- uasm_i_lui(&p, K0, uasm_rel_hi((long)tlb_do_page_fault_0));
- uasm_i_addiu(&p, K0, K0, uasm_rel_lo((long)tlb_do_page_fault_0));
- uasm_i_jr(&p, K0);
+ uasm_i_lui(&p, GPR_K0, uasm_rel_hi((long)tlb_do_page_fault_0));
+ uasm_i_addiu(&p, GPR_K0, GPR_K0, uasm_rel_lo((long)tlb_do_page_fault_0));
+ uasm_i_jr(&p, GPR_K0);
} else
#endif
uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
@@ -2289,9 +2271,9 @@ static void build_r4000_tlb_store_handler(void)
build_restore_work_registers(&p);
#ifdef CONFIG_CPU_MICROMIPS
if ((unsigned long)tlb_do_page_fault_1 & 1) {
- uasm_i_lui(&p, K0, uasm_rel_hi((long)tlb_do_page_fault_1));
- uasm_i_addiu(&p, K0, K0, uasm_rel_lo((long)tlb_do_page_fault_1));
- uasm_i_jr(&p, K0);
+ uasm_i_lui(&p, GPR_K0, uasm_rel_hi((long)tlb_do_page_fault_1));
+ uasm_i_addiu(&p, GPR_K0, GPR_K0, uasm_rel_lo((long)tlb_do_page_fault_1));
+ uasm_i_jr(&p, GPR_K0);
} else
#endif
uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
@@ -2346,9 +2328,9 @@ static void build_r4000_tlb_modify_handler(void)
build_restore_work_registers(&p);
#ifdef CONFIG_CPU_MICROMIPS
if ((unsigned long)tlb_do_page_fault_1 & 1) {
- uasm_i_lui(&p, K0, uasm_rel_hi((long)tlb_do_page_fault_1));
- uasm_i_addiu(&p, K0, K0, uasm_rel_lo((long)tlb_do_page_fault_1));
- uasm_i_jr(&p, K0);
+ uasm_i_lui(&p, GPR_K0, uasm_rel_hi((long)tlb_do_page_fault_1));
+ uasm_i_addiu(&p, GPR_K0, GPR_K0, uasm_rel_lo((long)tlb_do_page_fault_1));
+ uasm_i_jr(&p, GPR_K0);
} else
#endif
uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
diff --git a/arch/mips/mobileye/Makefile b/arch/mips/mobileye/Makefile
new file mode 100644
index 000000000000..315c06b689cf
--- /dev/null
+++ b/arch/mips/mobileye/Makefile
@@ -0,0 +1 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
diff --git a/arch/mips/mobileye/Platform b/arch/mips/mobileye/Platform
new file mode 100644
index 000000000000..c69f811dd13a
--- /dev/null
+++ b/arch/mips/mobileye/Platform
@@ -0,0 +1,15 @@
+#
+# Copyright (C) 2016 Imagination Technologies
+# Author: Paul Burton <paul.burton@mips.com>
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+
+load-$(CONFIG_MACH_EYEQ5) = 0xa800000808000000
+all-$(CONFIG_MACH_EYEQ5) += vmlinux.gz.itb
+
+its-y := vmlinux.its.S
+its-$(CONFIG_FIT_IMAGE_FDT_EPM5) += board-epm5.its.S
diff --git a/arch/mips/mobileye/board-epm5.its.S b/arch/mips/mobileye/board-epm5.its.S
new file mode 100644
index 000000000000..08e8c4f183d6
--- /dev/null
+++ b/arch/mips/mobileye/board-epm5.its.S
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
+/ {
+ images {
+ fdt-mobileye-epm5 {
+ description = "Mobileeye MP5 Device Tree";
+ data = /incbin/("boot/dts/mobileye/eyeq5-epm5.dtb");
+ type = "flat_dt";
+ arch = "mips";
+ compression = "none";
+ hash {
+ algo = "sha1";
+ };
+ };
+ };
+
+ configurations {
+ default = "conf-1";
+ conf-1 {
+ description = "Mobileye EPM5 Linux kernel";
+ kernel = "kernel";
+ fdt = "fdt-mobileye-epm5";
+ };
+ };
+};
diff --git a/arch/mips/mobileye/vmlinux.its.S b/arch/mips/mobileye/vmlinux.its.S
new file mode 100644
index 000000000000..3e254676540f
--- /dev/null
+++ b/arch/mips/mobileye/vmlinux.its.S
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/dts-v1/;
+
+/ {
+ description = KERNEL_NAME;
+ #address-cells = <ADDR_CELLS>;
+
+ images {
+ kernel {
+ description = KERNEL_NAME;
+ data = /incbin/(VMLINUX_BINARY);
+ type = "kernel";
+ arch = "mips";
+ os = "linux";
+ compression = VMLINUX_COMPRESSION;
+ load = /bits/ ADDR_BITS <VMLINUX_LOAD_ADDRESS>;
+ entry = /bits/ ADDR_BITS <VMLINUX_ENTRY_ADDRESS>;
+ hash {
+ algo = "sha1";
+ };
+ };
+ };
+
+ configurations {
+ default = "conf-default";
+
+ conf-default {
+ description = "Generic Linux kernel";
+ kernel = "kernel";
+ };
+ };
+};
diff --git a/arch/mips/pci/fixup-ath79.c b/arch/mips/pci/fixup-ath79.c
index 09a4ce53424f..6a6c4f58f7f4 100644
--- a/arch/mips/pci/fixup-ath79.c
+++ b/arch/mips/pci/fixup-ath79.c
@@ -9,7 +9,7 @@
int pcibios_plat_dev_init(struct pci_dev *dev)
{
- return PCIBIOS_SUCCESSFUL;
+ return 0;
}
int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
diff --git a/arch/mips/pci/fixup-lantiq.c b/arch/mips/pci/fixup-lantiq.c
index 13009666204f..8bcc136976dc 100644
--- a/arch/mips/pci/fixup-lantiq.c
+++ b/arch/mips/pci/fixup-lantiq.c
@@ -7,17 +7,8 @@
#include <linux/of_pci.h>
#include <linux/pci.h>
-int (*ltq_pci_plat_arch_init)(struct pci_dev *dev) = NULL;
-int (*ltq_pci_plat_dev_init)(struct pci_dev *dev) = NULL;
-
int pcibios_plat_dev_init(struct pci_dev *dev)
{
- if (ltq_pci_plat_arch_init)
- return ltq_pci_plat_arch_init(dev);
-
- if (ltq_pci_plat_dev_init)
- return ltq_pci_plat_dev_init(dev);
-
return 0;
}
diff --git a/arch/mips/pci/ops-tx4927.c b/arch/mips/pci/ops-tx4927.c
index f7802f100401..37087f4137ee 100644
--- a/arch/mips/pci/ops-tx4927.c
+++ b/arch/mips/pci/ops-tx4927.c
@@ -60,7 +60,7 @@ static int mkaddr(struct pci_bus *bus, unsigned int devfn, int where,
{
if (bus->parent == NULL &&
devfn >= PCI_DEVFN(TX4927_PCIC_MAX_DEVNU, 0))
- return -1;
+ return PCIBIOS_DEVICE_NOT_FOUND;
__raw_writel(((bus->number & 0xff) << 0x10)
| ((devfn & 0xff) << 0x08) | (where & 0xfc)
| (bus->parent ? 1 : 0),
@@ -69,7 +69,7 @@ static int mkaddr(struct pci_bus *bus, unsigned int devfn, int where,
__raw_writel((__raw_readl(&pcicptr->pcistatus) & 0x0000ffff)
| (PCI_STATUS_REC_MASTER_ABORT << 16),
&pcicptr->pcistatus);
- return 0;
+ return PCIBIOS_SUCCESSFUL;
}
static int check_abort(struct tx4927_pcic_reg __iomem *pcicptr)
@@ -140,10 +140,12 @@ static int tx4927_pci_config_read(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 *val)
{
struct tx4927_pcic_reg __iomem *pcicptr = pci_bus_to_pcicptr(bus);
+ int ret;
- if (mkaddr(bus, devfn, where, pcicptr)) {
- *val = 0xffffffff;
- return -1;
+ ret = mkaddr(bus, devfn, where, pcicptr);
+ if (ret != PCIBIOS_SUCCESSFUL) {
+ PCI_SET_ERROR_RESPONSE(val);
+ return ret;
}
switch (size) {
case 1:
@@ -162,9 +164,11 @@ static int tx4927_pci_config_write(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 val)
{
struct tx4927_pcic_reg __iomem *pcicptr = pci_bus_to_pcicptr(bus);
+ int ret;
- if (mkaddr(bus, devfn, where, pcicptr))
- return -1;
+ ret = mkaddr(bus, devfn, where, pcicptr);
+ if (ret != PCIBIOS_SUCCESSFUL)
+ return ret;
switch (size) {
case 1:
icd_writeb(val, where & 3, pcicptr);
diff --git a/arch/mips/ralink/timer.c b/arch/mips/ralink/timer.c
index fc503679a93d..54094f6e033e 100644
--- a/arch/mips/ralink/timer.c
+++ b/arch/mips/ralink/timer.c
@@ -6,11 +6,16 @@
* Copyright (C) 2013 John Crispin <john@phrozen.org>
*/
-#include <linux/platform_device.h>
+#include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/err.h>
#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
#include <linux/timer.h>
-#include <linux/of_gpio.h>
-#include <linux/clk.h>
+#include <linux/types.h>
#include <asm/mach-ralink/ralink_regs.h>
diff --git a/arch/mips/sgi-ip22/ip22-gio.c b/arch/mips/sgi-ip22/ip22-gio.c
index 81c9f0a8880b..a3cdcb289941 100644
--- a/arch/mips/sgi-ip22/ip22-gio.c
+++ b/arch/mips/sgi-ip22/ip22-gio.c
@@ -12,7 +12,7 @@
#include <asm/sgi/mc.h>
#include <asm/sgi/ip22.h>
-static struct bus_type gio_bus_type;
+static const struct bus_type gio_bus_type;
static struct {
const char *name;
@@ -378,7 +378,7 @@ static void ip22_check_gio(int slotno, unsigned long addr, int irq)
printk(KERN_INFO "GIO: slot %d : Empty\n", slotno);
}
-static struct bus_type gio_bus_type = {
+static const struct bus_type gio_bus_type = {
.name = "gio",
.dev_groups = gio_dev_groups,
.match = gio_bus_match,
diff --git a/arch/mips/sibyte/common/sb_tbprof.c b/arch/mips/sibyte/common/sb_tbprof.c
index 408db45efdc8..af5333986900 100644
--- a/arch/mips/sibyte/common/sb_tbprof.c
+++ b/arch/mips/sibyte/common/sb_tbprof.c
@@ -535,13 +535,14 @@ static const struct file_operations sbprof_tb_fops = {
.llseek = default_llseek,
};
-static struct class *tb_class;
+static const struct class tb_class = {
+ .name = "sb_tracebuffer",
+};
static struct device *tb_dev;
static int __init sbprof_tb_init(void)
{
struct device *dev;
- struct class *tbc;
int err;
if (register_chrdev(SBPROF_TB_MAJOR, DEVNAME, &sbprof_tb_fops)) {
@@ -550,15 +551,11 @@ static int __init sbprof_tb_init(void)
return -EIO;
}
- tbc = class_create("sb_tracebuffer");
- if (IS_ERR(tbc)) {
- err = PTR_ERR(tbc);
+ err = class_register(&tb_class);
+ if (err)
goto out_chrdev;
- }
-
- tb_class = tbc;
- dev = device_create(tbc, NULL, MKDEV(SBPROF_TB_MAJOR, 0), NULL, "tb");
+ dev = device_create(&tb_class, NULL, MKDEV(SBPROF_TB_MAJOR, 0), NULL, "tb");
if (IS_ERR(dev)) {
err = PTR_ERR(dev);
goto out_class;
@@ -573,7 +570,7 @@ static int __init sbprof_tb_init(void)
return 0;
out_class:
- class_destroy(tb_class);
+ class_unregister(&tb_class);
out_chrdev:
unregister_chrdev(SBPROF_TB_MAJOR, DEVNAME);
@@ -582,9 +579,9 @@ out_chrdev:
static void __exit sbprof_tb_cleanup(void)
{
- device_destroy(tb_class, MKDEV(SBPROF_TB_MAJOR, 0));
+ device_destroy(&tb_class, MKDEV(SBPROF_TB_MAJOR, 0));
unregister_chrdev(SBPROF_TB_MAJOR, DEVNAME);
- class_destroy(tb_class);
+ class_unregister(&tb_class);
}
module_init(sbprof_tb_init);
diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c
index b098a3c76ae9..1e67fecd466e 100644
--- a/arch/mips/txx9/generic/setup.c
+++ b/arch/mips/txx9/generic/setup.c
@@ -762,7 +762,7 @@ void __init txx9_aclc_init(unsigned long baseaddr, int irq,
{
}
-static struct bus_type txx9_sramc_subsys = {
+static const struct bus_type txx9_sramc_subsys = {
.name = "txx9_sram",
.dev_name = "txx9_sram",
};
diff --git a/arch/nios2/Kconfig b/arch/nios2/Kconfig
index 58d9565dc2c7..9c0e6eaeb005 100644
--- a/arch/nios2/Kconfig
+++ b/arch/nios2/Kconfig
@@ -2,6 +2,7 @@
config NIOS2
def_bool y
select ARCH_32BIT_OFF_T
+ select ARCH_HAS_CPU_CACHE_ALIASING
select ARCH_HAS_DMA_PREP_COHERENT
select ARCH_HAS_SYNC_DMA_FOR_CPU
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
@@ -15,6 +16,7 @@ config NIOS2
select GENERIC_IRQ_SHOW
select HAVE_ARCH_TRACEHOOK
select HAVE_ARCH_KGDB
+ select HAVE_PAGE_SIZE_4KB
select IRQ_DOMAIN
select LOCK_MM_AND_FIND_VMA
select MODULES_USE_ELF_RELA
diff --git a/arch/nios2/include/asm/cachetype.h b/arch/nios2/include/asm/cachetype.h
new file mode 100644
index 000000000000..eb9c416b8a1c
--- /dev/null
+++ b/arch/nios2/include/asm/cachetype.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_NIOS2_CACHETYPE_H
+#define __ASM_NIOS2_CACHETYPE_H
+
+#include <asm/page.h>
+#include <asm/cache.h>
+
+#define cpu_dcache_is_aliasing() (NIOS2_DCACHE_SIZE > PAGE_SIZE)
+
+#endif
diff --git a/arch/nios2/include/asm/page.h b/arch/nios2/include/asm/page.h
index 0ae7d9ce369b..0722f88e63cc 100644
--- a/arch/nios2/include/asm/page.h
+++ b/arch/nios2/include/asm/page.h
@@ -21,7 +21,7 @@
/*
* PAGE_SHIFT determines the page size
*/
-#define PAGE_SHIFT 12
+#define PAGE_SHIFT CONFIG_PAGE_SHIFT
#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE - 1))
diff --git a/arch/nios2/include/asm/pgtable.h b/arch/nios2/include/asm/pgtable.h
index 5144506dfa69..d052dfcbe8d3 100644
--- a/arch/nios2/include/asm/pgtable.h
+++ b/arch/nios2/include/asm/pgtable.h
@@ -178,6 +178,8 @@ static inline void set_pte(pte_t *ptep, pte_t pteval)
*ptep = pteval;
}
+#define PFN_PTE_SHIFT 0
+
static inline void set_ptes(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte, unsigned int nr)
{
diff --git a/arch/nios2/kernel/prom.c b/arch/nios2/kernel/prom.c
index 8d98af5c7201..9a8393e6b4a8 100644
--- a/arch/nios2/kernel/prom.c
+++ b/arch/nios2/kernel/prom.c
@@ -21,7 +21,8 @@
void __init early_init_devtree(void *params)
{
- __be32 *dtb = (u32 *)__dtb_start;
+ __be32 __maybe_unused *dtb = (u32 *)__dtb_start;
+
#if defined(CONFIG_NIOS2_DTB_AT_PHYS_ADDR)
if (be32_to_cpup((__be32 *)CONFIG_NIOS2_DTB_PHYS_ADDR) ==
OF_DT_HEADER) {
@@ -30,8 +31,11 @@ void __init early_init_devtree(void *params)
return;
}
#endif
+
+#ifdef CONFIG_NIOS2_DTB_SOURCE_BOOL
if (be32_to_cpu((__be32) *dtb) == OF_DT_HEADER)
params = (void *)__dtb_start;
+#endif
early_init_dt_scan(params);
}
diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig
index fd9bb76a610b..3586cda55bde 100644
--- a/arch/openrisc/Kconfig
+++ b/arch/openrisc/Kconfig
@@ -25,6 +25,7 @@ config OPENRISC
select GENERIC_CPU_DEVICES
select HAVE_PCI
select HAVE_UID16
+ select HAVE_PAGE_SIZE_8KB
select GENERIC_ATOMIC64
select GENERIC_CLOCKEVENTS_BROADCAST
select GENERIC_SMP_IDLE_THREAD
diff --git a/arch/openrisc/include/asm/fixmap.h b/arch/openrisc/include/asm/fixmap.h
index ad78e50b7ba3..ecdb98a5839f 100644
--- a/arch/openrisc/include/asm/fixmap.h
+++ b/arch/openrisc/include/asm/fixmap.h
@@ -50,35 +50,6 @@ enum fixed_addresses {
/* FIXADDR_BOTTOM might be a better name here... */
#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
-#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
-#define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
-
-/*
- * 'index to address' translation. If anyone tries to use the idx
- * directly without tranlation, we catch the bug with a NULL-deference
- * kernel oops. Illegal ranges of incoming indices are caught too.
- */
-static __always_inline unsigned long fix_to_virt(const unsigned int idx)
-{
- /*
- * this branch gets completely eliminated after inlining,
- * except when someone tries to use fixaddr indices in an
- * illegal way. (such as mixing up address types or using
- * out-of-range indices).
- *
- * If it doesn't get removed, the linker will complain
- * loudly with a reasonably clear error message..
- */
- if (idx >= __end_of_fixed_addresses)
- BUG();
-
- return __fix_to_virt(idx);
-}
-
-static inline unsigned long virt_to_fix(const unsigned long vaddr)
-{
- BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
- return __virt_to_fix(vaddr);
-}
+#include <asm-generic/fixmap.h>
#endif
diff --git a/arch/openrisc/include/asm/page.h b/arch/openrisc/include/asm/page.h
index 44fc1fd56717..1d5913f67c31 100644
--- a/arch/openrisc/include/asm/page.h
+++ b/arch/openrisc/include/asm/page.h
@@ -18,7 +18,7 @@
/* PAGE_SHIFT determines the page size */
-#define PAGE_SHIFT 13
+#define PAGE_SHIFT CONFIG_PAGE_SHIFT
#ifdef __ASSEMBLY__
#define PAGE_SIZE (1 << PAGE_SHIFT)
#else
@@ -77,11 +77,6 @@ static inline unsigned long virt_to_pfn(const void *kaddr)
return __pa(kaddr) >> PAGE_SHIFT;
}
-static inline void * pfn_to_virt(unsigned long pfn)
-{
- return (void *)((unsigned long)__va(pfn) << PAGE_SHIFT);
-}
-
#define virt_to_page(addr) \
(mem_map + (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT))
diff --git a/arch/openrisc/kernel/setup.c b/arch/openrisc/kernel/setup.c
index 9cf7fb60441f..be56eaafc8b9 100644
--- a/arch/openrisc/kernel/setup.c
+++ b/arch/openrisc/kernel/setup.c
@@ -255,6 +255,9 @@ void calibrate_delay(void)
void __init setup_arch(char **cmdline_p)
{
+ /* setup memblock allocator */
+ setup_memory();
+
unflatten_and_copy_device_tree();
setup_cpuinfo();
@@ -278,9 +281,6 @@ void __init setup_arch(char **cmdline_p)
}
#endif
- /* setup memblock allocator */
- setup_memory();
-
/* paging_init() sets up the MMU and marks all pages as reserved */
paging_init();
diff --git a/arch/openrisc/kernel/smp.c b/arch/openrisc/kernel/smp.c
index 1c5a2d71d675..86da4bc5ee0b 100644
--- a/arch/openrisc/kernel/smp.c
+++ b/arch/openrisc/kernel/smp.c
@@ -57,10 +57,6 @@ static void boot_secondary(unsigned int cpu, struct task_struct *idle)
spin_unlock(&boot_lock);
}
-void __init smp_prepare_boot_cpu(void)
-{
-}
-
void __init smp_init_cpus(void)
{
struct device_node *cpu;
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 5c845e8d59d9..daafeb20f993 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -8,11 +8,12 @@ config PARISC
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_SYSCALL_TRACEPOINTS
select ARCH_WANT_FRAME_POINTERS
+ select ARCH_HAS_CPU_CACHE_ALIASING
select ARCH_HAS_DMA_ALLOC if PA11
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_STRICT_KERNEL_RWX
select ARCH_HAS_STRICT_MODULE_RWX
- select ARCH_HAS_UBSAN_SANITIZE_ALL
+ select ARCH_HAS_UBSAN
select ARCH_HAS_PTE_SPECIAL
select ARCH_NO_SG_CHAIN
select ARCH_SUPPORTS_HUGETLBFS if PA20
@@ -237,9 +238,9 @@ config PARISC_HUGE_KERNEL
def_bool y if !MODULES || UBSAN || FTRACE || COMPILE_TEST
config MLONGCALLS
- def_bool y if PARISC_HUGE_KERNEL
bool "Enable the -mlong-calls compiler option for big kernels" if !PARISC_HUGE_KERNEL
depends on PA8X00
+ default PARISC_HUGE_KERNEL
help
If you configure the kernel to include many drivers built-in instead
as modules, the kernel executable may become too big, so that the
@@ -254,9 +255,9 @@ config MLONGCALLS
Enabling this option will probably slow down your kernel.
config 64BIT
- def_bool y if "$(ARCH)" = "parisc64"
bool "64-bit kernel" if "$(ARCH)" = "parisc"
depends on PA8X00
+ default "$(ARCH)" = "parisc64"
help
Enable this if you want to support 64bit kernel on PA-RISC platform.
@@ -273,6 +274,7 @@ choice
config PARISC_PAGE_SIZE_4KB
bool "4KB"
+ select HAVE_PAGE_SIZE_4KB
help
This lets you select the page size of the kernel. For best
performance, a page size of 16KB is recommended. For best
@@ -288,10 +290,12 @@ config PARISC_PAGE_SIZE_4KB
config PARISC_PAGE_SIZE_16KB
bool "16KB"
+ select HAVE_PAGE_SIZE_16KB
depends on PA8X00 && BROKEN && !KFENCE
config PARISC_PAGE_SIZE_64KB
bool "64KB"
+ select HAVE_PAGE_SIZE_64KB
depends on PA8X00 && BROKEN && !KFENCE
endchoice
diff --git a/arch/parisc/include/asm/assembly.h b/arch/parisc/include/asm/assembly.h
index 5937d5edaba1..000a28e1c5e8 100644
--- a/arch/parisc/include/asm/assembly.h
+++ b/arch/parisc/include/asm/assembly.h
@@ -97,26 +97,28 @@
* version takes two arguments: a src and destination register.
* However, the source and destination registers can not be
* the same register.
+ *
+ * We use add,l to avoid clobbering the C/B bits in the PSW.
*/
.macro tophys grvirt, grphys
- ldil L%(__PAGE_OFFSET), \grphys
- sub \grvirt, \grphys, \grphys
+ ldil L%(-__PAGE_OFFSET), \grphys
+ addl \grvirt, \grphys, \grphys
.endm
-
+
.macro tovirt grphys, grvirt
ldil L%(__PAGE_OFFSET), \grvirt
- add \grphys, \grvirt, \grvirt
+ addl \grphys, \grvirt, \grvirt
.endm
.macro tophys_r1 gr
- ldil L%(__PAGE_OFFSET), %r1
- sub \gr, %r1, \gr
+ ldil L%(-__PAGE_OFFSET), %r1
+ addl \gr, %r1, \gr
.endm
-
+
.macro tovirt_r1 gr
ldil L%(__PAGE_OFFSET), %r1
- add \gr, %r1, \gr
+ addl \gr, %r1, \gr
.endm
.macro delay value
diff --git a/arch/parisc/include/asm/cachetype.h b/arch/parisc/include/asm/cachetype.h
new file mode 100644
index 000000000000..e0868a1d3c47
--- /dev/null
+++ b/arch/parisc/include/asm/cachetype.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_PARISC_CACHETYPE_H
+#define __ASM_PARISC_CACHETYPE_H
+
+#include <linux/types.h>
+
+#define cpu_dcache_is_aliasing() true
+
+#endif
diff --git a/arch/parisc/include/asm/checksum.h b/arch/parisc/include/asm/checksum.h
index 3c43baca7b39..2aceebcd695c 100644
--- a/arch/parisc/include/asm/checksum.h
+++ b/arch/parisc/include/asm/checksum.h
@@ -40,7 +40,7 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
" addc %0, %5, %0\n"
" addc %0, %3, %0\n"
"1: ldws,ma 4(%1), %3\n"
-" addib,< 0, %2, 1b\n"
+" addib,> -1, %2, 1b\n"
" addc %0, %3, %0\n"
"\n"
" extru %0, 31, 16, %4\n"
@@ -126,6 +126,7 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
** Try to keep 4 registers with "live" values ahead of the ALU.
*/
+" depdi 0, 31, 32, %0\n"/* clear upper half of incoming checksum */
" ldd,ma 8(%1), %4\n" /* get 1st saddr word */
" ldd,ma 8(%2), %5\n" /* get 1st daddr word */
" add %4, %0, %0\n"
@@ -137,8 +138,8 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
" add,dc %3, %0, %0\n" /* fold in proto+len | carry bit */
" extrd,u %0, 31, 32, %4\n"/* copy upper half down */
" depdi 0, 31, 32, %0\n"/* clear upper half */
-" add %4, %0, %0\n" /* fold into 32-bits */
-" addc 0, %0, %0\n" /* add carry */
+" add,dc %4, %0, %0\n" /* fold into 32-bits, plus carry */
+" addc 0, %0, %0\n" /* add final carry */
#else
@@ -163,7 +164,8 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
" ldw,ma 4(%2), %7\n" /* 4th daddr */
" addc %6, %0, %0\n"
" addc %7, %0, %0\n"
-" addc %3, %0, %0\n" /* fold in proto+len, catch carry */
+" addc %3, %0, %0\n" /* fold in proto+len */
+" addc 0, %0, %0\n" /* add carry */
#endif
: "=r" (sum), "=r" (saddr), "=r" (daddr), "=r" (len),
diff --git a/arch/parisc/include/asm/mman.h b/arch/parisc/include/asm/mman.h
new file mode 100644
index 000000000000..47c5a1991d10
--- /dev/null
+++ b/arch/parisc/include/asm/mman.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_MMAN_H__
+#define __ASM_MMAN_H__
+
+#include <uapi/asm/mman.h>
+
+/* PARISC cannot allow mdwe as it needs writable stacks */
+static inline bool arch_memory_deny_write_exec_supported(void)
+{
+ return false;
+}
+#define arch_memory_deny_write_exec_supported arch_memory_deny_write_exec_supported
+
+#endif /* __ASM_MMAN_H__ */
diff --git a/arch/parisc/include/asm/page.h b/arch/parisc/include/asm/page.h
index 667e703c0e8f..ad4e15d12ed1 100644
--- a/arch/parisc/include/asm/page.h
+++ b/arch/parisc/include/asm/page.h
@@ -4,15 +4,7 @@
#include <linux/const.h>
-#if defined(CONFIG_PARISC_PAGE_SIZE_4KB)
-# define PAGE_SHIFT 12
-#elif defined(CONFIG_PARISC_PAGE_SIZE_16KB)
-# define PAGE_SHIFT 14
-#elif defined(CONFIG_PARISC_PAGE_SIZE_64KB)
-# define PAGE_SHIFT 16
-#else
-# error "unknown default kernel page size"
-#endif
+#define PAGE_SHIFT CONFIG_PAGE_SHIFT
#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
diff --git a/arch/parisc/include/asm/parisc-device.h b/arch/parisc/include/asm/parisc-device.h
index 4de3b391d812..7ddd7f433367 100644
--- a/arch/parisc/include/asm/parisc-device.h
+++ b/arch/parisc/include/asm/parisc-device.h
@@ -61,7 +61,7 @@ parisc_get_drvdata(struct parisc_device *d)
return dev_get_drvdata(&d->dev);
}
-extern struct bus_type parisc_bus_type;
+extern const struct bus_type parisc_bus_type;
int iosapic_serial_irq(struct parisc_device *dev);
diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
index c7ff339732ba..ac19d685e4a5 100644
--- a/arch/parisc/kernel/drivers.c
+++ b/arch/parisc/kernel/drivers.c
@@ -618,7 +618,7 @@ static struct attribute *parisc_device_attrs[] = {
};
ATTRIBUTE_GROUPS(parisc_device);
-struct bus_type parisc_bus_type = {
+const struct bus_type parisc_bus_type = {
.name = "parisc",
.match = parisc_generic_match,
.uevent = parisc_uevent,
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index 2f81bfd4f15e..dff66be65d29 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -498,7 +498,7 @@ asmlinkage void do_cpu_irq_mask(struct pt_regs *regs)
old_regs = set_irq_regs(regs);
local_irq_disable();
- irq_enter();
+ irq_enter_rcu();
eirr_val = mfctl(23) & cpu_eiem & per_cpu(local_ack_eiem, cpu);
if (!eirr_val)
@@ -533,7 +533,7 @@ asmlinkage void do_cpu_irq_mask(struct pt_regs *regs)
#endif /* CONFIG_IRQSTACKS */
out:
- irq_exit();
+ irq_exit_rcu();
set_irq_regs(old_regs);
return;
diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c
index c520e551a165..71e596ca5a86 100644
--- a/arch/parisc/kernel/unaligned.c
+++ b/arch/parisc/kernel/unaligned.c
@@ -169,6 +169,7 @@ static int emulate_ldw(struct pt_regs *regs, int toreg, int flop)
static int emulate_ldd(struct pt_regs *regs, int toreg, int flop)
{
unsigned long saddr = regs->ior;
+ unsigned long shift, temp1;
__u64 val = 0;
ASM_EXCEPTIONTABLE_VAR(ret);
@@ -180,25 +181,22 @@ static int emulate_ldd(struct pt_regs *regs, int toreg, int flop)
#ifdef CONFIG_64BIT
__asm__ __volatile__ (
-" depd,z %3,60,3,%%r19\n" /* r19=(ofs&7)*8 */
-" mtsp %4, %%sr1\n"
-" depd %%r0,63,3,%3\n"
-"1: ldd 0(%%sr1,%3),%0\n"
-"2: ldd 8(%%sr1,%3),%%r20\n"
-" subi 64,%%r19,%%r19\n"
-" mtsar %%r19\n"
-" shrpd %0,%%r20,%%sar,%0\n"
+" depd,z %2,60,3,%3\n" /* shift=(ofs&7)*8 */
+" mtsp %5, %%sr1\n"
+" depd %%r0,63,3,%2\n"
+"1: ldd 0(%%sr1,%2),%0\n"
+"2: ldd 8(%%sr1,%2),%4\n"
+" subi 64,%3,%3\n"
+" mtsar %3\n"
+" shrpd %0,%4,%%sar,%0\n"
"3: \n"
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 3b, "%1")
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 3b, "%1")
- : "=r" (val), "+r" (ret)
- : "0" (val), "r" (saddr), "r" (regs->isr)
- : "r19", "r20" );
+ : "+r" (val), "+r" (ret), "+r" (saddr), "=&r" (shift), "=&r" (temp1)
+ : "r" (regs->isr) );
#else
- {
- unsigned long shift, temp1;
__asm__ __volatile__ (
-" zdep %2,29,2,%3\n" /* r19=(ofs&3)*8 */
+" zdep %2,29,2,%3\n" /* shift=(ofs&3)*8 */
" mtsp %5, %%sr1\n"
" dep %%r0,31,2,%2\n"
"1: ldw 0(%%sr1,%2),%0\n"
@@ -214,7 +212,6 @@ static int emulate_ldd(struct pt_regs *regs, int toreg, int flop)
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(3b, 4b, "%1")
: "+r" (val), "+r" (ret), "+r" (saddr), "=&r" (shift), "=&r" (temp1)
: "r" (regs->isr) );
- }
#endif
DPRINTF("val = 0x%llx\n", val);
@@ -399,6 +396,13 @@ void handle_unaligned(struct pt_regs *regs)
if (!unaligned_enabled)
goto force_sigbus;
+ } else {
+ static DEFINE_RATELIMIT_STATE(kernel_ratelimit, 5 * HZ, 5);
+ if (!(current->thread.flags & PARISC_UAC_NOPRINT) &&
+ __ratelimit(&kernel_ratelimit))
+ pr_warn("Kernel: unaligned access to " RFMT " in %pS "
+ "(iir " RFMT ")\n",
+ regs->ior, (void *)regs->iaoq[0], regs->iir);
}
/* handle modification - OK, it's ugly, see the instruction manual */
diff --git a/arch/parisc/math-emu/dfsqrt.c b/arch/parisc/math-emu/dfsqrt.c
index 63d339c81c14..e3a3a19b966b 100644
--- a/arch/parisc/math-emu/dfsqrt.c
+++ b/arch/parisc/math-emu/dfsqrt.c
@@ -15,7 +15,7 @@
* Double Floating-point Square Root
*
* External Interfaces:
- * dbl_fsqrt(srcptr,nullptr,dstptr,status)
+ * dbl_fsqrt(srcptr,_nullptr,dstptr,status)
*
* Internal Interfaces:
*
@@ -37,7 +37,7 @@
unsigned int
dbl_fsqrt(
dbl_floating_point *srcptr,
- unsigned int *nullptr,
+ unsigned int *_nullptr,
dbl_floating_point *dstptr,
unsigned int *status)
{
diff --git a/arch/parisc/math-emu/fcnvff.c b/arch/parisc/math-emu/fcnvff.c
index 0530e6127797..61e489704c86 100644
--- a/arch/parisc/math-emu/fcnvff.c
+++ b/arch/parisc/math-emu/fcnvff.c
@@ -16,8 +16,8 @@
* Double Floating-point to Single Floating-point
*
* External Interfaces:
- * dbl_to_sgl_fcnvff(srcptr,nullptr,dstptr,status)
- * sgl_to_dbl_fcnvff(srcptr,nullptr,dstptr,status)
+ * dbl_to_sgl_fcnvff(srcptr,_nullptr,dstptr,status)
+ * sgl_to_dbl_fcnvff(srcptr,_nullptr,dstptr,status)
*
* Internal Interfaces:
*
@@ -40,7 +40,7 @@
int
sgl_to_dbl_fcnvff(
sgl_floating_point *srcptr,
- unsigned int *nullptr,
+ unsigned int *_nullptr,
dbl_floating_point *dstptr,
unsigned int *status)
{
@@ -127,7 +127,7 @@ sgl_to_dbl_fcnvff(
int
dbl_to_sgl_fcnvff(
dbl_floating_point *srcptr,
- unsigned int *nullptr,
+ unsigned int *_nullptr,
sgl_floating_point *dstptr,
unsigned int *status)
{
diff --git a/arch/parisc/math-emu/fcnvfu.c b/arch/parisc/math-emu/fcnvfu.c
index c971618a6f3c..c31790ceecca 100644
--- a/arch/parisc/math-emu/fcnvfu.c
+++ b/arch/parisc/math-emu/fcnvfu.c
@@ -15,10 +15,10 @@
* Floating-point to Unsigned Fixed-point Converts
*
* External Interfaces:
- * dbl_to_dbl_fcnvfu(srcptr,nullptr,dstptr,status)
- * dbl_to_sgl_fcnvfu(srcptr,nullptr,dstptr,status)
- * sgl_to_dbl_fcnvfu(srcptr,nullptr,dstptr,status)
- * sgl_to_sgl_fcnvfu(srcptr,nullptr,dstptr,status)
+ * dbl_to_dbl_fcnvfu(srcptr,_nullptr,dstptr,status)
+ * dbl_to_sgl_fcnvfu(srcptr,_nullptr,dstptr,status)
+ * sgl_to_dbl_fcnvfu(srcptr,_nullptr,dstptr,status)
+ * sgl_to_sgl_fcnvfu(srcptr,_nullptr,dstptr,status)
*
* Internal Interfaces:
*
@@ -45,7 +45,7 @@
int
sgl_to_sgl_fcnvfu(
sgl_floating_point *srcptr,
- unsigned int *nullptr,
+ unsigned int *_nullptr,
unsigned int *dstptr,
unsigned int *status)
{
@@ -166,7 +166,7 @@ sgl_to_sgl_fcnvfu(
int
sgl_to_dbl_fcnvfu(
sgl_floating_point *srcptr,
- unsigned int *nullptr,
+ unsigned int *_nullptr,
dbl_unsigned *dstptr,
unsigned int *status)
{
@@ -285,7 +285,7 @@ sgl_to_dbl_fcnvfu(
*/
/*ARGSUSED*/
int
-dbl_to_sgl_fcnvfu (dbl_floating_point * srcptr, unsigned int *nullptr,
+dbl_to_sgl_fcnvfu (dbl_floating_point * srcptr, unsigned int *_nullptr,
unsigned int *dstptr, unsigned int *status)
{
register unsigned int srcp1, srcp2, result;
@@ -408,7 +408,7 @@ dbl_to_sgl_fcnvfu (dbl_floating_point * srcptr, unsigned int *nullptr,
*/
/*ARGSUSED*/
int
-dbl_to_dbl_fcnvfu (dbl_floating_point * srcptr, unsigned int *nullptr,
+dbl_to_dbl_fcnvfu (dbl_floating_point * srcptr, unsigned int *_nullptr,
dbl_unsigned * dstptr, unsigned int *status)
{
register int src_exponent;
diff --git a/arch/parisc/math-emu/fcnvfut.c b/arch/parisc/math-emu/fcnvfut.c
index 5b657f852578..2cf1daf3b7ad 100644
--- a/arch/parisc/math-emu/fcnvfut.c
+++ b/arch/parisc/math-emu/fcnvfut.c
@@ -15,10 +15,10 @@
* Floating-point to Unsigned Fixed-point Converts with Truncation
*
* External Interfaces:
- * dbl_to_dbl_fcnvfut(srcptr,nullptr,dstptr,status)
- * dbl_to_sgl_fcnvfut(srcptr,nullptr,dstptr,status)
- * sgl_to_dbl_fcnvfut(srcptr,nullptr,dstptr,status)
- * sgl_to_sgl_fcnvfut(srcptr,nullptr,dstptr,status)
+ * dbl_to_dbl_fcnvfut(srcptr,_nullptr,dstptr,status)
+ * dbl_to_sgl_fcnvfut(srcptr,_nullptr,dstptr,status)
+ * sgl_to_dbl_fcnvfut(srcptr,_nullptr,dstptr,status)
+ * sgl_to_sgl_fcnvfut(srcptr,_nullptr,dstptr,status)
*
* Internal Interfaces:
*
@@ -44,7 +44,7 @@
*/
/*ARGSUSED*/
int
-sgl_to_sgl_fcnvfut (sgl_floating_point * srcptr, unsigned int *nullptr,
+sgl_to_sgl_fcnvfut (sgl_floating_point * srcptr, unsigned int *_nullptr,
unsigned int *dstptr, unsigned int *status)
{
register unsigned int src, result;
@@ -113,7 +113,7 @@ sgl_to_sgl_fcnvfut (sgl_floating_point * srcptr, unsigned int *nullptr,
*/
/*ARGSUSED*/
int
-sgl_to_dbl_fcnvfut (sgl_floating_point * srcptr, unsigned int *nullptr,
+sgl_to_dbl_fcnvfut (sgl_floating_point * srcptr, unsigned int *_nullptr,
dbl_unsigned * dstptr, unsigned int *status)
{
register int src_exponent;
@@ -183,7 +183,7 @@ sgl_to_dbl_fcnvfut (sgl_floating_point * srcptr, unsigned int *nullptr,
*/
/*ARGSUSED*/
int
-dbl_to_sgl_fcnvfut (dbl_floating_point * srcptr, unsigned int *nullptr,
+dbl_to_sgl_fcnvfut (dbl_floating_point * srcptr, unsigned int *_nullptr,
unsigned int *dstptr, unsigned int *status)
{
register unsigned int srcp1, srcp2, result;
@@ -252,7 +252,7 @@ dbl_to_sgl_fcnvfut (dbl_floating_point * srcptr, unsigned int *nullptr,
*/
/*ARGSUSED*/
int
-dbl_to_dbl_fcnvfut (dbl_floating_point * srcptr, unsigned int *nullptr,
+dbl_to_dbl_fcnvfut (dbl_floating_point * srcptr, unsigned int *_nullptr,
dbl_unsigned * dstptr, unsigned int *status)
{
register int src_exponent;
diff --git a/arch/parisc/math-emu/fcnvfx.c b/arch/parisc/math-emu/fcnvfx.c
index 5e153078d803..99bd61479452 100644
--- a/arch/parisc/math-emu/fcnvfx.c
+++ b/arch/parisc/math-emu/fcnvfx.c
@@ -18,10 +18,10 @@
* Double Floating-point to Double Fixed-point
*
* External Interfaces:
- * dbl_to_dbl_fcnvfx(srcptr,nullptr,dstptr,status)
- * dbl_to_sgl_fcnvfx(srcptr,nullptr,dstptr,status)
- * sgl_to_dbl_fcnvfx(srcptr,nullptr,dstptr,status)
- * sgl_to_sgl_fcnvfx(srcptr,nullptr,dstptr,status)
+ * dbl_to_dbl_fcnvfx(srcptr,_nullptr,dstptr,status)
+ * dbl_to_sgl_fcnvfx(srcptr,_nullptr,dstptr,status)
+ * sgl_to_dbl_fcnvfx(srcptr,_nullptr,dstptr,status)
+ * sgl_to_sgl_fcnvfx(srcptr,_nullptr,dstptr,status)
*
* Internal Interfaces:
*
@@ -44,7 +44,7 @@
int
sgl_to_sgl_fcnvfx(
sgl_floating_point *srcptr,
- sgl_floating_point *nullptr,
+ sgl_floating_point *_nullptr,
int *dstptr,
sgl_floating_point *status)
{
@@ -141,7 +141,7 @@ sgl_to_sgl_fcnvfx(
int
sgl_to_dbl_fcnvfx(
sgl_floating_point *srcptr,
- unsigned int *nullptr,
+ unsigned int *_nullptr,
dbl_integer *dstptr,
unsigned int *status)
{
@@ -262,7 +262,7 @@ sgl_to_dbl_fcnvfx(
int
dbl_to_sgl_fcnvfx(
dbl_floating_point *srcptr,
- unsigned int *nullptr,
+ unsigned int *_nullptr,
int *dstptr,
unsigned int *status)
{
@@ -373,7 +373,7 @@ dbl_to_sgl_fcnvfx(
int
dbl_to_dbl_fcnvfx(
dbl_floating_point *srcptr,
- unsigned int *nullptr,
+ unsigned int *_nullptr,
dbl_integer *dstptr,
unsigned int *status)
{
diff --git a/arch/parisc/math-emu/fcnvfxt.c b/arch/parisc/math-emu/fcnvfxt.c
index ebec31e40d01..3b7cc62257d0 100644
--- a/arch/parisc/math-emu/fcnvfxt.c
+++ b/arch/parisc/math-emu/fcnvfxt.c
@@ -18,10 +18,10 @@
* Double Floating-point to Double Fixed-point /w truncated result
*
* External Interfaces:
- * dbl_to_dbl_fcnvfxt(srcptr,nullptr,dstptr,status)
- * dbl_to_sgl_fcnvfxt(srcptr,nullptr,dstptr,status)
- * sgl_to_dbl_fcnvfxt(srcptr,nullptr,dstptr,status)
- * sgl_to_sgl_fcnvfxt(srcptr,nullptr,dstptr,status)
+ * dbl_to_dbl_fcnvfxt(srcptr,_nullptr,dstptr,status)
+ * dbl_to_sgl_fcnvfxt(srcptr,_nullptr,dstptr,status)
+ * sgl_to_dbl_fcnvfxt(srcptr,_nullptr,dstptr,status)
+ * sgl_to_sgl_fcnvfxt(srcptr,_nullptr,dstptr,status)
*
* Internal Interfaces:
*
@@ -45,7 +45,7 @@
int
sgl_to_sgl_fcnvfxt(
sgl_floating_point *srcptr,
- unsigned int *nullptr,
+ unsigned int *_nullptr,
int *dstptr,
unsigned int *status)
{
@@ -109,7 +109,7 @@ sgl_to_sgl_fcnvfxt(
int
sgl_to_dbl_fcnvfxt(
sgl_floating_point *srcptr,
- unsigned int *nullptr,
+ unsigned int *_nullptr,
dbl_integer *dstptr,
unsigned int *status)
{
@@ -183,7 +183,7 @@ sgl_to_dbl_fcnvfxt(
int
dbl_to_sgl_fcnvfxt(
dbl_floating_point *srcptr,
- unsigned int *nullptr,
+ unsigned int *_nullptr,
int *dstptr,
unsigned int *status)
{
@@ -248,7 +248,7 @@ dbl_to_sgl_fcnvfxt(
int
dbl_to_dbl_fcnvfxt(
dbl_floating_point *srcptr,
- unsigned int *nullptr,
+ unsigned int *_nullptr,
dbl_integer *dstptr,
unsigned int *status)
{
diff --git a/arch/parisc/math-emu/fcnvuf.c b/arch/parisc/math-emu/fcnvuf.c
index c54978a0ace1..c166feb57045 100644
--- a/arch/parisc/math-emu/fcnvuf.c
+++ b/arch/parisc/math-emu/fcnvuf.c
@@ -15,10 +15,10 @@
* Fixed point to Floating-point Converts
*
* External Interfaces:
- * dbl_to_dbl_fcnvuf(srcptr,nullptr,dstptr,status)
- * dbl_to_sgl_fcnvuf(srcptr,nullptr,dstptr,status)
- * sgl_to_dbl_fcnvuf(srcptr,nullptr,dstptr,status)
- * sgl_to_sgl_fcnvuf(srcptr,nullptr,dstptr,status)
+ * dbl_to_dbl_fcnvuf(srcptr,_nullptr,dstptr,status)
+ * dbl_to_sgl_fcnvuf(srcptr,_nullptr,dstptr,status)
+ * sgl_to_dbl_fcnvuf(srcptr,_nullptr,dstptr,status)
+ * sgl_to_sgl_fcnvuf(srcptr,_nullptr,dstptr,status)
*
* Internal Interfaces:
*
@@ -45,7 +45,7 @@
int
sgl_to_sgl_fcnvuf(
unsigned int *srcptr,
- unsigned int *nullptr,
+ unsigned int *_nullptr,
sgl_floating_point *dstptr,
unsigned int *status)
{
@@ -104,7 +104,7 @@ sgl_to_sgl_fcnvuf(
int
sgl_to_dbl_fcnvuf(
unsigned int *srcptr,
- unsigned int *nullptr,
+ unsigned int *_nullptr,
dbl_floating_point *dstptr,
unsigned int *status)
{
@@ -145,7 +145,7 @@ sgl_to_dbl_fcnvuf(
int
dbl_to_sgl_fcnvuf(
dbl_unsigned *srcptr,
- unsigned int *nullptr,
+ unsigned int *_nullptr,
sgl_floating_point *dstptr,
unsigned int *status)
{
@@ -227,7 +227,7 @@ dbl_to_sgl_fcnvuf(
int
dbl_to_dbl_fcnvuf(
dbl_unsigned *srcptr,
- unsigned int *nullptr,
+ unsigned int *_nullptr,
dbl_floating_point *dstptr,
unsigned int *status)
{
diff --git a/arch/parisc/math-emu/fcnvxf.c b/arch/parisc/math-emu/fcnvxf.c
index 69401797146b..11bc1e8a13aa 100644
--- a/arch/parisc/math-emu/fcnvxf.c
+++ b/arch/parisc/math-emu/fcnvxf.c
@@ -18,10 +18,10 @@
* Double Fixed-point to Double Floating-point
*
* External Interfaces:
- * dbl_to_dbl_fcnvxf(srcptr,nullptr,dstptr,status)
- * dbl_to_sgl_fcnvxf(srcptr,nullptr,dstptr,status)
- * sgl_to_dbl_fcnvxf(srcptr,nullptr,dstptr,status)
- * sgl_to_sgl_fcnvxf(srcptr,nullptr,dstptr,status)
+ * dbl_to_dbl_fcnvxf(srcptr,_nullptr,dstptr,status)
+ * dbl_to_sgl_fcnvxf(srcptr,_nullptr,dstptr,status)
+ * sgl_to_dbl_fcnvxf(srcptr,_nullptr,dstptr,status)
+ * sgl_to_sgl_fcnvxf(srcptr,_nullptr,dstptr,status)
*
* Internal Interfaces:
*
@@ -44,7 +44,7 @@
int
sgl_to_sgl_fcnvxf(
int *srcptr,
- unsigned int *nullptr,
+ unsigned int *_nullptr,
sgl_floating_point *dstptr,
unsigned int *status)
{
@@ -115,7 +115,7 @@ sgl_to_sgl_fcnvxf(
int
sgl_to_dbl_fcnvxf(
int *srcptr,
- unsigned int *nullptr,
+ unsigned int *_nullptr,
dbl_floating_point *dstptr,
unsigned int *status)
{
@@ -166,7 +166,7 @@ sgl_to_dbl_fcnvxf(
int
dbl_to_sgl_fcnvxf(
dbl_integer *srcptr,
- unsigned int *nullptr,
+ unsigned int *_nullptr,
sgl_floating_point *dstptr,
unsigned int *status)
{
@@ -271,7 +271,7 @@ dbl_to_sgl_fcnvxf(
int
dbl_to_dbl_fcnvxf(
dbl_integer *srcptr,
- unsigned int *nullptr,
+ unsigned int *_nullptr,
dbl_floating_point *dstptr,
unsigned int *status)
{
diff --git a/arch/parisc/math-emu/frnd.c b/arch/parisc/math-emu/frnd.c
index 0b0e8493e08a..825d89650c2d 100644
--- a/arch/parisc/math-emu/frnd.c
+++ b/arch/parisc/math-emu/frnd.c
@@ -14,8 +14,8 @@
* Quad Floating-point Round to Integer (returns unimplemented)
*
* External Interfaces:
- * dbl_frnd(srcptr,nullptr,dstptr,status)
- * sgl_frnd(srcptr,nullptr,dstptr,status)
+ * dbl_frnd(srcptr,_nullptr,dstptr,status)
+ * sgl_frnd(srcptr,_nullptr,dstptr,status)
*
* END_DESC
*/
@@ -33,7 +33,7 @@
/*ARGSUSED*/
int
sgl_frnd(sgl_floating_point *srcptr,
- unsigned int *nullptr,
+ unsigned int *_nullptr,
sgl_floating_point *dstptr,
unsigned int *status)
{
@@ -138,7 +138,7 @@ sgl_frnd(sgl_floating_point *srcptr,
int
dbl_frnd(
dbl_floating_point *srcptr,
- unsigned int *nullptr,
+ unsigned int *_nullptr,
dbl_floating_point *dstptr,
unsigned int *status)
{
diff --git a/arch/parisc/math-emu/sfsqrt.c b/arch/parisc/math-emu/sfsqrt.c
index bd6a84f468d8..8e9e023e7b2e 100644
--- a/arch/parisc/math-emu/sfsqrt.c
+++ b/arch/parisc/math-emu/sfsqrt.c
@@ -15,7 +15,7 @@
* Single Floating-point Square Root
*
* External Interfaces:
- * sgl_fsqrt(srcptr,nullptr,dstptr,status)
+ * sgl_fsqrt(srcptr,_nullptr,dstptr,status)
*
* Internal Interfaces:
*
@@ -37,7 +37,7 @@
unsigned int
sgl_fsqrt(
sgl_floating_point *srcptr,
- unsigned int *nullptr,
+ unsigned int *_nullptr,
sgl_floating_point *dstptr,
unsigned int *status)
{
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index b9fc064d38d2..1c4be3373686 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -154,7 +154,7 @@ config PPC
select ARCH_HAS_SYSCALL_WRAPPER if !SPU_BASE && !COMPAT
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
select ARCH_HAS_UACCESS_FLUSHCACHE
- select ARCH_HAS_UBSAN_SANITIZE_ALL
+ select ARCH_HAS_UBSAN
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select ARCH_KEEP_MEMBLOCK
select ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE if PPC_RADIX_MMU
@@ -212,7 +212,7 @@ config PPC
select HAVE_ARCH_HUGE_VMAP if PPC_RADIX_MMU || PPC_8xx
select HAVE_ARCH_JUMP_LABEL
select HAVE_ARCH_JUMP_LABEL_RELATIVE
- select HAVE_ARCH_KASAN if PPC32 && PPC_PAGE_SHIFT <= 14
+ select HAVE_ARCH_KASAN if PPC32 && PAGE_SHIFT <= 14
select HAVE_ARCH_KASAN if PPC_RADIX_MMU
select HAVE_ARCH_KASAN if PPC_BOOK3E_64
select HAVE_ARCH_KASAN_VMALLOC if HAVE_ARCH_KASAN
@@ -333,7 +333,6 @@ config PANIC_TIMEOUT
config COMPAT
bool "Enable support for 32bit binaries"
depends on PPC64
- depends on !CC_IS_CLANG || CLANG_VERSION >= 120000
default y if !CPU_LITTLE_ENDIAN
select ARCH_WANT_OLD_COMPAT_IPC
select COMPAT_OLD_SIGACTION
@@ -689,9 +688,7 @@ config ARCH_SELECTS_CRASH_DUMP
config FA_DUMP
bool "Firmware-assisted dump"
- depends on PPC64 && (PPC_RTAS || PPC_POWERNV)
- select CRASH_CORE
- select CRASH_DUMP
+ depends on CRASH_DUMP && PPC64 && (PPC_RTAS || PPC_POWERNV)
help
A robust mechanism to get reliable kernel crash dump with
assistance from firmware. This approach does not use kexec,
@@ -809,19 +806,23 @@ choice
config PPC_4K_PAGES
bool "4k page size"
select HAVE_ARCH_SOFT_DIRTY if PPC_BOOK3S_64
+ select HAVE_PAGE_SIZE_4KB
config PPC_16K_PAGES
bool "16k page size"
depends on 44x || PPC_8xx
+ select HAVE_PAGE_SIZE_16KB
config PPC_64K_PAGES
bool "64k page size"
depends on 44x || PPC_BOOK3S_64
select HAVE_ARCH_SOFT_DIRTY if PPC_BOOK3S_64
+ select HAVE_PAGE_SIZE_64KB
config PPC_256K_PAGES
bool "256k page size (Requires non-standard binutils settings)"
depends on 44x && !PPC_47x
+ select HAVE_PAGE_SIZE_256KB
help
Make the page size 256k.
@@ -832,29 +833,6 @@ config PPC_256K_PAGES
endchoice
-config PAGE_SIZE_4KB
- def_bool y
- depends on PPC_4K_PAGES
-
-config PAGE_SIZE_16KB
- def_bool y
- depends on PPC_16K_PAGES
-
-config PAGE_SIZE_64KB
- def_bool y
- depends on PPC_64K_PAGES
-
-config PAGE_SIZE_256KB
- def_bool y
- depends on PPC_256K_PAGES
-
-config PPC_PAGE_SHIFT
- int
- default 18 if PPC_256K_PAGES
- default 16 if PPC_64K_PAGES
- default 14 if PPC_16K_PAGES
- default 12
-
config THREAD_SHIFT
int "Thread shift" if EXPERT
range 13 15
@@ -891,7 +869,7 @@ config DATA_SHIFT
default 23 if (DEBUG_PAGEALLOC || KFENCE) && PPC_8xx && PIN_TLB_DATA
default 19 if (DEBUG_PAGEALLOC || KFENCE) && PPC_8xx
default 24 if STRICT_KERNEL_RWX && PPC_85xx
- default PPC_PAGE_SHIFT
+ default PAGE_SHIFT
help
On Book3S 32 (603+), DBATs are used to map kernel text and rodata RO.
Smaller is the alignment, greater is the number of necessary DBATs.
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 051247027da0..65261cbe5bfd 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -144,11 +144,11 @@ CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mno-pointers-to-nested-functions)
CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mlong-double-128)
# Clang unconditionally reserves r2 on ppc32 and does not support the flag
-# https://bugs.llvm.org/show_bug.cgi?id=39555
+# https://llvm.org/pr39555
CFLAGS-$(CONFIG_PPC32) := $(call cc-option, -ffixed-r2)
# Clang doesn't support -mmultiple / -mno-multiple
-# https://bugs.llvm.org/show_bug.cgi?id=39556
+# https://llvm.org/pr39556
CFLAGS-$(CONFIG_PPC32) += $(call cc-option, $(MULTIPLEWORD))
CFLAGS-$(CONFIG_PPC32) += $(call cc-option,-mno-readonly-in-sdata)
@@ -219,18 +219,6 @@ KBUILD_CFLAGS += -fno-asynchronous-unwind-tables
# often slow when they are implemented at all
KBUILD_CFLAGS += $(call cc-option,-mno-string)
-cpu-as-$(CONFIG_ALTIVEC) += $(call as-option,-Wa$(comma)-maltivec)
-
-# When using '-many -mpower4' gas will first try and find a matching power4
-# mnemonic and failing that it will allow any valid mnemonic that GAS knows
-# about. GCC will pass -many to GAS when assembling, clang does not.
-# LLVM IAS doesn't understand either flag: https://github.com/ClangBuiltLinux/linux/issues/675
-# but LLVM IAS only supports ISA >= 2.06 for Book3S 64 anyway...
-cpu-as-$(CONFIG_PPC_BOOK3S_64) += $(call as-option,-Wa$(comma)-mpower4) $(call as-option,-Wa$(comma)-many)
-
-KBUILD_AFLAGS += $(cpu-as-y)
-KBUILD_CFLAGS += $(cpu-as-y)
-
KBUILD_AFLAGS += $(aflags-y)
KBUILD_CFLAGS += $(cflags-y)
@@ -314,6 +302,26 @@ 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 \
+ -f $(srctree)/Makefile allmodconfig
+
+generated_configs += ppc8xx_allmodconfig
+ppc8xx_allmodconfig:
+ $(Q)$(MAKE) KCONFIG_ALLCONFIG=$(srctree)/arch/powerpc/configs/8xx.config \
+ -f $(srctree)/Makefile allmodconfig
+
+generated_configs += ppc85xx_allmodconfig
+ppc85xx_allmodconfig:
+ $(Q)$(MAKE) KCONFIG_ALLCONFIG=$(srctree)/arch/powerpc/configs/85xx-32bit.config \
+ -f $(srctree)/Makefile allmodconfig
+
generated_configs += ppc_defconfig
ppc_defconfig:
$(call merge_into_defconfig,book3s_32.config,)
diff --git a/arch/powerpc/boot/dts/akebono.dts b/arch/powerpc/boot/dts/akebono.dts
index df18f8dc4642..343326c30380 100644
--- a/arch/powerpc/boot/dts/akebono.dts
+++ b/arch/powerpc/boot/dts/akebono.dts
@@ -126,7 +126,7 @@
interrupts = <93 2>;
};
- EHCI0: ehci@30010000000 {
+ EHCI0: usb@30010000000 {
compatible = "ibm,476gtr-ehci", "generic-ehci";
reg = <0x300 0x10000000 0x0 0x10000>;
interrupt-parent = <&MPIC>;
@@ -140,14 +140,14 @@
interrupt-parent = <&MPIC>;
};
- OHCI0: ohci@30010010000 {
+ OHCI0: usb@30010010000 {
compatible = "ibm,476gtr-ohci", "generic-ohci";
reg = <0x300 0x10010000 0x0 0x10000>;
interrupt-parent = <&MPIC>;
interrupts = <89 1>;
};
- OHCI1: ohci@30010020000 {
+ OHCI1: usb@30010020000 {
compatible = "ibm,476gtr-ohci", "generic-ohci";
reg = <0x300 0x10020000 0x0 0x10000>;
interrupt-parent = <&MPIC>;
diff --git a/arch/powerpc/boot/simple_alloc.c b/arch/powerpc/boot/simple_alloc.c
index 267d6524caac..d07796fdf91a 100644
--- a/arch/powerpc/boot/simple_alloc.c
+++ b/arch/powerpc/boot/simple_alloc.c
@@ -112,8 +112,11 @@ static void *simple_realloc(void *ptr, unsigned long size)
return ptr;
new = simple_malloc(size);
- memcpy(new, ptr, p->size);
- simple_free(ptr);
+ if (new) {
+ memcpy(new, ptr, p->size);
+ simple_free(ptr);
+ }
+
return new;
}
diff --git a/arch/powerpc/configs/40x.config b/arch/powerpc/configs/40x.config
new file mode 100644
index 000000000000..82a9d58ddb81
--- /dev/null
+++ b/arch/powerpc/configs/40x.config
@@ -0,0 +1,2 @@
+CONFIG_PPC64=n
+CONFIG_40x=y
diff --git a/arch/powerpc/configs/44x.config b/arch/powerpc/configs/44x.config
new file mode 100644
index 000000000000..79b7b1962995
--- /dev/null
+++ b/arch/powerpc/configs/44x.config
@@ -0,0 +1,2 @@
+CONFIG_PPC64=n
+CONFIG_44x=y
diff --git a/arch/powerpc/configs/85xx-32bit.config b/arch/powerpc/configs/85xx-32bit.config
index 6b8894d727a2..a85310bcb1fd 100644
--- a/arch/powerpc/configs/85xx-32bit.config
+++ b/arch/powerpc/configs/85xx-32bit.config
@@ -1,3 +1,4 @@
+CONFIG_PPC64=n
CONFIG_HIGHMEM=y
CONFIG_KEXEC=y
CONFIG_PPC_85xx=y
diff --git a/arch/powerpc/configs/8xx.config b/arch/powerpc/configs/8xx.config
new file mode 100644
index 000000000000..7eb3ffbbd667
--- /dev/null
+++ b/arch/powerpc/configs/8xx.config
@@ -0,0 +1,2 @@
+CONFIG_PPC64=n
+CONFIG_PPC_8xx=y
diff --git a/arch/powerpc/configs/ps3_defconfig b/arch/powerpc/configs/ps3_defconfig
index aa8bb0208bcc..2b175ddf82f0 100644
--- a/arch/powerpc/configs/ps3_defconfig
+++ b/arch/powerpc/configs/ps3_defconfig
@@ -24,7 +24,6 @@ CONFIG_PS3_VRAM=m
CONFIG_PS3_LPM=m
# CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set
CONFIG_KEXEC=y
-# CONFIG_PPC64_BIG_ENDIAN_ELF_ABI_V2 is not set
CONFIG_PPC_4K_PAGES=y
CONFIG_SCHED_SMT=y
CONFIG_PM=y
diff --git a/arch/powerpc/crypto/Kconfig b/arch/powerpc/crypto/Kconfig
index 6fc2248ca561..1e201b7ae2fc 100644
--- a/arch/powerpc/crypto/Kconfig
+++ b/arch/powerpc/crypto/Kconfig
@@ -137,4 +137,24 @@ config CRYPTO_POLY1305_P10
- Power10 or later
- Little-endian
+config CRYPTO_DEV_VMX
+ bool "Support for VMX cryptographic acceleration instructions"
+ depends on PPC64 && VSX
+ help
+ Support for VMX cryptographic acceleration instructions.
+
+config CRYPTO_DEV_VMX_ENCRYPT
+ tristate "Encryption acceleration support on P8 CPU"
+ depends on CRYPTO_DEV_VMX
+ select CRYPTO_AES
+ select CRYPTO_CBC
+ select CRYPTO_CTR
+ select CRYPTO_GHASH
+ select CRYPTO_XTS
+ default m
+ help
+ Support for VMX cryptographic acceleration instructions on Power8 CPU.
+ This module supports acceleration for AES and GHASH in hardware. If you
+ choose 'M' here, this module will be called vmx-crypto.
+
endmenu
diff --git a/arch/powerpc/crypto/Makefile b/arch/powerpc/crypto/Makefile
index ebdac1b9eb9a..fca0e9739869 100644
--- a/arch/powerpc/crypto/Makefile
+++ b/arch/powerpc/crypto/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_CRYPTO_VPMSUM_TESTER) += crc-vpmsum_test.o
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
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
@@ -27,14 +28,29 @@ crct10dif-vpmsum-y := crct10dif-vpmsum_asm.o crct10dif-vpmsum_glue.o
aes-gcm-p10-crypto-y := aes-gcm-p10-glue.o aes-gcm-p10.o ghashp10-ppc.o aesp10-ppc.o
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
+
+ifeq ($(CONFIG_CPU_LITTLE_ENDIAN),y)
+override flavour := linux-ppc64le
+else
+ifdef CONFIG_PPC64_ELF_ABI_V2
+override flavour := linux-ppc64-elfv2
+else
+override flavour := linux-ppc64
+endif
+endif
quiet_cmd_perl = PERL $@
- cmd_perl = $(PERL) $< $(if $(CONFIG_CPU_LITTLE_ENDIAN), linux-ppc64le, linux-ppc64) > $@
+ cmd_perl = $(PERL) $< $(flavour) > $@
-targets += aesp10-ppc.S ghashp10-ppc.S
+targets += aesp10-ppc.S ghashp10-ppc.S aesp8-ppc.S ghashp8-ppc.S
$(obj)/aesp10-ppc.S $(obj)/ghashp10-ppc.S: $(obj)/%.S: $(src)/%.pl FORCE
$(call if_changed,perl)
+$(obj)/aesp8-ppc.S $(obj)/ghashp8-ppc.S: $(obj)/%.S: $(src)/%.pl FORCE
+ $(call if_changed,perl)
+
OBJECT_FILES_NON_STANDARD_aesp10-ppc.o := y
OBJECT_FILES_NON_STANDARD_ghashp10-ppc.o := y
+OBJECT_FILES_NON_STANDARD_aesp8-ppc.o := y
diff --git a/arch/powerpc/crypto/aes.c b/arch/powerpc/crypto/aes.c
new file mode 100644
index 000000000000..ec06189fbf99
--- /dev/null
+++ b/arch/powerpc/crypto/aes.c
@@ -0,0 +1,134 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * AES routines supporting VMX instructions on the Power 8
+ *
+ * Copyright (C) 2015 International Business Machines Inc.
+ *
+ * Author: Marcelo Henrique Cerri <mhcerri@br.ibm.com>
+ */
+
+#include <linux/types.h>
+#include <linux/err.h>
+#include <linux/crypto.h>
+#include <linux/delay.h>
+#include <asm/simd.h>
+#include <asm/switch_to.h>
+#include <crypto/aes.h>
+#include <crypto/internal/cipher.h>
+#include <crypto/internal/simd.h>
+
+#include "aesp8-ppc.h"
+
+struct p8_aes_ctx {
+ struct crypto_cipher *fallback;
+ struct aes_key enc_key;
+ struct aes_key dec_key;
+};
+
+static int p8_aes_init(struct crypto_tfm *tfm)
+{
+ const char *alg = crypto_tfm_alg_name(tfm);
+ struct crypto_cipher *fallback;
+ struct p8_aes_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ fallback = crypto_alloc_cipher(alg, 0, CRYPTO_ALG_NEED_FALLBACK);
+ if (IS_ERR(fallback)) {
+ printk(KERN_ERR
+ "Failed to allocate transformation for '%s': %ld\n",
+ alg, PTR_ERR(fallback));
+ return PTR_ERR(fallback);
+ }
+
+ crypto_cipher_set_flags(fallback,
+ crypto_cipher_get_flags((struct
+ crypto_cipher *)
+ tfm));
+ ctx->fallback = fallback;
+
+ return 0;
+}
+
+static void p8_aes_exit(struct crypto_tfm *tfm)
+{
+ struct p8_aes_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ if (ctx->fallback) {
+ crypto_free_cipher(ctx->fallback);
+ ctx->fallback = NULL;
+ }
+}
+
+static int p8_aes_setkey(struct crypto_tfm *tfm, const u8 *key,
+ unsigned int keylen)
+{
+ int ret;
+ struct p8_aes_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ preempt_disable();
+ pagefault_disable();
+ enable_kernel_vsx();
+ ret = aes_p8_set_encrypt_key(key, keylen * 8, &ctx->enc_key);
+ ret |= aes_p8_set_decrypt_key(key, keylen * 8, &ctx->dec_key);
+ disable_kernel_vsx();
+ pagefault_enable();
+ preempt_enable();
+
+ ret |= crypto_cipher_setkey(ctx->fallback, key, keylen);
+
+ return ret ? -EINVAL : 0;
+}
+
+static void p8_aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+{
+ struct p8_aes_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ if (!crypto_simd_usable()) {
+ crypto_cipher_encrypt_one(ctx->fallback, dst, src);
+ } else {
+ preempt_disable();
+ pagefault_disable();
+ enable_kernel_vsx();
+ aes_p8_encrypt(src, dst, &ctx->enc_key);
+ disable_kernel_vsx();
+ pagefault_enable();
+ preempt_enable();
+ }
+}
+
+static void p8_aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+{
+ struct p8_aes_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ if (!crypto_simd_usable()) {
+ crypto_cipher_decrypt_one(ctx->fallback, dst, src);
+ } else {
+ preempt_disable();
+ pagefault_disable();
+ enable_kernel_vsx();
+ aes_p8_decrypt(src, dst, &ctx->dec_key);
+ disable_kernel_vsx();
+ pagefault_enable();
+ preempt_enable();
+ }
+}
+
+struct crypto_alg p8_aes_alg = {
+ .cra_name = "aes",
+ .cra_driver_name = "p8_aes",
+ .cra_module = THIS_MODULE,
+ .cra_priority = 1000,
+ .cra_type = NULL,
+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER | CRYPTO_ALG_NEED_FALLBACK,
+ .cra_alignmask = 0,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct p8_aes_ctx),
+ .cra_init = p8_aes_init,
+ .cra_exit = p8_aes_exit,
+ .cra_cipher = {
+ .cia_min_keysize = AES_MIN_KEY_SIZE,
+ .cia_max_keysize = AES_MAX_KEY_SIZE,
+ .cia_setkey = p8_aes_setkey,
+ .cia_encrypt = p8_aes_encrypt,
+ .cia_decrypt = p8_aes_decrypt,
+ },
+};
diff --git a/arch/powerpc/crypto/aes_cbc.c b/arch/powerpc/crypto/aes_cbc.c
new file mode 100644
index 000000000000..ed0debc7acb5
--- /dev/null
+++ b/arch/powerpc/crypto/aes_cbc.c
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * AES CBC routines supporting VMX instructions on the Power 8
+ *
+ * Copyright (C) 2015 International Business Machines Inc.
+ *
+ * Author: Marcelo Henrique Cerri <mhcerri@br.ibm.com>
+ */
+
+#include <asm/simd.h>
+#include <asm/switch_to.h>
+#include <crypto/aes.h>
+#include <crypto/internal/simd.h>
+#include <crypto/internal/skcipher.h>
+
+#include "aesp8-ppc.h"
+
+struct p8_aes_cbc_ctx {
+ struct crypto_skcipher *fallback;
+ struct aes_key enc_key;
+ struct aes_key dec_key;
+};
+
+static int p8_aes_cbc_init(struct crypto_skcipher *tfm)
+{
+ struct p8_aes_cbc_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct crypto_skcipher *fallback;
+
+ fallback = crypto_alloc_skcipher("cbc(aes)", 0,
+ CRYPTO_ALG_NEED_FALLBACK |
+ CRYPTO_ALG_ASYNC);
+ if (IS_ERR(fallback)) {
+ pr_err("Failed to allocate cbc(aes) fallback: %ld\n",
+ PTR_ERR(fallback));
+ return PTR_ERR(fallback);
+ }
+
+ crypto_skcipher_set_reqsize(tfm, sizeof(struct skcipher_request) +
+ crypto_skcipher_reqsize(fallback));
+ ctx->fallback = fallback;
+ return 0;
+}
+
+static void p8_aes_cbc_exit(struct crypto_skcipher *tfm)
+{
+ struct p8_aes_cbc_ctx *ctx = crypto_skcipher_ctx(tfm);
+
+ crypto_free_skcipher(ctx->fallback);
+}
+
+static int p8_aes_cbc_setkey(struct crypto_skcipher *tfm, const u8 *key,
+ unsigned int keylen)
+{
+ struct p8_aes_cbc_ctx *ctx = crypto_skcipher_ctx(tfm);
+ int ret;
+
+ preempt_disable();
+ pagefault_disable();
+ enable_kernel_vsx();
+ ret = aes_p8_set_encrypt_key(key, keylen * 8, &ctx->enc_key);
+ ret |= aes_p8_set_decrypt_key(key, keylen * 8, &ctx->dec_key);
+ disable_kernel_vsx();
+ pagefault_enable();
+ preempt_enable();
+
+ ret |= crypto_skcipher_setkey(ctx->fallback, key, keylen);
+
+ return ret ? -EINVAL : 0;
+}
+
+static int p8_aes_cbc_crypt(struct skcipher_request *req, int enc)
+{
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ const struct p8_aes_cbc_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct skcipher_walk walk;
+ unsigned int nbytes;
+ int ret;
+
+ if (!crypto_simd_usable()) {
+ struct skcipher_request *subreq = skcipher_request_ctx(req);
+
+ *subreq = *req;
+ skcipher_request_set_tfm(subreq, ctx->fallback);
+ return enc ? crypto_skcipher_encrypt(subreq) :
+ crypto_skcipher_decrypt(subreq);
+ }
+
+ ret = skcipher_walk_virt(&walk, req, false);
+ while ((nbytes = walk.nbytes) != 0) {
+ preempt_disable();
+ pagefault_disable();
+ enable_kernel_vsx();
+ aes_p8_cbc_encrypt(walk.src.virt.addr,
+ walk.dst.virt.addr,
+ round_down(nbytes, AES_BLOCK_SIZE),
+ enc ? &ctx->enc_key : &ctx->dec_key,
+ walk.iv, enc);
+ disable_kernel_vsx();
+ pagefault_enable();
+ preempt_enable();
+
+ ret = skcipher_walk_done(&walk, nbytes % AES_BLOCK_SIZE);
+ }
+ return ret;
+}
+
+static int p8_aes_cbc_encrypt(struct skcipher_request *req)
+{
+ return p8_aes_cbc_crypt(req, 1);
+}
+
+static int p8_aes_cbc_decrypt(struct skcipher_request *req)
+{
+ return p8_aes_cbc_crypt(req, 0);
+}
+
+struct skcipher_alg p8_aes_cbc_alg = {
+ .base.cra_name = "cbc(aes)",
+ .base.cra_driver_name = "p8_aes_cbc",
+ .base.cra_module = THIS_MODULE,
+ .base.cra_priority = 2000,
+ .base.cra_flags = CRYPTO_ALG_NEED_FALLBACK,
+ .base.cra_blocksize = AES_BLOCK_SIZE,
+ .base.cra_ctxsize = sizeof(struct p8_aes_cbc_ctx),
+ .setkey = p8_aes_cbc_setkey,
+ .encrypt = p8_aes_cbc_encrypt,
+ .decrypt = p8_aes_cbc_decrypt,
+ .init = p8_aes_cbc_init,
+ .exit = p8_aes_cbc_exit,
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+};
diff --git a/arch/powerpc/crypto/aes_ctr.c b/arch/powerpc/crypto/aes_ctr.c
new file mode 100644
index 000000000000..9a3da8cd62f3
--- /dev/null
+++ b/arch/powerpc/crypto/aes_ctr.c
@@ -0,0 +1,149 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * AES CTR routines supporting VMX instructions on the Power 8
+ *
+ * Copyright (C) 2015 International Business Machines Inc.
+ *
+ * Author: Marcelo Henrique Cerri <mhcerri@br.ibm.com>
+ */
+
+#include <asm/simd.h>
+#include <asm/switch_to.h>
+#include <crypto/aes.h>
+#include <crypto/internal/simd.h>
+#include <crypto/internal/skcipher.h>
+
+#include "aesp8-ppc.h"
+
+struct p8_aes_ctr_ctx {
+ struct crypto_skcipher *fallback;
+ struct aes_key enc_key;
+};
+
+static int p8_aes_ctr_init(struct crypto_skcipher *tfm)
+{
+ struct p8_aes_ctr_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct crypto_skcipher *fallback;
+
+ fallback = crypto_alloc_skcipher("ctr(aes)", 0,
+ CRYPTO_ALG_NEED_FALLBACK |
+ CRYPTO_ALG_ASYNC);
+ if (IS_ERR(fallback)) {
+ pr_err("Failed to allocate ctr(aes) fallback: %ld\n",
+ PTR_ERR(fallback));
+ return PTR_ERR(fallback);
+ }
+
+ crypto_skcipher_set_reqsize(tfm, sizeof(struct skcipher_request) +
+ crypto_skcipher_reqsize(fallback));
+ ctx->fallback = fallback;
+ return 0;
+}
+
+static void p8_aes_ctr_exit(struct crypto_skcipher *tfm)
+{
+ struct p8_aes_ctr_ctx *ctx = crypto_skcipher_ctx(tfm);
+
+ crypto_free_skcipher(ctx->fallback);
+}
+
+static int p8_aes_ctr_setkey(struct crypto_skcipher *tfm, const u8 *key,
+ unsigned int keylen)
+{
+ struct p8_aes_ctr_ctx *ctx = crypto_skcipher_ctx(tfm);
+ int ret;
+
+ preempt_disable();
+ pagefault_disable();
+ enable_kernel_vsx();
+ ret = aes_p8_set_encrypt_key(key, keylen * 8, &ctx->enc_key);
+ disable_kernel_vsx();
+ pagefault_enable();
+ preempt_enable();
+
+ ret |= crypto_skcipher_setkey(ctx->fallback, key, keylen);
+
+ return ret ? -EINVAL : 0;
+}
+
+static void p8_aes_ctr_final(const struct p8_aes_ctr_ctx *ctx,
+ struct skcipher_walk *walk)
+{
+ u8 *ctrblk = walk->iv;
+ u8 keystream[AES_BLOCK_SIZE];
+ u8 *src = walk->src.virt.addr;
+ u8 *dst = walk->dst.virt.addr;
+ unsigned int nbytes = walk->nbytes;
+
+ preempt_disable();
+ pagefault_disable();
+ enable_kernel_vsx();
+ aes_p8_encrypt(ctrblk, keystream, &ctx->enc_key);
+ disable_kernel_vsx();
+ pagefault_enable();
+ preempt_enable();
+
+ crypto_xor_cpy(dst, keystream, src, nbytes);
+ crypto_inc(ctrblk, AES_BLOCK_SIZE);
+}
+
+static int p8_aes_ctr_crypt(struct skcipher_request *req)
+{
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ const struct p8_aes_ctr_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct skcipher_walk walk;
+ unsigned int nbytes;
+ int ret;
+
+ if (!crypto_simd_usable()) {
+ struct skcipher_request *subreq = skcipher_request_ctx(req);
+
+ *subreq = *req;
+ skcipher_request_set_tfm(subreq, ctx->fallback);
+ return crypto_skcipher_encrypt(subreq);
+ }
+
+ ret = skcipher_walk_virt(&walk, req, false);
+ while ((nbytes = walk.nbytes) >= AES_BLOCK_SIZE) {
+ preempt_disable();
+ pagefault_disable();
+ enable_kernel_vsx();
+ aes_p8_ctr32_encrypt_blocks(walk.src.virt.addr,
+ walk.dst.virt.addr,
+ nbytes / AES_BLOCK_SIZE,
+ &ctx->enc_key, walk.iv);
+ disable_kernel_vsx();
+ pagefault_enable();
+ preempt_enable();
+
+ do {
+ crypto_inc(walk.iv, AES_BLOCK_SIZE);
+ } while ((nbytes -= AES_BLOCK_SIZE) >= AES_BLOCK_SIZE);
+
+ ret = skcipher_walk_done(&walk, nbytes);
+ }
+ if (nbytes) {
+ p8_aes_ctr_final(ctx, &walk);
+ ret = skcipher_walk_done(&walk, 0);
+ }
+ return ret;
+}
+
+struct skcipher_alg p8_aes_ctr_alg = {
+ .base.cra_name = "ctr(aes)",
+ .base.cra_driver_name = "p8_aes_ctr",
+ .base.cra_module = THIS_MODULE,
+ .base.cra_priority = 2000,
+ .base.cra_flags = CRYPTO_ALG_NEED_FALLBACK,
+ .base.cra_blocksize = 1,
+ .base.cra_ctxsize = sizeof(struct p8_aes_ctr_ctx),
+ .setkey = p8_aes_ctr_setkey,
+ .encrypt = p8_aes_ctr_crypt,
+ .decrypt = p8_aes_ctr_crypt,
+ .init = p8_aes_ctr_init,
+ .exit = p8_aes_ctr_exit,
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .chunksize = AES_BLOCK_SIZE,
+};
diff --git a/arch/powerpc/crypto/aes_xts.c b/arch/powerpc/crypto/aes_xts.c
new file mode 100644
index 000000000000..dabbccb41550
--- /dev/null
+++ b/arch/powerpc/crypto/aes_xts.c
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * AES XTS routines supporting VMX In-core instructions on Power 8
+ *
+ * Copyright (C) 2015 International Business Machines Inc.
+ *
+ * Author: Leonidas S. Barbosa <leosilva@linux.vnet.ibm.com>
+ */
+
+#include <asm/simd.h>
+#include <asm/switch_to.h>
+#include <crypto/aes.h>
+#include <crypto/internal/simd.h>
+#include <crypto/internal/skcipher.h>
+#include <crypto/xts.h>
+
+#include "aesp8-ppc.h"
+
+struct p8_aes_xts_ctx {
+ struct crypto_skcipher *fallback;
+ struct aes_key enc_key;
+ struct aes_key dec_key;
+ struct aes_key tweak_key;
+};
+
+static int p8_aes_xts_init(struct crypto_skcipher *tfm)
+{
+ struct p8_aes_xts_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct crypto_skcipher *fallback;
+
+ fallback = crypto_alloc_skcipher("xts(aes)", 0,
+ CRYPTO_ALG_NEED_FALLBACK |
+ CRYPTO_ALG_ASYNC);
+ if (IS_ERR(fallback)) {
+ pr_err("Failed to allocate xts(aes) fallback: %ld\n",
+ PTR_ERR(fallback));
+ return PTR_ERR(fallback);
+ }
+
+ crypto_skcipher_set_reqsize(tfm, sizeof(struct skcipher_request) +
+ crypto_skcipher_reqsize(fallback));
+ ctx->fallback = fallback;
+ return 0;
+}
+
+static void p8_aes_xts_exit(struct crypto_skcipher *tfm)
+{
+ struct p8_aes_xts_ctx *ctx = crypto_skcipher_ctx(tfm);
+
+ crypto_free_skcipher(ctx->fallback);
+}
+
+static int p8_aes_xts_setkey(struct crypto_skcipher *tfm, const u8 *key,
+ unsigned int keylen)
+{
+ struct p8_aes_xts_ctx *ctx = crypto_skcipher_ctx(tfm);
+ int ret;
+
+ ret = xts_verify_key(tfm, key, keylen);
+ if (ret)
+ return ret;
+
+ preempt_disable();
+ pagefault_disable();
+ enable_kernel_vsx();
+ ret = aes_p8_set_encrypt_key(key + keylen/2, (keylen/2) * 8, &ctx->tweak_key);
+ ret |= aes_p8_set_encrypt_key(key, (keylen/2) * 8, &ctx->enc_key);
+ ret |= aes_p8_set_decrypt_key(key, (keylen/2) * 8, &ctx->dec_key);
+ disable_kernel_vsx();
+ pagefault_enable();
+ preempt_enable();
+
+ ret |= crypto_skcipher_setkey(ctx->fallback, key, keylen);
+
+ return ret ? -EINVAL : 0;
+}
+
+static int p8_aes_xts_crypt(struct skcipher_request *req, int enc)
+{
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ const struct p8_aes_xts_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct skcipher_walk walk;
+ unsigned int nbytes;
+ u8 tweak[AES_BLOCK_SIZE];
+ int ret;
+
+ if (req->cryptlen < AES_BLOCK_SIZE)
+ return -EINVAL;
+
+ if (!crypto_simd_usable() || (req->cryptlen % XTS_BLOCK_SIZE) != 0) {
+ struct skcipher_request *subreq = skcipher_request_ctx(req);
+
+ *subreq = *req;
+ skcipher_request_set_tfm(subreq, ctx->fallback);
+ return enc ? crypto_skcipher_encrypt(subreq) :
+ crypto_skcipher_decrypt(subreq);
+ }
+
+ ret = skcipher_walk_virt(&walk, req, false);
+ if (ret)
+ return ret;
+
+ preempt_disable();
+ pagefault_disable();
+ enable_kernel_vsx();
+
+ aes_p8_encrypt(walk.iv, tweak, &ctx->tweak_key);
+
+ disable_kernel_vsx();
+ pagefault_enable();
+ preempt_enable();
+
+ while ((nbytes = walk.nbytes) != 0) {
+ preempt_disable();
+ pagefault_disable();
+ enable_kernel_vsx();
+ if (enc)
+ aes_p8_xts_encrypt(walk.src.virt.addr,
+ walk.dst.virt.addr,
+ round_down(nbytes, AES_BLOCK_SIZE),
+ &ctx->enc_key, NULL, tweak);
+ else
+ aes_p8_xts_decrypt(walk.src.virt.addr,
+ walk.dst.virt.addr,
+ round_down(nbytes, AES_BLOCK_SIZE),
+ &ctx->dec_key, NULL, tweak);
+ disable_kernel_vsx();
+ pagefault_enable();
+ preempt_enable();
+
+ ret = skcipher_walk_done(&walk, nbytes % AES_BLOCK_SIZE);
+ }
+ return ret;
+}
+
+static int p8_aes_xts_encrypt(struct skcipher_request *req)
+{
+ return p8_aes_xts_crypt(req, 1);
+}
+
+static int p8_aes_xts_decrypt(struct skcipher_request *req)
+{
+ return p8_aes_xts_crypt(req, 0);
+}
+
+struct skcipher_alg p8_aes_xts_alg = {
+ .base.cra_name = "xts(aes)",
+ .base.cra_driver_name = "p8_aes_xts",
+ .base.cra_module = THIS_MODULE,
+ .base.cra_priority = 2000,
+ .base.cra_flags = CRYPTO_ALG_NEED_FALLBACK,
+ .base.cra_blocksize = AES_BLOCK_SIZE,
+ .base.cra_ctxsize = sizeof(struct p8_aes_xts_ctx),
+ .setkey = p8_aes_xts_setkey,
+ .encrypt = p8_aes_xts_encrypt,
+ .decrypt = p8_aes_xts_decrypt,
+ .init = p8_aes_xts_init,
+ .exit = p8_aes_xts_exit,
+ .min_keysize = 2 * AES_MIN_KEY_SIZE,
+ .max_keysize = 2 * AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+};
diff --git a/arch/powerpc/crypto/aesp8-ppc.h b/arch/powerpc/crypto/aesp8-ppc.h
new file mode 100644
index 000000000000..5764d4438388
--- /dev/null
+++ b/arch/powerpc/crypto/aesp8-ppc.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <linux/types.h>
+#include <crypto/aes.h>
+
+struct aes_key {
+ u8 key[AES_MAX_KEYLENGTH];
+ int rounds;
+};
+
+extern struct shash_alg p8_ghash_alg;
+extern struct crypto_alg p8_aes_alg;
+extern struct skcipher_alg p8_aes_cbc_alg;
+extern struct skcipher_alg p8_aes_ctr_alg;
+extern struct skcipher_alg p8_aes_xts_alg;
+
+int aes_p8_set_encrypt_key(const u8 *userKey, const int bits,
+ struct aes_key *key);
+int aes_p8_set_decrypt_key(const u8 *userKey, const int bits,
+ struct aes_key *key);
+void aes_p8_encrypt(const u8 *in, u8 *out, const struct aes_key *key);
+void aes_p8_decrypt(const u8 *in, u8 *out, const struct aes_key *key);
+void aes_p8_cbc_encrypt(const u8 *in, u8 *out, size_t len,
+ const struct aes_key *key, u8 *iv, const int enc);
+void aes_p8_ctr32_encrypt_blocks(const u8 *in, u8 *out,
+ size_t len, const struct aes_key *key,
+ const u8 *iv);
+void aes_p8_xts_encrypt(const u8 *in, u8 *out, size_t len,
+ const struct aes_key *key1, const struct aes_key *key2, u8 *iv);
+void aes_p8_xts_decrypt(const u8 *in, u8 *out, size_t len,
+ const struct aes_key *key1, const struct aes_key *key2, u8 *iv);
diff --git a/arch/powerpc/crypto/aesp8-ppc.pl b/arch/powerpc/crypto/aesp8-ppc.pl
new file mode 100644
index 000000000000..f729589d792e
--- /dev/null
+++ b/arch/powerpc/crypto/aesp8-ppc.pl
@@ -0,0 +1,3889 @@
+#! /usr/bin/env perl
+# SPDX-License-Identifier: GPL-2.0
+
+# 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://www.openssl.org/~appro/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/.
+# ====================================================================
+#
+# This module implements support for AES instructions as per PowerISA
+# specification version 2.07, first implemented by POWER8 processor.
+# The module is endian-agnostic in sense that it supports both big-
+# and little-endian cases. Data alignment in parallelizable modes is
+# handled with VSX loads and stores, which implies MSR.VSX flag being
+# set. It should also be noted that ISA specification doesn't prohibit
+# alignment exceptions for these instructions on page boundaries.
+# Initially alignment was handled in pure AltiVec/VMX way [when data
+# is aligned programmatically, which in turn guarantees exception-
+# free execution], but it turned to hamper performance when vcipher
+# instructions are interleaved. It's reckoned that eventual
+# misalignment penalties at page boundaries are in average lower
+# than additional overhead in pure AltiVec approach.
+#
+# May 2016
+#
+# Add XTS subroutine, 9x on little- and 12x improvement on big-endian
+# systems were measured.
+#
+######################################################################
+# Current large-block performance in cycles per byte processed with
+# 128-bit key (less is better).
+#
+# CBC en-/decrypt CTR XTS
+# POWER8[le] 3.96/0.72 0.74 1.1
+# POWER8[be] 3.75/0.65 0.66 1.0
+
+$flavour = shift;
+
+if ($flavour =~ /64/) {
+ $SIZE_T =8;
+ $LRSAVE =2*$SIZE_T;
+ $STU ="stdu";
+ $POP ="ld";
+ $PUSH ="std";
+ $UCMP ="cmpld";
+ $SHL ="sldi";
+} elsif ($flavour =~ /32/) {
+ $SIZE_T =4;
+ $LRSAVE =$SIZE_T;
+ $STU ="stwu";
+ $POP ="lwz";
+ $PUSH ="stw";
+ $UCMP ="cmplw";
+ $SHL ="slwi";
+} else { die "nonsense $flavour"; }
+
+$LITTLE_ENDIAN = ($flavour=~/le$/) ? $SIZE_T : 0;
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
+die "can't locate ppc-xlate.pl";
+
+open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
+
+$FRAME=8*$SIZE_T;
+$prefix="aes_p8";
+
+$sp="r1";
+$vrsave="r12";
+
+#########################################################################
+{{{ # Key setup procedures #
+my ($inp,$bits,$out,$ptr,$cnt,$rounds)=map("r$_",(3..8));
+my ($zero,$in0,$in1,$key,$rcon,$mask,$tmp)=map("v$_",(0..6));
+my ($stage,$outperm,$outmask,$outhead,$outtail)=map("v$_",(7..11));
+
+$code.=<<___;
+.machine "any"
+
+.text
+
+.align 7
+rcon:
+.long 0x01000000, 0x01000000, 0x01000000, 0x01000000 ?rev
+.long 0x1b000000, 0x1b000000, 0x1b000000, 0x1b000000 ?rev
+.long 0x0d0e0f0c, 0x0d0e0f0c, 0x0d0e0f0c, 0x0d0e0f0c ?rev
+.long 0,0,0,0 ?asis
+.long 0x0f102132, 0x43546576, 0x8798a9ba, 0xcbdcedfe
+Lconsts:
+ mflr r0
+ bcl 20,31,\$+4
+ mflr $ptr #vvvvv "distance between . and rcon
+ addi $ptr,$ptr,-0x58
+ mtlr r0
+ blr
+ .long 0
+ .byte 0,12,0x14,0,0,0,0,0
+.asciz "AES for PowerISA 2.07, CRYPTOGAMS by <appro\@openssl.org>"
+
+.globl .${prefix}_set_encrypt_key
+Lset_encrypt_key:
+ mflr r11
+ $PUSH r11,$LRSAVE($sp)
+
+ li $ptr,-1
+ ${UCMP}i $inp,0
+ beq- Lenc_key_abort # if ($inp==0) return -1;
+ ${UCMP}i $out,0
+ beq- Lenc_key_abort # if ($out==0) return -1;
+ li $ptr,-2
+ cmpwi $bits,128
+ blt- Lenc_key_abort
+ cmpwi $bits,256
+ bgt- Lenc_key_abort
+ andi. r0,$bits,0x3f
+ bne- Lenc_key_abort
+
+ lis r0,0xfff0
+ mfspr $vrsave,256
+ mtspr 256,r0
+
+ bl Lconsts
+ mtlr r11
+
+ neg r9,$inp
+ lvx $in0,0,$inp
+ addi $inp,$inp,15 # 15 is not typo
+ lvsr $key,0,r9 # borrow $key
+ li r8,0x20
+ cmpwi $bits,192
+ lvx $in1,0,$inp
+ le?vspltisb $mask,0x0f # borrow $mask
+ lvx $rcon,0,$ptr
+ le?vxor $key,$key,$mask # adjust for byte swap
+ lvx $mask,r8,$ptr
+ addi $ptr,$ptr,0x10
+ vperm $in0,$in0,$in1,$key # align [and byte swap in LE]
+ li $cnt,8
+ vxor $zero,$zero,$zero
+ mtctr $cnt
+
+ ?lvsr $outperm,0,$out
+ vspltisb $outmask,-1
+ lvx $outhead,0,$out
+ ?vperm $outmask,$zero,$outmask,$outperm
+
+ blt Loop128
+ addi $inp,$inp,8
+ beq L192
+ addi $inp,$inp,8
+ b L256
+
+.align 4
+Loop128:
+ vperm $key,$in0,$in0,$mask # rotate-n-splat
+ vsldoi $tmp,$zero,$in0,12 # >>32
+ vperm $outtail,$in0,$in0,$outperm # rotate
+ vsel $stage,$outhead,$outtail,$outmask
+ vmr $outhead,$outtail
+ vcipherlast $key,$key,$rcon
+ stvx $stage,0,$out
+ addi $out,$out,16
+
+ vxor $in0,$in0,$tmp
+ vsldoi $tmp,$zero,$tmp,12 # >>32
+ vxor $in0,$in0,$tmp
+ vsldoi $tmp,$zero,$tmp,12 # >>32
+ vxor $in0,$in0,$tmp
+ vadduwm $rcon,$rcon,$rcon
+ vxor $in0,$in0,$key
+ bdnz Loop128
+
+ lvx $rcon,0,$ptr # last two round keys
+
+ vperm $key,$in0,$in0,$mask # rotate-n-splat
+ vsldoi $tmp,$zero,$in0,12 # >>32
+ vperm $outtail,$in0,$in0,$outperm # rotate
+ vsel $stage,$outhead,$outtail,$outmask
+ vmr $outhead,$outtail
+ vcipherlast $key,$key,$rcon
+ stvx $stage,0,$out
+ addi $out,$out,16
+
+ vxor $in0,$in0,$tmp
+ vsldoi $tmp,$zero,$tmp,12 # >>32
+ vxor $in0,$in0,$tmp
+ vsldoi $tmp,$zero,$tmp,12 # >>32
+ vxor $in0,$in0,$tmp
+ vadduwm $rcon,$rcon,$rcon
+ vxor $in0,$in0,$key
+
+ vperm $key,$in0,$in0,$mask # rotate-n-splat
+ vsldoi $tmp,$zero,$in0,12 # >>32
+ vperm $outtail,$in0,$in0,$outperm # rotate
+ vsel $stage,$outhead,$outtail,$outmask
+ vmr $outhead,$outtail
+ vcipherlast $key,$key,$rcon
+ stvx $stage,0,$out
+ addi $out,$out,16
+
+ vxor $in0,$in0,$tmp
+ vsldoi $tmp,$zero,$tmp,12 # >>32
+ vxor $in0,$in0,$tmp
+ vsldoi $tmp,$zero,$tmp,12 # >>32
+ vxor $in0,$in0,$tmp
+ vxor $in0,$in0,$key
+ vperm $outtail,$in0,$in0,$outperm # rotate
+ vsel $stage,$outhead,$outtail,$outmask
+ vmr $outhead,$outtail
+ stvx $stage,0,$out
+
+ addi $inp,$out,15 # 15 is not typo
+ addi $out,$out,0x50
+
+ li $rounds,10
+ b Ldone
+
+.align 4
+L192:
+ lvx $tmp,0,$inp
+ li $cnt,4
+ vperm $outtail,$in0,$in0,$outperm # rotate
+ vsel $stage,$outhead,$outtail,$outmask
+ vmr $outhead,$outtail
+ stvx $stage,0,$out
+ addi $out,$out,16
+ vperm $in1,$in1,$tmp,$key # align [and byte swap in LE]
+ vspltisb $key,8 # borrow $key
+ mtctr $cnt
+ vsububm $mask,$mask,$key # adjust the mask
+
+Loop192:
+ vperm $key,$in1,$in1,$mask # roate-n-splat
+ vsldoi $tmp,$zero,$in0,12 # >>32
+ vcipherlast $key,$key,$rcon
+
+ vxor $in0,$in0,$tmp
+ vsldoi $tmp,$zero,$tmp,12 # >>32
+ vxor $in0,$in0,$tmp
+ vsldoi $tmp,$zero,$tmp,12 # >>32
+ vxor $in0,$in0,$tmp
+
+ vsldoi $stage,$zero,$in1,8
+ vspltw $tmp,$in0,3
+ vxor $tmp,$tmp,$in1
+ vsldoi $in1,$zero,$in1,12 # >>32
+ vadduwm $rcon,$rcon,$rcon
+ vxor $in1,$in1,$tmp
+ vxor $in0,$in0,$key
+ vxor $in1,$in1,$key
+ vsldoi $stage,$stage,$in0,8
+
+ vperm $key,$in1,$in1,$mask # rotate-n-splat
+ vsldoi $tmp,$zero,$in0,12 # >>32
+ vperm $outtail,$stage,$stage,$outperm # rotate
+ vsel $stage,$outhead,$outtail,$outmask
+ vmr $outhead,$outtail
+ vcipherlast $key,$key,$rcon
+ stvx $stage,0,$out
+ addi $out,$out,16
+
+ vsldoi $stage,$in0,$in1,8
+ vxor $in0,$in0,$tmp
+ vsldoi $tmp,$zero,$tmp,12 # >>32
+ vperm $outtail,$stage,$stage,$outperm # rotate
+ vsel $stage,$outhead,$outtail,$outmask
+ vmr $outhead,$outtail
+ vxor $in0,$in0,$tmp
+ vsldoi $tmp,$zero,$tmp,12 # >>32
+ vxor $in0,$in0,$tmp
+ stvx $stage,0,$out
+ addi $out,$out,16
+
+ vspltw $tmp,$in0,3
+ vxor $tmp,$tmp,$in1
+ vsldoi $in1,$zero,$in1,12 # >>32
+ vadduwm $rcon,$rcon,$rcon
+ vxor $in1,$in1,$tmp
+ vxor $in0,$in0,$key
+ vxor $in1,$in1,$key
+ vperm $outtail,$in0,$in0,$outperm # rotate
+ vsel $stage,$outhead,$outtail,$outmask
+ vmr $outhead,$outtail
+ stvx $stage,0,$out
+ addi $inp,$out,15 # 15 is not typo
+ addi $out,$out,16
+ bdnz Loop192
+
+ li $rounds,12
+ addi $out,$out,0x20
+ b Ldone
+
+.align 4
+L256:
+ lvx $tmp,0,$inp
+ li $cnt,7
+ li $rounds,14
+ vperm $outtail,$in0,$in0,$outperm # rotate
+ vsel $stage,$outhead,$outtail,$outmask
+ vmr $outhead,$outtail
+ stvx $stage,0,$out
+ addi $out,$out,16
+ vperm $in1,$in1,$tmp,$key # align [and byte swap in LE]
+ mtctr $cnt
+
+Loop256:
+ vperm $key,$in1,$in1,$mask # rotate-n-splat
+ vsldoi $tmp,$zero,$in0,12 # >>32
+ vperm $outtail,$in1,$in1,$outperm # rotate
+ vsel $stage,$outhead,$outtail,$outmask
+ vmr $outhead,$outtail
+ vcipherlast $key,$key,$rcon
+ stvx $stage,0,$out
+ addi $out,$out,16
+
+ vxor $in0,$in0,$tmp
+ vsldoi $tmp,$zero,$tmp,12 # >>32
+ vxor $in0,$in0,$tmp
+ vsldoi $tmp,$zero,$tmp,12 # >>32
+ vxor $in0,$in0,$tmp
+ vadduwm $rcon,$rcon,$rcon
+ vxor $in0,$in0,$key
+ vperm $outtail,$in0,$in0,$outperm # rotate
+ vsel $stage,$outhead,$outtail,$outmask
+ vmr $outhead,$outtail
+ stvx $stage,0,$out
+ addi $inp,$out,15 # 15 is not typo
+ addi $out,$out,16
+ bdz Ldone
+
+ vspltw $key,$in0,3 # just splat
+ vsldoi $tmp,$zero,$in1,12 # >>32
+ vsbox $key,$key
+
+ vxor $in1,$in1,$tmp
+ vsldoi $tmp,$zero,$tmp,12 # >>32
+ vxor $in1,$in1,$tmp
+ vsldoi $tmp,$zero,$tmp,12 # >>32
+ vxor $in1,$in1,$tmp
+
+ vxor $in1,$in1,$key
+ b Loop256
+
+.align 4
+Ldone:
+ lvx $in1,0,$inp # redundant in aligned case
+ vsel $in1,$outhead,$in1,$outmask
+ stvx $in1,0,$inp
+ li $ptr,0
+ mtspr 256,$vrsave
+ stw $rounds,0($out)
+
+Lenc_key_abort:
+ mr r3,$ptr
+ blr
+ .long 0
+ .byte 0,12,0x14,1,0,0,3,0
+ .long 0
+.size .${prefix}_set_encrypt_key,.-.${prefix}_set_encrypt_key
+
+.globl .${prefix}_set_decrypt_key
+ $STU $sp,-$FRAME($sp)
+ mflr r10
+ $PUSH r10,$FRAME+$LRSAVE($sp)
+ bl Lset_encrypt_key
+ mtlr r10
+
+ cmpwi r3,0
+ bne- Ldec_key_abort
+
+ slwi $cnt,$rounds,4
+ subi $inp,$out,240 # first round key
+ srwi $rounds,$rounds,1
+ add $out,$inp,$cnt # last round key
+ mtctr $rounds
+
+Ldeckey:
+ lwz r0, 0($inp)
+ lwz r6, 4($inp)
+ lwz r7, 8($inp)
+ lwz r8, 12($inp)
+ addi $inp,$inp,16
+ lwz r9, 0($out)
+ lwz r10,4($out)
+ lwz r11,8($out)
+ lwz r12,12($out)
+ stw r0, 0($out)
+ stw r6, 4($out)
+ stw r7, 8($out)
+ stw r8, 12($out)
+ subi $out,$out,16
+ stw r9, -16($inp)
+ stw r10,-12($inp)
+ stw r11,-8($inp)
+ stw r12,-4($inp)
+ bdnz Ldeckey
+
+ xor r3,r3,r3 # return value
+Ldec_key_abort:
+ addi $sp,$sp,$FRAME
+ blr
+ .long 0
+ .byte 0,12,4,1,0x80,0,3,0
+ .long 0
+.size .${prefix}_set_decrypt_key,.-.${prefix}_set_decrypt_key
+___
+}}}
+#########################################################################
+{{{ # Single block en- and decrypt procedures #
+sub gen_block () {
+my $dir = shift;
+my $n = $dir eq "de" ? "n" : "";
+my ($inp,$out,$key,$rounds,$idx)=map("r$_",(3..7));
+
+$code.=<<___;
+.globl .${prefix}_${dir}crypt
+ lwz $rounds,240($key)
+ lis r0,0xfc00
+ mfspr $vrsave,256
+ li $idx,15 # 15 is not typo
+ mtspr 256,r0
+
+ lvx v0,0,$inp
+ neg r11,$out
+ lvx v1,$idx,$inp
+ lvsl v2,0,$inp # inpperm
+ le?vspltisb v4,0x0f
+ ?lvsl v3,0,r11 # outperm
+ le?vxor v2,v2,v4
+ li $idx,16
+ vperm v0,v0,v1,v2 # align [and byte swap in LE]
+ lvx v1,0,$key
+ ?lvsl v5,0,$key # keyperm
+ srwi $rounds,$rounds,1
+ lvx v2,$idx,$key
+ addi $idx,$idx,16
+ subi $rounds,$rounds,1
+ ?vperm v1,v1,v2,v5 # align round key
+
+ vxor v0,v0,v1
+ lvx v1,$idx,$key
+ addi $idx,$idx,16
+ mtctr $rounds
+
+Loop_${dir}c:
+ ?vperm v2,v2,v1,v5
+ v${n}cipher v0,v0,v2
+ lvx v2,$idx,$key
+ addi $idx,$idx,16
+ ?vperm v1,v1,v2,v5
+ v${n}cipher v0,v0,v1
+ lvx v1,$idx,$key
+ addi $idx,$idx,16
+ bdnz Loop_${dir}c
+
+ ?vperm v2,v2,v1,v5
+ v${n}cipher v0,v0,v2
+ lvx v2,$idx,$key
+ ?vperm v1,v1,v2,v5
+ v${n}cipherlast v0,v0,v1
+
+ vspltisb v2,-1
+ vxor v1,v1,v1
+ li $idx,15 # 15 is not typo
+ ?vperm v2,v1,v2,v3 # outmask
+ le?vxor v3,v3,v4
+ lvx v1,0,$out # outhead
+ vperm v0,v0,v0,v3 # rotate [and byte swap in LE]
+ vsel v1,v1,v0,v2
+ lvx v4,$idx,$out
+ stvx v1,0,$out
+ vsel v0,v0,v4,v2
+ stvx v0,$idx,$out
+
+ mtspr 256,$vrsave
+ blr
+ .long 0
+ .byte 0,12,0x14,0,0,0,3,0
+ .long 0
+.size .${prefix}_${dir}crypt,.-.${prefix}_${dir}crypt
+___
+}
+&gen_block("en");
+&gen_block("de");
+}}}
+#########################################################################
+{{{ # CBC en- and decrypt procedures #
+my ($inp,$out,$len,$key,$ivp,$enc,$rounds,$idx)=map("r$_",(3..10));
+my ($rndkey0,$rndkey1,$inout,$tmp)= map("v$_",(0..3));
+my ($ivec,$inptail,$inpperm,$outhead,$outperm,$outmask,$keyperm)=
+ map("v$_",(4..10));
+$code.=<<___;
+.globl .${prefix}_cbc_encrypt
+ ${UCMP}i $len,16
+ bltlr-
+
+ cmpwi $enc,0 # test direction
+ lis r0,0xffe0
+ mfspr $vrsave,256
+ mtspr 256,r0
+
+ li $idx,15
+ vxor $rndkey0,$rndkey0,$rndkey0
+ le?vspltisb $tmp,0x0f
+
+ lvx $ivec,0,$ivp # load [unaligned] iv
+ lvsl $inpperm,0,$ivp
+ lvx $inptail,$idx,$ivp
+ le?vxor $inpperm,$inpperm,$tmp
+ vperm $ivec,$ivec,$inptail,$inpperm
+
+ neg r11,$inp
+ ?lvsl $keyperm,0,$key # prepare for unaligned key
+ lwz $rounds,240($key)
+
+ lvsr $inpperm,0,r11 # prepare for unaligned load
+ lvx $inptail,0,$inp
+ addi $inp,$inp,15 # 15 is not typo
+ le?vxor $inpperm,$inpperm,$tmp
+
+ ?lvsr $outperm,0,$out # prepare for unaligned store
+ vspltisb $outmask,-1
+ lvx $outhead,0,$out
+ ?vperm $outmask,$rndkey0,$outmask,$outperm
+ le?vxor $outperm,$outperm,$tmp
+
+ srwi $rounds,$rounds,1
+ li $idx,16
+ subi $rounds,$rounds,1
+ beq Lcbc_dec
+
+Lcbc_enc:
+ vmr $inout,$inptail
+ lvx $inptail,0,$inp
+ addi $inp,$inp,16
+ mtctr $rounds
+ subi $len,$len,16 # len-=16
+
+ lvx $rndkey0,0,$key
+ vperm $inout,$inout,$inptail,$inpperm
+ lvx $rndkey1,$idx,$key
+ addi $idx,$idx,16
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+ vxor $inout,$inout,$rndkey0
+ lvx $rndkey0,$idx,$key
+ addi $idx,$idx,16
+ vxor $inout,$inout,$ivec
+
+Loop_cbc_enc:
+ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm
+ vcipher $inout,$inout,$rndkey1
+ lvx $rndkey1,$idx,$key
+ addi $idx,$idx,16
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+ vcipher $inout,$inout,$rndkey0
+ lvx $rndkey0,$idx,$key
+ addi $idx,$idx,16
+ bdnz Loop_cbc_enc
+
+ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm
+ vcipher $inout,$inout,$rndkey1
+ lvx $rndkey1,$idx,$key
+ li $idx,16
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+ vcipherlast $ivec,$inout,$rndkey0
+ ${UCMP}i $len,16
+
+ vperm $tmp,$ivec,$ivec,$outperm
+ vsel $inout,$outhead,$tmp,$outmask
+ vmr $outhead,$tmp
+ stvx $inout,0,$out
+ addi $out,$out,16
+ bge Lcbc_enc
+
+ b Lcbc_done
+
+.align 4
+Lcbc_dec:
+ ${UCMP}i $len,128
+ bge _aesp8_cbc_decrypt8x
+ vmr $tmp,$inptail
+ lvx $inptail,0,$inp
+ addi $inp,$inp,16
+ mtctr $rounds
+ subi $len,$len,16 # len-=16
+
+ lvx $rndkey0,0,$key
+ vperm $tmp,$tmp,$inptail,$inpperm
+ lvx $rndkey1,$idx,$key
+ addi $idx,$idx,16
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+ vxor $inout,$tmp,$rndkey0
+ lvx $rndkey0,$idx,$key
+ addi $idx,$idx,16
+
+Loop_cbc_dec:
+ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm
+ vncipher $inout,$inout,$rndkey1
+ lvx $rndkey1,$idx,$key
+ addi $idx,$idx,16
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+ vncipher $inout,$inout,$rndkey0
+ lvx $rndkey0,$idx,$key
+ addi $idx,$idx,16
+ bdnz Loop_cbc_dec
+
+ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm
+ vncipher $inout,$inout,$rndkey1
+ lvx $rndkey1,$idx,$key
+ li $idx,16
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+ vncipherlast $inout,$inout,$rndkey0
+ ${UCMP}i $len,16
+
+ vxor $inout,$inout,$ivec
+ vmr $ivec,$tmp
+ vperm $tmp,$inout,$inout,$outperm
+ vsel $inout,$outhead,$tmp,$outmask
+ vmr $outhead,$tmp
+ stvx $inout,0,$out
+ addi $out,$out,16
+ bge Lcbc_dec
+
+Lcbc_done:
+ addi $out,$out,-1
+ lvx $inout,0,$out # redundant in aligned case
+ vsel $inout,$outhead,$inout,$outmask
+ stvx $inout,0,$out
+
+ neg $enc,$ivp # write [unaligned] iv
+ li $idx,15 # 15 is not typo
+ vxor $rndkey0,$rndkey0,$rndkey0
+ vspltisb $outmask,-1
+ le?vspltisb $tmp,0x0f
+ ?lvsl $outperm,0,$enc
+ ?vperm $outmask,$rndkey0,$outmask,$outperm
+ le?vxor $outperm,$outperm,$tmp
+ lvx $outhead,0,$ivp
+ vperm $ivec,$ivec,$ivec,$outperm
+ vsel $inout,$outhead,$ivec,$outmask
+ lvx $inptail,$idx,$ivp
+ stvx $inout,0,$ivp
+ vsel $inout,$ivec,$inptail,$outmask
+ stvx $inout,$idx,$ivp
+
+ mtspr 256,$vrsave
+ blr
+ .long 0
+ .byte 0,12,0x14,0,0,0,6,0
+ .long 0
+___
+#########################################################################
+{{ # Optimized CBC decrypt procedure #
+my $key_="r11";
+my ($x00,$x10,$x20,$x30,$x40,$x50,$x60,$x70)=map("r$_",(0,8,26..31));
+my ($in0, $in1, $in2, $in3, $in4, $in5, $in6, $in7 )=map("v$_",(0..3,10..13));
+my ($out0,$out1,$out2,$out3,$out4,$out5,$out6,$out7)=map("v$_",(14..21));
+my $rndkey0="v23"; # v24-v25 rotating buffer for first found keys
+ # v26-v31 last 6 round keys
+my ($tmp,$keyperm)=($in3,$in4); # aliases with "caller", redundant assignment
+
+$code.=<<___;
+.align 5
+_aesp8_cbc_decrypt8x:
+ $STU $sp,-`($FRAME+21*16+6*$SIZE_T)`($sp)
+ li r10,`$FRAME+8*16+15`
+ li r11,`$FRAME+8*16+31`
+ stvx v20,r10,$sp # ABI says so
+ addi r10,r10,32
+ stvx v21,r11,$sp
+ addi r11,r11,32
+ stvx v22,r10,$sp
+ addi r10,r10,32
+ stvx v23,r11,$sp
+ addi r11,r11,32
+ stvx v24,r10,$sp
+ addi r10,r10,32
+ stvx v25,r11,$sp
+ addi r11,r11,32
+ stvx v26,r10,$sp
+ addi r10,r10,32
+ stvx v27,r11,$sp
+ addi r11,r11,32
+ stvx v28,r10,$sp
+ addi r10,r10,32
+ stvx v29,r11,$sp
+ addi r11,r11,32
+ stvx v30,r10,$sp
+ stvx v31,r11,$sp
+ li r0,-1
+ stw $vrsave,`$FRAME+21*16-4`($sp) # save vrsave
+ li $x10,0x10
+ $PUSH r26,`$FRAME+21*16+0*$SIZE_T`($sp)
+ li $x20,0x20
+ $PUSH r27,`$FRAME+21*16+1*$SIZE_T`($sp)
+ li $x30,0x30
+ $PUSH r28,`$FRAME+21*16+2*$SIZE_T`($sp)
+ li $x40,0x40
+ $PUSH r29,`$FRAME+21*16+3*$SIZE_T`($sp)
+ li $x50,0x50
+ $PUSH r30,`$FRAME+21*16+4*$SIZE_T`($sp)
+ li $x60,0x60
+ $PUSH r31,`$FRAME+21*16+5*$SIZE_T`($sp)
+ li $x70,0x70
+ mtspr 256,r0
+
+ subi $rounds,$rounds,3 # -4 in total
+ subi $len,$len,128 # bias
+
+ lvx $rndkey0,$x00,$key # load key schedule
+ lvx v30,$x10,$key
+ addi $key,$key,0x20
+ lvx v31,$x00,$key
+ ?vperm $rndkey0,$rndkey0,v30,$keyperm
+ addi $key_,$sp,$FRAME+15
+ mtctr $rounds
+
+Load_cbc_dec_key:
+ ?vperm v24,v30,v31,$keyperm
+ lvx v30,$x10,$key
+ addi $key,$key,0x20
+ stvx v24,$x00,$key_ # off-load round[1]
+ ?vperm v25,v31,v30,$keyperm
+ lvx v31,$x00,$key
+ stvx v25,$x10,$key_ # off-load round[2]
+ addi $key_,$key_,0x20
+ bdnz Load_cbc_dec_key
+
+ lvx v26,$x10,$key
+ ?vperm v24,v30,v31,$keyperm
+ lvx v27,$x20,$key
+ stvx v24,$x00,$key_ # off-load round[3]
+ ?vperm v25,v31,v26,$keyperm
+ lvx v28,$x30,$key
+ stvx v25,$x10,$key_ # off-load round[4]
+ addi $key_,$sp,$FRAME+15 # rewind $key_
+ ?vperm v26,v26,v27,$keyperm
+ lvx v29,$x40,$key
+ ?vperm v27,v27,v28,$keyperm
+ lvx v30,$x50,$key
+ ?vperm v28,v28,v29,$keyperm
+ lvx v31,$x60,$key
+ ?vperm v29,v29,v30,$keyperm
+ lvx $out0,$x70,$key # borrow $out0
+ ?vperm v30,v30,v31,$keyperm
+ lvx v24,$x00,$key_ # pre-load round[1]
+ ?vperm v31,v31,$out0,$keyperm
+ lvx v25,$x10,$key_ # pre-load round[2]
+
+ #lvx $inptail,0,$inp # "caller" already did this
+ #addi $inp,$inp,15 # 15 is not typo
+ subi $inp,$inp,15 # undo "caller"
+
+ le?li $idx,8
+ lvx_u $in0,$x00,$inp # load first 8 "words"
+ le?lvsl $inpperm,0,$idx
+ le?vspltisb $tmp,0x0f
+ lvx_u $in1,$x10,$inp
+ le?vxor $inpperm,$inpperm,$tmp # transform for lvx_u/stvx_u
+ lvx_u $in2,$x20,$inp
+ le?vperm $in0,$in0,$in0,$inpperm
+ lvx_u $in3,$x30,$inp
+ le?vperm $in1,$in1,$in1,$inpperm
+ lvx_u $in4,$x40,$inp
+ le?vperm $in2,$in2,$in2,$inpperm
+ vxor $out0,$in0,$rndkey0
+ lvx_u $in5,$x50,$inp
+ le?vperm $in3,$in3,$in3,$inpperm
+ vxor $out1,$in1,$rndkey0
+ lvx_u $in6,$x60,$inp
+ le?vperm $in4,$in4,$in4,$inpperm
+ vxor $out2,$in2,$rndkey0
+ lvx_u $in7,$x70,$inp
+ addi $inp,$inp,0x80
+ le?vperm $in5,$in5,$in5,$inpperm
+ vxor $out3,$in3,$rndkey0
+ le?vperm $in6,$in6,$in6,$inpperm
+ vxor $out4,$in4,$rndkey0
+ le?vperm $in7,$in7,$in7,$inpperm
+ vxor $out5,$in5,$rndkey0
+ vxor $out6,$in6,$rndkey0
+ vxor $out7,$in7,$rndkey0
+
+ mtctr $rounds
+ b Loop_cbc_dec8x
+.align 5
+Loop_cbc_dec8x:
+ vncipher $out0,$out0,v24
+ vncipher $out1,$out1,v24
+ vncipher $out2,$out2,v24
+ vncipher $out3,$out3,v24
+ vncipher $out4,$out4,v24
+ vncipher $out5,$out5,v24
+ vncipher $out6,$out6,v24
+ vncipher $out7,$out7,v24
+ lvx v24,$x20,$key_ # round[3]
+ addi $key_,$key_,0x20
+
+ vncipher $out0,$out0,v25
+ vncipher $out1,$out1,v25
+ vncipher $out2,$out2,v25
+ vncipher $out3,$out3,v25
+ vncipher $out4,$out4,v25
+ vncipher $out5,$out5,v25
+ vncipher $out6,$out6,v25
+ vncipher $out7,$out7,v25
+ lvx v25,$x10,$key_ # round[4]
+ bdnz Loop_cbc_dec8x
+
+ subic $len,$len,128 # $len-=128
+ vncipher $out0,$out0,v24
+ vncipher $out1,$out1,v24
+ vncipher $out2,$out2,v24
+ vncipher $out3,$out3,v24
+ vncipher $out4,$out4,v24
+ vncipher $out5,$out5,v24
+ vncipher $out6,$out6,v24
+ vncipher $out7,$out7,v24
+
+ subfe. r0,r0,r0 # borrow?-1:0
+ vncipher $out0,$out0,v25
+ vncipher $out1,$out1,v25
+ vncipher $out2,$out2,v25
+ vncipher $out3,$out3,v25
+ vncipher $out4,$out4,v25
+ vncipher $out5,$out5,v25
+ vncipher $out6,$out6,v25
+ vncipher $out7,$out7,v25
+
+ and r0,r0,$len
+ vncipher $out0,$out0,v26
+ vncipher $out1,$out1,v26
+ vncipher $out2,$out2,v26
+ vncipher $out3,$out3,v26
+ vncipher $out4,$out4,v26
+ vncipher $out5,$out5,v26
+ vncipher $out6,$out6,v26
+ vncipher $out7,$out7,v26
+
+ add $inp,$inp,r0 # $inp is adjusted in such
+ # way that at exit from the
+ # loop inX-in7 are loaded
+ # with last "words"
+ vncipher $out0,$out0,v27
+ vncipher $out1,$out1,v27
+ vncipher $out2,$out2,v27
+ vncipher $out3,$out3,v27
+ vncipher $out4,$out4,v27
+ vncipher $out5,$out5,v27
+ vncipher $out6,$out6,v27
+ vncipher $out7,$out7,v27
+
+ addi $key_,$sp,$FRAME+15 # rewind $key_
+ vncipher $out0,$out0,v28
+ vncipher $out1,$out1,v28
+ vncipher $out2,$out2,v28
+ vncipher $out3,$out3,v28
+ vncipher $out4,$out4,v28
+ vncipher $out5,$out5,v28
+ vncipher $out6,$out6,v28
+ vncipher $out7,$out7,v28
+ lvx v24,$x00,$key_ # re-pre-load round[1]
+
+ vncipher $out0,$out0,v29
+ vncipher $out1,$out1,v29
+ vncipher $out2,$out2,v29
+ vncipher $out3,$out3,v29
+ vncipher $out4,$out4,v29
+ vncipher $out5,$out5,v29
+ vncipher $out6,$out6,v29
+ vncipher $out7,$out7,v29
+ lvx v25,$x10,$key_ # re-pre-load round[2]
+
+ vncipher $out0,$out0,v30
+ vxor $ivec,$ivec,v31 # xor with last round key
+ vncipher $out1,$out1,v30
+ vxor $in0,$in0,v31
+ vncipher $out2,$out2,v30
+ vxor $in1,$in1,v31
+ vncipher $out3,$out3,v30
+ vxor $in2,$in2,v31
+ vncipher $out4,$out4,v30
+ vxor $in3,$in3,v31
+ vncipher $out5,$out5,v30
+ vxor $in4,$in4,v31
+ vncipher $out6,$out6,v30
+ vxor $in5,$in5,v31
+ vncipher $out7,$out7,v30
+ vxor $in6,$in6,v31
+
+ vncipherlast $out0,$out0,$ivec
+ vncipherlast $out1,$out1,$in0
+ lvx_u $in0,$x00,$inp # load next input block
+ vncipherlast $out2,$out2,$in1
+ lvx_u $in1,$x10,$inp
+ vncipherlast $out3,$out3,$in2
+ le?vperm $in0,$in0,$in0,$inpperm
+ lvx_u $in2,$x20,$inp
+ vncipherlast $out4,$out4,$in3
+ le?vperm $in1,$in1,$in1,$inpperm
+ lvx_u $in3,$x30,$inp
+ vncipherlast $out5,$out5,$in4
+ le?vperm $in2,$in2,$in2,$inpperm
+ lvx_u $in4,$x40,$inp
+ vncipherlast $out6,$out6,$in5
+ le?vperm $in3,$in3,$in3,$inpperm
+ lvx_u $in5,$x50,$inp
+ vncipherlast $out7,$out7,$in6
+ le?vperm $in4,$in4,$in4,$inpperm
+ lvx_u $in6,$x60,$inp
+ vmr $ivec,$in7
+ le?vperm $in5,$in5,$in5,$inpperm
+ lvx_u $in7,$x70,$inp
+ addi $inp,$inp,0x80
+
+ le?vperm $out0,$out0,$out0,$inpperm
+ le?vperm $out1,$out1,$out1,$inpperm
+ stvx_u $out0,$x00,$out
+ le?vperm $in6,$in6,$in6,$inpperm
+ vxor $out0,$in0,$rndkey0
+ le?vperm $out2,$out2,$out2,$inpperm
+ stvx_u $out1,$x10,$out
+ le?vperm $in7,$in7,$in7,$inpperm
+ vxor $out1,$in1,$rndkey0
+ le?vperm $out3,$out3,$out3,$inpperm
+ stvx_u $out2,$x20,$out
+ vxor $out2,$in2,$rndkey0
+ le?vperm $out4,$out4,$out4,$inpperm
+ stvx_u $out3,$x30,$out
+ vxor $out3,$in3,$rndkey0
+ le?vperm $out5,$out5,$out5,$inpperm
+ stvx_u $out4,$x40,$out
+ vxor $out4,$in4,$rndkey0
+ le?vperm $out6,$out6,$out6,$inpperm
+ stvx_u $out5,$x50,$out
+ vxor $out5,$in5,$rndkey0
+ le?vperm $out7,$out7,$out7,$inpperm
+ stvx_u $out6,$x60,$out
+ vxor $out6,$in6,$rndkey0
+ stvx_u $out7,$x70,$out
+ addi $out,$out,0x80
+ vxor $out7,$in7,$rndkey0
+
+ mtctr $rounds
+ beq Loop_cbc_dec8x # did $len-=128 borrow?
+
+ addic. $len,$len,128
+ beq Lcbc_dec8x_done
+ nop
+ nop
+
+Loop_cbc_dec8x_tail: # up to 7 "words" tail...
+ vncipher $out1,$out1,v24
+ vncipher $out2,$out2,v24
+ vncipher $out3,$out3,v24
+ vncipher $out4,$out4,v24
+ vncipher $out5,$out5,v24
+ vncipher $out6,$out6,v24
+ vncipher $out7,$out7,v24
+ lvx v24,$x20,$key_ # round[3]
+ addi $key_,$key_,0x20
+
+ vncipher $out1,$out1,v25
+ vncipher $out2,$out2,v25
+ vncipher $out3,$out3,v25
+ vncipher $out4,$out4,v25
+ vncipher $out5,$out5,v25
+ vncipher $out6,$out6,v25
+ vncipher $out7,$out7,v25
+ lvx v25,$x10,$key_ # round[4]
+ bdnz Loop_cbc_dec8x_tail
+
+ vncipher $out1,$out1,v24
+ vncipher $out2,$out2,v24
+ vncipher $out3,$out3,v24
+ vncipher $out4,$out4,v24
+ vncipher $out5,$out5,v24
+ vncipher $out6,$out6,v24
+ vncipher $out7,$out7,v24
+
+ vncipher $out1,$out1,v25
+ vncipher $out2,$out2,v25
+ vncipher $out3,$out3,v25
+ vncipher $out4,$out4,v25
+ vncipher $out5,$out5,v25
+ vncipher $out6,$out6,v25
+ vncipher $out7,$out7,v25
+
+ vncipher $out1,$out1,v26
+ vncipher $out2,$out2,v26
+ vncipher $out3,$out3,v26
+ vncipher $out4,$out4,v26
+ vncipher $out5,$out5,v26
+ vncipher $out6,$out6,v26
+ vncipher $out7,$out7,v26
+
+ vncipher $out1,$out1,v27
+ vncipher $out2,$out2,v27
+ vncipher $out3,$out3,v27
+ vncipher $out4,$out4,v27
+ vncipher $out5,$out5,v27
+ vncipher $out6,$out6,v27
+ vncipher $out7,$out7,v27
+
+ vncipher $out1,$out1,v28
+ vncipher $out2,$out2,v28
+ vncipher $out3,$out3,v28
+ vncipher $out4,$out4,v28
+ vncipher $out5,$out5,v28
+ vncipher $out6,$out6,v28
+ vncipher $out7,$out7,v28
+
+ vncipher $out1,$out1,v29
+ vncipher $out2,$out2,v29
+ vncipher $out3,$out3,v29
+ vncipher $out4,$out4,v29
+ vncipher $out5,$out5,v29
+ vncipher $out6,$out6,v29
+ vncipher $out7,$out7,v29
+
+ vncipher $out1,$out1,v30
+ vxor $ivec,$ivec,v31 # last round key
+ vncipher $out2,$out2,v30
+ vxor $in1,$in1,v31
+ vncipher $out3,$out3,v30
+ vxor $in2,$in2,v31
+ vncipher $out4,$out4,v30
+ vxor $in3,$in3,v31
+ vncipher $out5,$out5,v30
+ vxor $in4,$in4,v31
+ vncipher $out6,$out6,v30
+ vxor $in5,$in5,v31
+ vncipher $out7,$out7,v30
+ vxor $in6,$in6,v31
+
+ cmplwi $len,32 # switch($len)
+ blt Lcbc_dec8x_one
+ nop
+ beq Lcbc_dec8x_two
+ cmplwi $len,64
+ blt Lcbc_dec8x_three
+ nop
+ beq Lcbc_dec8x_four
+ cmplwi $len,96
+ blt Lcbc_dec8x_five
+ nop
+ beq Lcbc_dec8x_six
+
+Lcbc_dec8x_seven:
+ vncipherlast $out1,$out1,$ivec
+ vncipherlast $out2,$out2,$in1
+ vncipherlast $out3,$out3,$in2
+ vncipherlast $out4,$out4,$in3
+ vncipherlast $out5,$out5,$in4
+ vncipherlast $out6,$out6,$in5
+ vncipherlast $out7,$out7,$in6
+ vmr $ivec,$in7
+
+ le?vperm $out1,$out1,$out1,$inpperm
+ le?vperm $out2,$out2,$out2,$inpperm
+ stvx_u $out1,$x00,$out
+ le?vperm $out3,$out3,$out3,$inpperm
+ stvx_u $out2,$x10,$out
+ le?vperm $out4,$out4,$out4,$inpperm
+ stvx_u $out3,$x20,$out
+ le?vperm $out5,$out5,$out5,$inpperm
+ stvx_u $out4,$x30,$out
+ le?vperm $out6,$out6,$out6,$inpperm
+ stvx_u $out5,$x40,$out
+ le?vperm $out7,$out7,$out7,$inpperm
+ stvx_u $out6,$x50,$out
+ stvx_u $out7,$x60,$out
+ addi $out,$out,0x70
+ b Lcbc_dec8x_done
+
+.align 5
+Lcbc_dec8x_six:
+ vncipherlast $out2,$out2,$ivec
+ vncipherlast $out3,$out3,$in2
+ vncipherlast $out4,$out4,$in3
+ vncipherlast $out5,$out5,$in4
+ vncipherlast $out6,$out6,$in5
+ vncipherlast $out7,$out7,$in6
+ vmr $ivec,$in7
+
+ le?vperm $out2,$out2,$out2,$inpperm
+ le?vperm $out3,$out3,$out3,$inpperm
+ stvx_u $out2,$x00,$out
+ le?vperm $out4,$out4,$out4,$inpperm
+ stvx_u $out3,$x10,$out
+ le?vperm $out5,$out5,$out5,$inpperm
+ stvx_u $out4,$x20,$out
+ le?vperm $out6,$out6,$out6,$inpperm
+ stvx_u $out5,$x30,$out
+ le?vperm $out7,$out7,$out7,$inpperm
+ stvx_u $out6,$x40,$out
+ stvx_u $out7,$x50,$out
+ addi $out,$out,0x60
+ b Lcbc_dec8x_done
+
+.align 5
+Lcbc_dec8x_five:
+ vncipherlast $out3,$out3,$ivec
+ vncipherlast $out4,$out4,$in3
+ vncipherlast $out5,$out5,$in4
+ vncipherlast $out6,$out6,$in5
+ vncipherlast $out7,$out7,$in6
+ vmr $ivec,$in7
+
+ le?vperm $out3,$out3,$out3,$inpperm
+ le?vperm $out4,$out4,$out4,$inpperm
+ stvx_u $out3,$x00,$out
+ le?vperm $out5,$out5,$out5,$inpperm
+ stvx_u $out4,$x10,$out
+ le?vperm $out6,$out6,$out6,$inpperm
+ stvx_u $out5,$x20,$out
+ le?vperm $out7,$out7,$out7,$inpperm
+ stvx_u $out6,$x30,$out
+ stvx_u $out7,$x40,$out
+ addi $out,$out,0x50
+ b Lcbc_dec8x_done
+
+.align 5
+Lcbc_dec8x_four:
+ vncipherlast $out4,$out4,$ivec
+ vncipherlast $out5,$out5,$in4
+ vncipherlast $out6,$out6,$in5
+ vncipherlast $out7,$out7,$in6
+ vmr $ivec,$in7
+
+ le?vperm $out4,$out4,$out4,$inpperm
+ le?vperm $out5,$out5,$out5,$inpperm
+ stvx_u $out4,$x00,$out
+ le?vperm $out6,$out6,$out6,$inpperm
+ stvx_u $out5,$x10,$out
+ le?vperm $out7,$out7,$out7,$inpperm
+ stvx_u $out6,$x20,$out
+ stvx_u $out7,$x30,$out
+ addi $out,$out,0x40
+ b Lcbc_dec8x_done
+
+.align 5
+Lcbc_dec8x_three:
+ vncipherlast $out5,$out5,$ivec
+ vncipherlast $out6,$out6,$in5
+ vncipherlast $out7,$out7,$in6
+ vmr $ivec,$in7
+
+ le?vperm $out5,$out5,$out5,$inpperm
+ le?vperm $out6,$out6,$out6,$inpperm
+ stvx_u $out5,$x00,$out
+ le?vperm $out7,$out7,$out7,$inpperm
+ stvx_u $out6,$x10,$out
+ stvx_u $out7,$x20,$out
+ addi $out,$out,0x30
+ b Lcbc_dec8x_done
+
+.align 5
+Lcbc_dec8x_two:
+ vncipherlast $out6,$out6,$ivec
+ vncipherlast $out7,$out7,$in6
+ vmr $ivec,$in7
+
+ le?vperm $out6,$out6,$out6,$inpperm
+ le?vperm $out7,$out7,$out7,$inpperm
+ stvx_u $out6,$x00,$out
+ stvx_u $out7,$x10,$out
+ addi $out,$out,0x20
+ b Lcbc_dec8x_done
+
+.align 5
+Lcbc_dec8x_one:
+ vncipherlast $out7,$out7,$ivec
+ vmr $ivec,$in7
+
+ le?vperm $out7,$out7,$out7,$inpperm
+ stvx_u $out7,0,$out
+ addi $out,$out,0x10
+
+Lcbc_dec8x_done:
+ le?vperm $ivec,$ivec,$ivec,$inpperm
+ stvx_u $ivec,0,$ivp # write [unaligned] iv
+
+ li r10,`$FRAME+15`
+ li r11,`$FRAME+31`
+ stvx $inpperm,r10,$sp # wipe copies of round keys
+ addi r10,r10,32
+ stvx $inpperm,r11,$sp
+ addi r11,r11,32
+ stvx $inpperm,r10,$sp
+ addi r10,r10,32
+ stvx $inpperm,r11,$sp
+ addi r11,r11,32
+ stvx $inpperm,r10,$sp
+ addi r10,r10,32
+ stvx $inpperm,r11,$sp
+ addi r11,r11,32
+ stvx $inpperm,r10,$sp
+ addi r10,r10,32
+ stvx $inpperm,r11,$sp
+ addi r11,r11,32
+
+ mtspr 256,$vrsave
+ lvx v20,r10,$sp # ABI says so
+ addi r10,r10,32
+ lvx v21,r11,$sp
+ addi r11,r11,32
+ lvx v22,r10,$sp
+ addi r10,r10,32
+ lvx v23,r11,$sp
+ addi r11,r11,32
+ lvx v24,r10,$sp
+ addi r10,r10,32
+ lvx v25,r11,$sp
+ addi r11,r11,32
+ lvx v26,r10,$sp
+ addi r10,r10,32
+ lvx v27,r11,$sp
+ addi r11,r11,32
+ lvx v28,r10,$sp
+ addi r10,r10,32
+ lvx v29,r11,$sp
+ addi r11,r11,32
+ lvx v30,r10,$sp
+ lvx v31,r11,$sp
+ $POP r26,`$FRAME+21*16+0*$SIZE_T`($sp)
+ $POP r27,`$FRAME+21*16+1*$SIZE_T`($sp)
+ $POP r28,`$FRAME+21*16+2*$SIZE_T`($sp)
+ $POP r29,`$FRAME+21*16+3*$SIZE_T`($sp)
+ $POP r30,`$FRAME+21*16+4*$SIZE_T`($sp)
+ $POP r31,`$FRAME+21*16+5*$SIZE_T`($sp)
+ addi $sp,$sp,`$FRAME+21*16+6*$SIZE_T`
+ blr
+ .long 0
+ .byte 0,12,0x14,0,0x80,6,6,0
+ .long 0
+.size .${prefix}_cbc_encrypt,.-.${prefix}_cbc_encrypt
+___
+}} }}}
+
+#########################################################################
+{{{ # CTR procedure[s] #
+
+####################### WARNING: Here be dragons! #######################
+#
+# This code is written as 'ctr32', based on a 32-bit counter used
+# upstream. The kernel does *not* use a 32-bit counter. The kernel uses
+# a 128-bit counter.
+#
+# This leads to subtle changes from the upstream code: the counter
+# is incremented with vaddu_q_m rather than vaddu_w_m. This occurs in
+# both the bulk (8 blocks at a time) path, and in the individual block
+# path. Be aware of this when doing updates.
+#
+# See:
+# 1d4aa0b4c181 ("crypto: vmx - Fixing AES-CTR counter bug")
+# 009b30ac7444 ("crypto: vmx - CTR: always increment IV as quadword")
+# https://github.com/openssl/openssl/pull/8942
+#
+#########################################################################
+my ($inp,$out,$len,$key,$ivp,$x10,$rounds,$idx)=map("r$_",(3..10));
+my ($rndkey0,$rndkey1,$inout,$tmp)= map("v$_",(0..3));
+my ($ivec,$inptail,$inpperm,$outhead,$outperm,$outmask,$keyperm,$one)=
+ map("v$_",(4..11));
+my $dat=$tmp;
+
+$code.=<<___;
+.globl .${prefix}_ctr32_encrypt_blocks
+ ${UCMP}i $len,1
+ bltlr-
+
+ lis r0,0xfff0
+ mfspr $vrsave,256
+ mtspr 256,r0
+
+ li $idx,15
+ vxor $rndkey0,$rndkey0,$rndkey0
+ le?vspltisb $tmp,0x0f
+
+ lvx $ivec,0,$ivp # load [unaligned] iv
+ lvsl $inpperm,0,$ivp
+ lvx $inptail,$idx,$ivp
+ vspltisb $one,1
+ le?vxor $inpperm,$inpperm,$tmp
+ vperm $ivec,$ivec,$inptail,$inpperm
+ vsldoi $one,$rndkey0,$one,1
+
+ neg r11,$inp
+ ?lvsl $keyperm,0,$key # prepare for unaligned key
+ lwz $rounds,240($key)
+
+ lvsr $inpperm,0,r11 # prepare for unaligned load
+ lvx $inptail,0,$inp
+ addi $inp,$inp,15 # 15 is not typo
+ le?vxor $inpperm,$inpperm,$tmp
+
+ srwi $rounds,$rounds,1
+ li $idx,16
+ subi $rounds,$rounds,1
+
+ ${UCMP}i $len,8
+ bge _aesp8_ctr32_encrypt8x
+
+ ?lvsr $outperm,0,$out # prepare for unaligned store
+ vspltisb $outmask,-1
+ lvx $outhead,0,$out
+ ?vperm $outmask,$rndkey0,$outmask,$outperm
+ le?vxor $outperm,$outperm,$tmp
+
+ lvx $rndkey0,0,$key
+ mtctr $rounds
+ lvx $rndkey1,$idx,$key
+ addi $idx,$idx,16
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+ vxor $inout,$ivec,$rndkey0
+ lvx $rndkey0,$idx,$key
+ addi $idx,$idx,16
+ b Loop_ctr32_enc
+
+.align 5
+Loop_ctr32_enc:
+ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm
+ vcipher $inout,$inout,$rndkey1
+ lvx $rndkey1,$idx,$key
+ addi $idx,$idx,16
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+ vcipher $inout,$inout,$rndkey0
+ lvx $rndkey0,$idx,$key
+ addi $idx,$idx,16
+ bdnz Loop_ctr32_enc
+
+ vadduqm $ivec,$ivec,$one # Kernel change for 128-bit
+ vmr $dat,$inptail
+ lvx $inptail,0,$inp
+ addi $inp,$inp,16
+ subic. $len,$len,1 # blocks--
+
+ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm
+ vcipher $inout,$inout,$rndkey1
+ lvx $rndkey1,$idx,$key
+ vperm $dat,$dat,$inptail,$inpperm
+ li $idx,16
+ ?vperm $rndkey1,$rndkey0,$rndkey1,$keyperm
+ lvx $rndkey0,0,$key
+ vxor $dat,$dat,$rndkey1 # last round key
+ vcipherlast $inout,$inout,$dat
+
+ lvx $rndkey1,$idx,$key
+ addi $idx,$idx,16
+ vperm $inout,$inout,$inout,$outperm
+ vsel $dat,$outhead,$inout,$outmask
+ mtctr $rounds
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+ vmr $outhead,$inout
+ vxor $inout,$ivec,$rndkey0
+ lvx $rndkey0,$idx,$key
+ addi $idx,$idx,16
+ stvx $dat,0,$out
+ addi $out,$out,16
+ bne Loop_ctr32_enc
+
+ addi $out,$out,-1
+ lvx $inout,0,$out # redundant in aligned case
+ vsel $inout,$outhead,$inout,$outmask
+ stvx $inout,0,$out
+
+ mtspr 256,$vrsave
+ blr
+ .long 0
+ .byte 0,12,0x14,0,0,0,6,0
+ .long 0
+___
+#########################################################################
+{{ # Optimized CTR procedure #
+my $key_="r11";
+my ($x00,$x10,$x20,$x30,$x40,$x50,$x60,$x70)=map("r$_",(0,8,26..31));
+my ($in0, $in1, $in2, $in3, $in4, $in5, $in6, $in7 )=map("v$_",(0..3,10,12..14));
+my ($out0,$out1,$out2,$out3,$out4,$out5,$out6,$out7)=map("v$_",(15..22));
+my $rndkey0="v23"; # v24-v25 rotating buffer for first found keys
+ # v26-v31 last 6 round keys
+my ($tmp,$keyperm)=($in3,$in4); # aliases with "caller", redundant assignment
+my ($two,$three,$four)=($outhead,$outperm,$outmask);
+
+$code.=<<___;
+.align 5
+_aesp8_ctr32_encrypt8x:
+ $STU $sp,-`($FRAME+21*16+6*$SIZE_T)`($sp)
+ li r10,`$FRAME+8*16+15`
+ li r11,`$FRAME+8*16+31`
+ stvx v20,r10,$sp # ABI says so
+ addi r10,r10,32
+ stvx v21,r11,$sp
+ addi r11,r11,32
+ stvx v22,r10,$sp
+ addi r10,r10,32
+ stvx v23,r11,$sp
+ addi r11,r11,32
+ stvx v24,r10,$sp
+ addi r10,r10,32
+ stvx v25,r11,$sp
+ addi r11,r11,32
+ stvx v26,r10,$sp
+ addi r10,r10,32
+ stvx v27,r11,$sp
+ addi r11,r11,32
+ stvx v28,r10,$sp
+ addi r10,r10,32
+ stvx v29,r11,$sp
+ addi r11,r11,32
+ stvx v30,r10,$sp
+ stvx v31,r11,$sp
+ li r0,-1
+ stw $vrsave,`$FRAME+21*16-4`($sp) # save vrsave
+ li $x10,0x10
+ $PUSH r26,`$FRAME+21*16+0*$SIZE_T`($sp)
+ li $x20,0x20
+ $PUSH r27,`$FRAME+21*16+1*$SIZE_T`($sp)
+ li $x30,0x30
+ $PUSH r28,`$FRAME+21*16+2*$SIZE_T`($sp)
+ li $x40,0x40
+ $PUSH r29,`$FRAME+21*16+3*$SIZE_T`($sp)
+ li $x50,0x50
+ $PUSH r30,`$FRAME+21*16+4*$SIZE_T`($sp)
+ li $x60,0x60
+ $PUSH r31,`$FRAME+21*16+5*$SIZE_T`($sp)
+ li $x70,0x70
+ mtspr 256,r0
+
+ subi $rounds,$rounds,3 # -4 in total
+
+ lvx $rndkey0,$x00,$key # load key schedule
+ lvx v30,$x10,$key
+ addi $key,$key,0x20
+ lvx v31,$x00,$key
+ ?vperm $rndkey0,$rndkey0,v30,$keyperm
+ addi $key_,$sp,$FRAME+15
+ mtctr $rounds
+
+Load_ctr32_enc_key:
+ ?vperm v24,v30,v31,$keyperm
+ lvx v30,$x10,$key
+ addi $key,$key,0x20
+ stvx v24,$x00,$key_ # off-load round[1]
+ ?vperm v25,v31,v30,$keyperm
+ lvx v31,$x00,$key
+ stvx v25,$x10,$key_ # off-load round[2]
+ addi $key_,$key_,0x20
+ bdnz Load_ctr32_enc_key
+
+ lvx v26,$x10,$key
+ ?vperm v24,v30,v31,$keyperm
+ lvx v27,$x20,$key
+ stvx v24,$x00,$key_ # off-load round[3]
+ ?vperm v25,v31,v26,$keyperm
+ lvx v28,$x30,$key
+ stvx v25,$x10,$key_ # off-load round[4]
+ addi $key_,$sp,$FRAME+15 # rewind $key_
+ ?vperm v26,v26,v27,$keyperm
+ lvx v29,$x40,$key
+ ?vperm v27,v27,v28,$keyperm
+ lvx v30,$x50,$key
+ ?vperm v28,v28,v29,$keyperm
+ lvx v31,$x60,$key
+ ?vperm v29,v29,v30,$keyperm
+ lvx $out0,$x70,$key # borrow $out0
+ ?vperm v30,v30,v31,$keyperm
+ lvx v24,$x00,$key_ # pre-load round[1]
+ ?vperm v31,v31,$out0,$keyperm
+ lvx v25,$x10,$key_ # pre-load round[2]
+
+ vadduqm $two,$one,$one
+ subi $inp,$inp,15 # undo "caller"
+ $SHL $len,$len,4
+
+ vadduqm $out1,$ivec,$one # counter values ...
+ vadduqm $out2,$ivec,$two # (do all ctr adds as 128-bit)
+ vxor $out0,$ivec,$rndkey0 # ... xored with rndkey[0]
+ le?li $idx,8
+ vadduqm $out3,$out1,$two
+ vxor $out1,$out1,$rndkey0
+ le?lvsl $inpperm,0,$idx
+ vadduqm $out4,$out2,$two
+ vxor $out2,$out2,$rndkey0
+ le?vspltisb $tmp,0x0f
+ vadduqm $out5,$out3,$two
+ vxor $out3,$out3,$rndkey0
+ le?vxor $inpperm,$inpperm,$tmp # transform for lvx_u/stvx_u
+ vadduqm $out6,$out4,$two
+ vxor $out4,$out4,$rndkey0
+ vadduqm $out7,$out5,$two
+ vxor $out5,$out5,$rndkey0
+ vadduqm $ivec,$out6,$two # next counter value
+ vxor $out6,$out6,$rndkey0
+ vxor $out7,$out7,$rndkey0
+
+ mtctr $rounds
+ b Loop_ctr32_enc8x
+.align 5
+Loop_ctr32_enc8x:
+ vcipher $out0,$out0,v24
+ vcipher $out1,$out1,v24
+ vcipher $out2,$out2,v24
+ vcipher $out3,$out3,v24
+ vcipher $out4,$out4,v24
+ vcipher $out5,$out5,v24
+ vcipher $out6,$out6,v24
+ vcipher $out7,$out7,v24
+Loop_ctr32_enc8x_middle:
+ lvx v24,$x20,$key_ # round[3]
+ addi $key_,$key_,0x20
+
+ vcipher $out0,$out0,v25
+ vcipher $out1,$out1,v25
+ vcipher $out2,$out2,v25
+ vcipher $out3,$out3,v25
+ vcipher $out4,$out4,v25
+ vcipher $out5,$out5,v25
+ vcipher $out6,$out6,v25
+ vcipher $out7,$out7,v25
+ lvx v25,$x10,$key_ # round[4]
+ bdnz Loop_ctr32_enc8x
+
+ subic r11,$len,256 # $len-256, borrow $key_
+ vcipher $out0,$out0,v24
+ vcipher $out1,$out1,v24
+ vcipher $out2,$out2,v24
+ vcipher $out3,$out3,v24
+ vcipher $out4,$out4,v24
+ vcipher $out5,$out5,v24
+ vcipher $out6,$out6,v24
+ vcipher $out7,$out7,v24
+
+ subfe r0,r0,r0 # borrow?-1:0
+ vcipher $out0,$out0,v25
+ vcipher $out1,$out1,v25
+ vcipher $out2,$out2,v25
+ vcipher $out3,$out3,v25
+ vcipher $out4,$out4,v25
+ vcipher $out5,$out5,v25
+ vcipher $out6,$out6,v25
+ vcipher $out7,$out7,v25
+
+ and r0,r0,r11
+ addi $key_,$sp,$FRAME+15 # rewind $key_
+ vcipher $out0,$out0,v26
+ vcipher $out1,$out1,v26
+ vcipher $out2,$out2,v26
+ vcipher $out3,$out3,v26
+ vcipher $out4,$out4,v26
+ vcipher $out5,$out5,v26
+ vcipher $out6,$out6,v26
+ vcipher $out7,$out7,v26
+ lvx v24,$x00,$key_ # re-pre-load round[1]
+
+ subic $len,$len,129 # $len-=129
+ vcipher $out0,$out0,v27
+ addi $len,$len,1 # $len-=128 really
+ vcipher $out1,$out1,v27
+ vcipher $out2,$out2,v27
+ vcipher $out3,$out3,v27
+ vcipher $out4,$out4,v27
+ vcipher $out5,$out5,v27
+ vcipher $out6,$out6,v27
+ vcipher $out7,$out7,v27
+ lvx v25,$x10,$key_ # re-pre-load round[2]
+
+ vcipher $out0,$out0,v28
+ lvx_u $in0,$x00,$inp # load input
+ vcipher $out1,$out1,v28
+ lvx_u $in1,$x10,$inp
+ vcipher $out2,$out2,v28
+ lvx_u $in2,$x20,$inp
+ vcipher $out3,$out3,v28
+ lvx_u $in3,$x30,$inp
+ vcipher $out4,$out4,v28
+ lvx_u $in4,$x40,$inp
+ vcipher $out5,$out5,v28
+ lvx_u $in5,$x50,$inp
+ vcipher $out6,$out6,v28
+ lvx_u $in6,$x60,$inp
+ vcipher $out7,$out7,v28
+ lvx_u $in7,$x70,$inp
+ addi $inp,$inp,0x80
+
+ vcipher $out0,$out0,v29
+ le?vperm $in0,$in0,$in0,$inpperm
+ vcipher $out1,$out1,v29
+ le?vperm $in1,$in1,$in1,$inpperm
+ vcipher $out2,$out2,v29
+ le?vperm $in2,$in2,$in2,$inpperm
+ vcipher $out3,$out3,v29
+ le?vperm $in3,$in3,$in3,$inpperm
+ vcipher $out4,$out4,v29
+ le?vperm $in4,$in4,$in4,$inpperm
+ vcipher $out5,$out5,v29
+ le?vperm $in5,$in5,$in5,$inpperm
+ vcipher $out6,$out6,v29
+ le?vperm $in6,$in6,$in6,$inpperm
+ vcipher $out7,$out7,v29
+ le?vperm $in7,$in7,$in7,$inpperm
+
+ add $inp,$inp,r0 # $inp is adjusted in such
+ # way that at exit from the
+ # loop inX-in7 are loaded
+ # with last "words"
+ subfe. r0,r0,r0 # borrow?-1:0
+ vcipher $out0,$out0,v30
+ vxor $in0,$in0,v31 # xor with last round key
+ vcipher $out1,$out1,v30
+ vxor $in1,$in1,v31
+ vcipher $out2,$out2,v30
+ vxor $in2,$in2,v31
+ vcipher $out3,$out3,v30
+ vxor $in3,$in3,v31
+ vcipher $out4,$out4,v30
+ vxor $in4,$in4,v31
+ vcipher $out5,$out5,v30
+ vxor $in5,$in5,v31
+ vcipher $out6,$out6,v30
+ vxor $in6,$in6,v31
+ vcipher $out7,$out7,v30
+ vxor $in7,$in7,v31
+
+ bne Lctr32_enc8x_break # did $len-129 borrow?
+
+ vcipherlast $in0,$out0,$in0
+ vcipherlast $in1,$out1,$in1
+ vadduqm $out1,$ivec,$one # counter values ...
+ vcipherlast $in2,$out2,$in2
+ vadduqm $out2,$ivec,$two
+ vxor $out0,$ivec,$rndkey0 # ... xored with rndkey[0]
+ vcipherlast $in3,$out3,$in3
+ vadduqm $out3,$out1,$two
+ vxor $out1,$out1,$rndkey0
+ vcipherlast $in4,$out4,$in4
+ vadduqm $out4,$out2,$two
+ vxor $out2,$out2,$rndkey0
+ vcipherlast $in5,$out5,$in5
+ vadduqm $out5,$out3,$two
+ vxor $out3,$out3,$rndkey0
+ vcipherlast $in6,$out6,$in6
+ vadduqm $out6,$out4,$two
+ vxor $out4,$out4,$rndkey0
+ vcipherlast $in7,$out7,$in7
+ vadduqm $out7,$out5,$two
+ vxor $out5,$out5,$rndkey0
+ le?vperm $in0,$in0,$in0,$inpperm
+ vadduqm $ivec,$out6,$two # next counter value
+ vxor $out6,$out6,$rndkey0
+ le?vperm $in1,$in1,$in1,$inpperm
+ vxor $out7,$out7,$rndkey0
+ mtctr $rounds
+
+ vcipher $out0,$out0,v24
+ stvx_u $in0,$x00,$out
+ le?vperm $in2,$in2,$in2,$inpperm
+ vcipher $out1,$out1,v24
+ stvx_u $in1,$x10,$out
+ le?vperm $in3,$in3,$in3,$inpperm
+ vcipher $out2,$out2,v24
+ stvx_u $in2,$x20,$out
+ le?vperm $in4,$in4,$in4,$inpperm
+ vcipher $out3,$out3,v24
+ stvx_u $in3,$x30,$out
+ le?vperm $in5,$in5,$in5,$inpperm
+ vcipher $out4,$out4,v24
+ stvx_u $in4,$x40,$out
+ le?vperm $in6,$in6,$in6,$inpperm
+ vcipher $out5,$out5,v24
+ stvx_u $in5,$x50,$out
+ le?vperm $in7,$in7,$in7,$inpperm
+ vcipher $out6,$out6,v24
+ stvx_u $in6,$x60,$out
+ vcipher $out7,$out7,v24
+ stvx_u $in7,$x70,$out
+ addi $out,$out,0x80
+
+ b Loop_ctr32_enc8x_middle
+
+.align 5
+Lctr32_enc8x_break:
+ cmpwi $len,-0x60
+ blt Lctr32_enc8x_one
+ nop
+ beq Lctr32_enc8x_two
+ cmpwi $len,-0x40
+ blt Lctr32_enc8x_three
+ nop
+ beq Lctr32_enc8x_four
+ cmpwi $len,-0x20
+ blt Lctr32_enc8x_five
+ nop
+ beq Lctr32_enc8x_six
+ cmpwi $len,0x00
+ blt Lctr32_enc8x_seven
+
+Lctr32_enc8x_eight:
+ vcipherlast $out0,$out0,$in0
+ vcipherlast $out1,$out1,$in1
+ vcipherlast $out2,$out2,$in2
+ vcipherlast $out3,$out3,$in3
+ vcipherlast $out4,$out4,$in4
+ vcipherlast $out5,$out5,$in5
+ vcipherlast $out6,$out6,$in6
+ vcipherlast $out7,$out7,$in7
+
+ le?vperm $out0,$out0,$out0,$inpperm
+ le?vperm $out1,$out1,$out1,$inpperm
+ stvx_u $out0,$x00,$out
+ le?vperm $out2,$out2,$out2,$inpperm
+ stvx_u $out1,$x10,$out
+ le?vperm $out3,$out3,$out3,$inpperm
+ stvx_u $out2,$x20,$out
+ le?vperm $out4,$out4,$out4,$inpperm
+ stvx_u $out3,$x30,$out
+ le?vperm $out5,$out5,$out5,$inpperm
+ stvx_u $out4,$x40,$out
+ le?vperm $out6,$out6,$out6,$inpperm
+ stvx_u $out5,$x50,$out
+ le?vperm $out7,$out7,$out7,$inpperm
+ stvx_u $out6,$x60,$out
+ stvx_u $out7,$x70,$out
+ addi $out,$out,0x80
+ b Lctr32_enc8x_done
+
+.align 5
+Lctr32_enc8x_seven:
+ vcipherlast $out0,$out0,$in1
+ vcipherlast $out1,$out1,$in2
+ vcipherlast $out2,$out2,$in3
+ vcipherlast $out3,$out3,$in4
+ vcipherlast $out4,$out4,$in5
+ vcipherlast $out5,$out5,$in6
+ vcipherlast $out6,$out6,$in7
+
+ le?vperm $out0,$out0,$out0,$inpperm
+ le?vperm $out1,$out1,$out1,$inpperm
+ stvx_u $out0,$x00,$out
+ le?vperm $out2,$out2,$out2,$inpperm
+ stvx_u $out1,$x10,$out
+ le?vperm $out3,$out3,$out3,$inpperm
+ stvx_u $out2,$x20,$out
+ le?vperm $out4,$out4,$out4,$inpperm
+ stvx_u $out3,$x30,$out
+ le?vperm $out5,$out5,$out5,$inpperm
+ stvx_u $out4,$x40,$out
+ le?vperm $out6,$out6,$out6,$inpperm
+ stvx_u $out5,$x50,$out
+ stvx_u $out6,$x60,$out
+ addi $out,$out,0x70
+ b Lctr32_enc8x_done
+
+.align 5
+Lctr32_enc8x_six:
+ vcipherlast $out0,$out0,$in2
+ vcipherlast $out1,$out1,$in3
+ vcipherlast $out2,$out2,$in4
+ vcipherlast $out3,$out3,$in5
+ vcipherlast $out4,$out4,$in6
+ vcipherlast $out5,$out5,$in7
+
+ le?vperm $out0,$out0,$out0,$inpperm
+ le?vperm $out1,$out1,$out1,$inpperm
+ stvx_u $out0,$x00,$out
+ le?vperm $out2,$out2,$out2,$inpperm
+ stvx_u $out1,$x10,$out
+ le?vperm $out3,$out3,$out3,$inpperm
+ stvx_u $out2,$x20,$out
+ le?vperm $out4,$out4,$out4,$inpperm
+ stvx_u $out3,$x30,$out
+ le?vperm $out5,$out5,$out5,$inpperm
+ stvx_u $out4,$x40,$out
+ stvx_u $out5,$x50,$out
+ addi $out,$out,0x60
+ b Lctr32_enc8x_done
+
+.align 5
+Lctr32_enc8x_five:
+ vcipherlast $out0,$out0,$in3
+ vcipherlast $out1,$out1,$in4
+ vcipherlast $out2,$out2,$in5
+ vcipherlast $out3,$out3,$in6
+ vcipherlast $out4,$out4,$in7
+
+ le?vperm $out0,$out0,$out0,$inpperm
+ le?vperm $out1,$out1,$out1,$inpperm
+ stvx_u $out0,$x00,$out
+ le?vperm $out2,$out2,$out2,$inpperm
+ stvx_u $out1,$x10,$out
+ le?vperm $out3,$out3,$out3,$inpperm
+ stvx_u $out2,$x20,$out
+ le?vperm $out4,$out4,$out4,$inpperm
+ stvx_u $out3,$x30,$out
+ stvx_u $out4,$x40,$out
+ addi $out,$out,0x50
+ b Lctr32_enc8x_done
+
+.align 5
+Lctr32_enc8x_four:
+ vcipherlast $out0,$out0,$in4
+ vcipherlast $out1,$out1,$in5
+ vcipherlast $out2,$out2,$in6
+ vcipherlast $out3,$out3,$in7
+
+ le?vperm $out0,$out0,$out0,$inpperm
+ le?vperm $out1,$out1,$out1,$inpperm
+ stvx_u $out0,$x00,$out
+ le?vperm $out2,$out2,$out2,$inpperm
+ stvx_u $out1,$x10,$out
+ le?vperm $out3,$out3,$out3,$inpperm
+ stvx_u $out2,$x20,$out
+ stvx_u $out3,$x30,$out
+ addi $out,$out,0x40
+ b Lctr32_enc8x_done
+
+.align 5
+Lctr32_enc8x_three:
+ vcipherlast $out0,$out0,$in5
+ vcipherlast $out1,$out1,$in6
+ vcipherlast $out2,$out2,$in7
+
+ le?vperm $out0,$out0,$out0,$inpperm
+ le?vperm $out1,$out1,$out1,$inpperm
+ stvx_u $out0,$x00,$out
+ le?vperm $out2,$out2,$out2,$inpperm
+ stvx_u $out1,$x10,$out
+ stvx_u $out2,$x20,$out
+ addi $out,$out,0x30
+ b Lctr32_enc8x_done
+
+.align 5
+Lctr32_enc8x_two:
+ vcipherlast $out0,$out0,$in6
+ vcipherlast $out1,$out1,$in7
+
+ le?vperm $out0,$out0,$out0,$inpperm
+ le?vperm $out1,$out1,$out1,$inpperm
+ stvx_u $out0,$x00,$out
+ stvx_u $out1,$x10,$out
+ addi $out,$out,0x20
+ b Lctr32_enc8x_done
+
+.align 5
+Lctr32_enc8x_one:
+ vcipherlast $out0,$out0,$in7
+
+ le?vperm $out0,$out0,$out0,$inpperm
+ stvx_u $out0,0,$out
+ addi $out,$out,0x10
+
+Lctr32_enc8x_done:
+ li r10,`$FRAME+15`
+ li r11,`$FRAME+31`
+ stvx $inpperm,r10,$sp # wipe copies of round keys
+ addi r10,r10,32
+ stvx $inpperm,r11,$sp
+ addi r11,r11,32
+ stvx $inpperm,r10,$sp
+ addi r10,r10,32
+ stvx $inpperm,r11,$sp
+ addi r11,r11,32
+ stvx $inpperm,r10,$sp
+ addi r10,r10,32
+ stvx $inpperm,r11,$sp
+ addi r11,r11,32
+ stvx $inpperm,r10,$sp
+ addi r10,r10,32
+ stvx $inpperm,r11,$sp
+ addi r11,r11,32
+
+ mtspr 256,$vrsave
+ lvx v20,r10,$sp # ABI says so
+ addi r10,r10,32
+ lvx v21,r11,$sp
+ addi r11,r11,32
+ lvx v22,r10,$sp
+ addi r10,r10,32
+ lvx v23,r11,$sp
+ addi r11,r11,32
+ lvx v24,r10,$sp
+ addi r10,r10,32
+ lvx v25,r11,$sp
+ addi r11,r11,32
+ lvx v26,r10,$sp
+ addi r10,r10,32
+ lvx v27,r11,$sp
+ addi r11,r11,32
+ lvx v28,r10,$sp
+ addi r10,r10,32
+ lvx v29,r11,$sp
+ addi r11,r11,32
+ lvx v30,r10,$sp
+ lvx v31,r11,$sp
+ $POP r26,`$FRAME+21*16+0*$SIZE_T`($sp)
+ $POP r27,`$FRAME+21*16+1*$SIZE_T`($sp)
+ $POP r28,`$FRAME+21*16+2*$SIZE_T`($sp)
+ $POP r29,`$FRAME+21*16+3*$SIZE_T`($sp)
+ $POP r30,`$FRAME+21*16+4*$SIZE_T`($sp)
+ $POP r31,`$FRAME+21*16+5*$SIZE_T`($sp)
+ addi $sp,$sp,`$FRAME+21*16+6*$SIZE_T`
+ blr
+ .long 0
+ .byte 0,12,0x14,0,0x80,6,6,0
+ .long 0
+.size .${prefix}_ctr32_encrypt_blocks,.-.${prefix}_ctr32_encrypt_blocks
+___
+}} }}}
+
+#########################################################################
+{{{ # XTS procedures #
+# int aes_p8_xts_[en|de]crypt(const char *inp, char *out, size_t len, #
+# const AES_KEY *key1, const AES_KEY *key2, #
+# [const] unsigned char iv[16]); #
+# If $key2 is NULL, then a "tweak chaining" mode is engaged, in which #
+# input tweak value is assumed to be encrypted already, and last tweak #
+# value, one suitable for consecutive call on same chunk of data, is #
+# written back to original buffer. In addition, in "tweak chaining" #
+# mode only complete input blocks are processed. #
+
+my ($inp,$out,$len,$key1,$key2,$ivp,$rounds,$idx) = map("r$_",(3..10));
+my ($rndkey0,$rndkey1,$inout) = map("v$_",(0..2));
+my ($output,$inptail,$inpperm,$leperm,$keyperm) = map("v$_",(3..7));
+my ($tweak,$seven,$eighty7,$tmp,$tweak1) = map("v$_",(8..12));
+my $taillen = $key2;
+
+ ($inp,$idx) = ($idx,$inp); # reassign
+
+$code.=<<___;
+.globl .${prefix}_xts_encrypt
+ mr $inp,r3 # reassign
+ li r3,-1
+ ${UCMP}i $len,16
+ bltlr-
+
+ lis r0,0xfff0
+ mfspr r12,256 # save vrsave
+ li r11,0
+ mtspr 256,r0
+
+ vspltisb $seven,0x07 # 0x070707..07
+ le?lvsl $leperm,r11,r11
+ le?vspltisb $tmp,0x0f
+ le?vxor $leperm,$leperm,$seven
+
+ li $idx,15
+ lvx $tweak,0,$ivp # load [unaligned] iv
+ lvsl $inpperm,0,$ivp
+ lvx $inptail,$idx,$ivp
+ le?vxor $inpperm,$inpperm,$tmp
+ vperm $tweak,$tweak,$inptail,$inpperm
+
+ neg r11,$inp
+ lvsr $inpperm,0,r11 # prepare for unaligned load
+ lvx $inout,0,$inp
+ addi $inp,$inp,15 # 15 is not typo
+ le?vxor $inpperm,$inpperm,$tmp
+
+ ${UCMP}i $key2,0 # key2==NULL?
+ beq Lxts_enc_no_key2
+
+ ?lvsl $keyperm,0,$key2 # prepare for unaligned key
+ lwz $rounds,240($key2)
+ srwi $rounds,$rounds,1
+ subi $rounds,$rounds,1
+ li $idx,16
+
+ lvx $rndkey0,0,$key2
+ lvx $rndkey1,$idx,$key2
+ addi $idx,$idx,16
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+ vxor $tweak,$tweak,$rndkey0
+ lvx $rndkey0,$idx,$key2
+ addi $idx,$idx,16
+ mtctr $rounds
+
+Ltweak_xts_enc:
+ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm
+ vcipher $tweak,$tweak,$rndkey1
+ lvx $rndkey1,$idx,$key2
+ addi $idx,$idx,16
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+ vcipher $tweak,$tweak,$rndkey0
+ lvx $rndkey0,$idx,$key2
+ addi $idx,$idx,16
+ bdnz Ltweak_xts_enc
+
+ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm
+ vcipher $tweak,$tweak,$rndkey1
+ lvx $rndkey1,$idx,$key2
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+ vcipherlast $tweak,$tweak,$rndkey0
+
+ li $ivp,0 # don't chain the tweak
+ b Lxts_enc
+
+Lxts_enc_no_key2:
+ li $idx,-16
+ and $len,$len,$idx # in "tweak chaining"
+ # mode only complete
+ # blocks are processed
+Lxts_enc:
+ lvx $inptail,0,$inp
+ addi $inp,$inp,16
+
+ ?lvsl $keyperm,0,$key1 # prepare for unaligned key
+ lwz $rounds,240($key1)
+ srwi $rounds,$rounds,1
+ subi $rounds,$rounds,1
+ li $idx,16
+
+ vslb $eighty7,$seven,$seven # 0x808080..80
+ vor $eighty7,$eighty7,$seven # 0x878787..87
+ vspltisb $tmp,1 # 0x010101..01
+ vsldoi $eighty7,$eighty7,$tmp,15 # 0x870101..01
+
+ ${UCMP}i $len,96
+ bge _aesp8_xts_encrypt6x
+
+ andi. $taillen,$len,15
+ subic r0,$len,32
+ subi $taillen,$taillen,16
+ subfe r0,r0,r0
+ and r0,r0,$taillen
+ add $inp,$inp,r0
+
+ lvx $rndkey0,0,$key1
+ lvx $rndkey1,$idx,$key1
+ addi $idx,$idx,16
+ vperm $inout,$inout,$inptail,$inpperm
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+ vxor $inout,$inout,$tweak
+ vxor $inout,$inout,$rndkey0
+ lvx $rndkey0,$idx,$key1
+ addi $idx,$idx,16
+ mtctr $rounds
+ b Loop_xts_enc
+
+.align 5
+Loop_xts_enc:
+ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm
+ vcipher $inout,$inout,$rndkey1
+ lvx $rndkey1,$idx,$key1
+ addi $idx,$idx,16
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+ vcipher $inout,$inout,$rndkey0
+ lvx $rndkey0,$idx,$key1
+ addi $idx,$idx,16
+ bdnz Loop_xts_enc
+
+ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm
+ vcipher $inout,$inout,$rndkey1
+ lvx $rndkey1,$idx,$key1
+ li $idx,16
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+ vxor $rndkey0,$rndkey0,$tweak
+ vcipherlast $output,$inout,$rndkey0
+
+ le?vperm $tmp,$output,$output,$leperm
+ be?nop
+ le?stvx_u $tmp,0,$out
+ be?stvx_u $output,0,$out
+ addi $out,$out,16
+
+ subic. $len,$len,16
+ beq Lxts_enc_done
+
+ vmr $inout,$inptail
+ lvx $inptail,0,$inp
+ addi $inp,$inp,16
+ lvx $rndkey0,0,$key1
+ lvx $rndkey1,$idx,$key1
+ addi $idx,$idx,16
+
+ subic r0,$len,32
+ subfe r0,r0,r0
+ and r0,r0,$taillen
+ add $inp,$inp,r0
+
+ vsrab $tmp,$tweak,$seven # next tweak value
+ vaddubm $tweak,$tweak,$tweak
+ vsldoi $tmp,$tmp,$tmp,15
+ vand $tmp,$tmp,$eighty7
+ vxor $tweak,$tweak,$tmp
+
+ vperm $inout,$inout,$inptail,$inpperm
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+ vxor $inout,$inout,$tweak
+ vxor $output,$output,$rndkey0 # just in case $len<16
+ vxor $inout,$inout,$rndkey0
+ lvx $rndkey0,$idx,$key1
+ addi $idx,$idx,16
+
+ mtctr $rounds
+ ${UCMP}i $len,16
+ bge Loop_xts_enc
+
+ vxor $output,$output,$tweak
+ lvsr $inpperm,0,$len # $inpperm is no longer needed
+ vxor $inptail,$inptail,$inptail # $inptail is no longer needed
+ vspltisb $tmp,-1
+ vperm $inptail,$inptail,$tmp,$inpperm
+ vsel $inout,$inout,$output,$inptail
+
+ subi r11,$out,17
+ subi $out,$out,16
+ mtctr $len
+ li $len,16
+Loop_xts_enc_steal:
+ lbzu r0,1(r11)
+ stb r0,16(r11)
+ bdnz Loop_xts_enc_steal
+
+ mtctr $rounds
+ b Loop_xts_enc # one more time...
+
+Lxts_enc_done:
+ ${UCMP}i $ivp,0
+ beq Lxts_enc_ret
+
+ vsrab $tmp,$tweak,$seven # next tweak value
+ vaddubm $tweak,$tweak,$tweak
+ vsldoi $tmp,$tmp,$tmp,15
+ vand $tmp,$tmp,$eighty7
+ vxor $tweak,$tweak,$tmp
+
+ le?vperm $tweak,$tweak,$tweak,$leperm
+ stvx_u $tweak,0,$ivp
+
+Lxts_enc_ret:
+ mtspr 256,r12 # restore vrsave
+ li r3,0
+ blr
+ .long 0
+ .byte 0,12,0x04,0,0x80,6,6,0
+ .long 0
+.size .${prefix}_xts_encrypt,.-.${prefix}_xts_encrypt
+
+.globl .${prefix}_xts_decrypt
+ mr $inp,r3 # reassign
+ li r3,-1
+ ${UCMP}i $len,16
+ bltlr-
+
+ lis r0,0xfff8
+ mfspr r12,256 # save vrsave
+ li r11,0
+ mtspr 256,r0
+
+ andi. r0,$len,15
+ neg r0,r0
+ andi. r0,r0,16
+ sub $len,$len,r0
+
+ vspltisb $seven,0x07 # 0x070707..07
+ le?lvsl $leperm,r11,r11
+ le?vspltisb $tmp,0x0f
+ le?vxor $leperm,$leperm,$seven
+
+ li $idx,15
+ lvx $tweak,0,$ivp # load [unaligned] iv
+ lvsl $inpperm,0,$ivp
+ lvx $inptail,$idx,$ivp
+ le?vxor $inpperm,$inpperm,$tmp
+ vperm $tweak,$tweak,$inptail,$inpperm
+
+ neg r11,$inp
+ lvsr $inpperm,0,r11 # prepare for unaligned load
+ lvx $inout,0,$inp
+ addi $inp,$inp,15 # 15 is not typo
+ le?vxor $inpperm,$inpperm,$tmp
+
+ ${UCMP}i $key2,0 # key2==NULL?
+ beq Lxts_dec_no_key2
+
+ ?lvsl $keyperm,0,$key2 # prepare for unaligned key
+ lwz $rounds,240($key2)
+ srwi $rounds,$rounds,1
+ subi $rounds,$rounds,1
+ li $idx,16
+
+ lvx $rndkey0,0,$key2
+ lvx $rndkey1,$idx,$key2
+ addi $idx,$idx,16
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+ vxor $tweak,$tweak,$rndkey0
+ lvx $rndkey0,$idx,$key2
+ addi $idx,$idx,16
+ mtctr $rounds
+
+Ltweak_xts_dec:
+ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm
+ vcipher $tweak,$tweak,$rndkey1
+ lvx $rndkey1,$idx,$key2
+ addi $idx,$idx,16
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+ vcipher $tweak,$tweak,$rndkey0
+ lvx $rndkey0,$idx,$key2
+ addi $idx,$idx,16
+ bdnz Ltweak_xts_dec
+
+ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm
+ vcipher $tweak,$tweak,$rndkey1
+ lvx $rndkey1,$idx,$key2
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+ vcipherlast $tweak,$tweak,$rndkey0
+
+ li $ivp,0 # don't chain the tweak
+ b Lxts_dec
+
+Lxts_dec_no_key2:
+ neg $idx,$len
+ andi. $idx,$idx,15
+ add $len,$len,$idx # in "tweak chaining"
+ # mode only complete
+ # blocks are processed
+Lxts_dec:
+ lvx $inptail,0,$inp
+ addi $inp,$inp,16
+
+ ?lvsl $keyperm,0,$key1 # prepare for unaligned key
+ lwz $rounds,240($key1)
+ srwi $rounds,$rounds,1
+ subi $rounds,$rounds,1
+ li $idx,16
+
+ vslb $eighty7,$seven,$seven # 0x808080..80
+ vor $eighty7,$eighty7,$seven # 0x878787..87
+ vspltisb $tmp,1 # 0x010101..01
+ vsldoi $eighty7,$eighty7,$tmp,15 # 0x870101..01
+
+ ${UCMP}i $len,96
+ bge _aesp8_xts_decrypt6x
+
+ lvx $rndkey0,0,$key1
+ lvx $rndkey1,$idx,$key1
+ addi $idx,$idx,16
+ vperm $inout,$inout,$inptail,$inpperm
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+ vxor $inout,$inout,$tweak
+ vxor $inout,$inout,$rndkey0
+ lvx $rndkey0,$idx,$key1
+ addi $idx,$idx,16
+ mtctr $rounds
+
+ ${UCMP}i $len,16
+ blt Ltail_xts_dec
+ be?b Loop_xts_dec
+
+.align 5
+Loop_xts_dec:
+ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm
+ vncipher $inout,$inout,$rndkey1
+ lvx $rndkey1,$idx,$key1
+ addi $idx,$idx,16
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+ vncipher $inout,$inout,$rndkey0
+ lvx $rndkey0,$idx,$key1
+ addi $idx,$idx,16
+ bdnz Loop_xts_dec
+
+ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm
+ vncipher $inout,$inout,$rndkey1
+ lvx $rndkey1,$idx,$key1
+ li $idx,16
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+ vxor $rndkey0,$rndkey0,$tweak
+ vncipherlast $output,$inout,$rndkey0
+
+ le?vperm $tmp,$output,$output,$leperm
+ be?nop
+ le?stvx_u $tmp,0,$out
+ be?stvx_u $output,0,$out
+ addi $out,$out,16
+
+ subic. $len,$len,16
+ beq Lxts_dec_done
+
+ vmr $inout,$inptail
+ lvx $inptail,0,$inp
+ addi $inp,$inp,16
+ lvx $rndkey0,0,$key1
+ lvx $rndkey1,$idx,$key1
+ addi $idx,$idx,16
+
+ vsrab $tmp,$tweak,$seven # next tweak value
+ vaddubm $tweak,$tweak,$tweak
+ vsldoi $tmp,$tmp,$tmp,15
+ vand $tmp,$tmp,$eighty7
+ vxor $tweak,$tweak,$tmp
+
+ vperm $inout,$inout,$inptail,$inpperm
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+ vxor $inout,$inout,$tweak
+ vxor $inout,$inout,$rndkey0
+ lvx $rndkey0,$idx,$key1
+ addi $idx,$idx,16
+
+ mtctr $rounds
+ ${UCMP}i $len,16
+ bge Loop_xts_dec
+
+Ltail_xts_dec:
+ vsrab $tmp,$tweak,$seven # next tweak value
+ vaddubm $tweak1,$tweak,$tweak
+ vsldoi $tmp,$tmp,$tmp,15
+ vand $tmp,$tmp,$eighty7
+ vxor $tweak1,$tweak1,$tmp
+
+ subi $inp,$inp,16
+ add $inp,$inp,$len
+
+ vxor $inout,$inout,$tweak # :-(
+ vxor $inout,$inout,$tweak1 # :-)
+
+Loop_xts_dec_short:
+ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm
+ vncipher $inout,$inout,$rndkey1
+ lvx $rndkey1,$idx,$key1
+ addi $idx,$idx,16
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+ vncipher $inout,$inout,$rndkey0
+ lvx $rndkey0,$idx,$key1
+ addi $idx,$idx,16
+ bdnz Loop_xts_dec_short
+
+ ?vperm $rndkey1,$rndkey1,$rndkey0,$keyperm
+ vncipher $inout,$inout,$rndkey1
+ lvx $rndkey1,$idx,$key1
+ li $idx,16
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+ vxor $rndkey0,$rndkey0,$tweak1
+ vncipherlast $output,$inout,$rndkey0
+
+ le?vperm $tmp,$output,$output,$leperm
+ be?nop
+ le?stvx_u $tmp,0,$out
+ be?stvx_u $output,0,$out
+
+ vmr $inout,$inptail
+ lvx $inptail,0,$inp
+ #addi $inp,$inp,16
+ lvx $rndkey0,0,$key1
+ lvx $rndkey1,$idx,$key1
+ addi $idx,$idx,16
+ vperm $inout,$inout,$inptail,$inpperm
+ ?vperm $rndkey0,$rndkey0,$rndkey1,$keyperm
+
+ lvsr $inpperm,0,$len # $inpperm is no longer needed
+ vxor $inptail,$inptail,$inptail # $inptail is no longer needed
+ vspltisb $tmp,-1
+ vperm $inptail,$inptail,$tmp,$inpperm
+ vsel $inout,$inout,$output,$inptail
+
+ vxor $rndkey0,$rndkey0,$tweak
+ vxor $inout,$inout,$rndkey0
+ lvx $rndkey0,$idx,$key1
+ addi $idx,$idx,16
+
+ subi r11,$out,1
+ mtctr $len
+ li $len,16
+Loop_xts_dec_steal:
+ lbzu r0,1(r11)
+ stb r0,16(r11)
+ bdnz Loop_xts_dec_steal
+
+ mtctr $rounds
+ b Loop_xts_dec # one more time...
+
+Lxts_dec_done:
+ ${UCMP}i $ivp,0
+ beq Lxts_dec_ret
+
+ vsrab $tmp,$tweak,$seven # next tweak value
+ vaddubm $tweak,$tweak,$tweak
+ vsldoi $tmp,$tmp,$tmp,15
+ vand $tmp,$tmp,$eighty7
+ vxor $tweak,$tweak,$tmp
+
+ le?vperm $tweak,$tweak,$tweak,$leperm
+ stvx_u $tweak,0,$ivp
+
+Lxts_dec_ret:
+ mtspr 256,r12 # restore vrsave
+ li r3,0
+ blr
+ .long 0
+ .byte 0,12,0x04,0,0x80,6,6,0
+ .long 0
+.size .${prefix}_xts_decrypt,.-.${prefix}_xts_decrypt
+___
+#########################################################################
+{{ # Optimized XTS procedures #
+my $key_=$key2;
+my ($x00,$x10,$x20,$x30,$x40,$x50,$x60,$x70)=map("r$_",(0,3,26..31));
+ $x00=0 if ($flavour =~ /osx/);
+my ($in0, $in1, $in2, $in3, $in4, $in5 )=map("v$_",(0..5));
+my ($out0, $out1, $out2, $out3, $out4, $out5)=map("v$_",(7,12..16));
+my ($twk0, $twk1, $twk2, $twk3, $twk4, $twk5)=map("v$_",(17..22));
+my $rndkey0="v23"; # v24-v25 rotating buffer for first found keys
+ # v26-v31 last 6 round keys
+my ($keyperm)=($out0); # aliases with "caller", redundant assignment
+my $taillen=$x70;
+
+$code.=<<___;
+.align 5
+_aesp8_xts_encrypt6x:
+ $STU $sp,-`($FRAME+21*16+6*$SIZE_T)`($sp)
+ mflr r11
+ li r7,`$FRAME+8*16+15`
+ li r3,`$FRAME+8*16+31`
+ $PUSH r11,`$FRAME+21*16+6*$SIZE_T+$LRSAVE`($sp)
+ stvx v20,r7,$sp # ABI says so
+ addi r7,r7,32
+ stvx v21,r3,$sp
+ addi r3,r3,32
+ stvx v22,r7,$sp
+ addi r7,r7,32
+ stvx v23,r3,$sp
+ addi r3,r3,32
+ stvx v24,r7,$sp
+ addi r7,r7,32
+ stvx v25,r3,$sp
+ addi r3,r3,32
+ stvx v26,r7,$sp
+ addi r7,r7,32
+ stvx v27,r3,$sp
+ addi r3,r3,32
+ stvx v28,r7,$sp
+ addi r7,r7,32
+ stvx v29,r3,$sp
+ addi r3,r3,32
+ stvx v30,r7,$sp
+ stvx v31,r3,$sp
+ li r0,-1
+ stw $vrsave,`$FRAME+21*16-4`($sp) # save vrsave
+ li $x10,0x10
+ $PUSH r26,`$FRAME+21*16+0*$SIZE_T`($sp)
+ li $x20,0x20
+ $PUSH r27,`$FRAME+21*16+1*$SIZE_T`($sp)
+ li $x30,0x30
+ $PUSH r28,`$FRAME+21*16+2*$SIZE_T`($sp)
+ li $x40,0x40
+ $PUSH r29,`$FRAME+21*16+3*$SIZE_T`($sp)
+ li $x50,0x50
+ $PUSH r30,`$FRAME+21*16+4*$SIZE_T`($sp)
+ li $x60,0x60
+ $PUSH r31,`$FRAME+21*16+5*$SIZE_T`($sp)
+ li $x70,0x70
+ mtspr 256,r0
+
+ xxlor 2, 32+$eighty7, 32+$eighty7
+ vsldoi $eighty7,$tmp,$eighty7,1 # 0x010101..87
+ xxlor 1, 32+$eighty7, 32+$eighty7
+
+ # Load XOR Lconsts.
+ mr $x70, r6
+ bl Lconsts
+ lxvw4x 0, $x40, r6 # load XOR contents
+ mr r6, $x70
+ li $x70,0x70
+
+ subi $rounds,$rounds,3 # -4 in total
+
+ lvx $rndkey0,$x00,$key1 # load key schedule
+ lvx v30,$x10,$key1
+ addi $key1,$key1,0x20
+ lvx v31,$x00,$key1
+ ?vperm $rndkey0,$rndkey0,v30,$keyperm
+ addi $key_,$sp,$FRAME+15
+ mtctr $rounds
+
+Load_xts_enc_key:
+ ?vperm v24,v30,v31,$keyperm
+ lvx v30,$x10,$key1
+ addi $key1,$key1,0x20
+ stvx v24,$x00,$key_ # off-load round[1]
+ ?vperm v25,v31,v30,$keyperm
+ lvx v31,$x00,$key1
+ stvx v25,$x10,$key_ # off-load round[2]
+ addi $key_,$key_,0x20
+ bdnz Load_xts_enc_key
+
+ lvx v26,$x10,$key1
+ ?vperm v24,v30,v31,$keyperm
+ lvx v27,$x20,$key1
+ stvx v24,$x00,$key_ # off-load round[3]
+ ?vperm v25,v31,v26,$keyperm
+ lvx v28,$x30,$key1
+ stvx v25,$x10,$key_ # off-load round[4]
+ addi $key_,$sp,$FRAME+15 # rewind $key_
+ ?vperm v26,v26,v27,$keyperm
+ lvx v29,$x40,$key1
+ ?vperm v27,v27,v28,$keyperm
+ lvx v30,$x50,$key1
+ ?vperm v28,v28,v29,$keyperm
+ lvx v31,$x60,$key1
+ ?vperm v29,v29,v30,$keyperm
+ lvx $twk5,$x70,$key1 # borrow $twk5
+ ?vperm v30,v30,v31,$keyperm
+ lvx v24,$x00,$key_ # pre-load round[1]
+ ?vperm v31,v31,$twk5,$keyperm
+ lvx v25,$x10,$key_ # pre-load round[2]
+
+ # Switch to use the following codes with 0x010101..87 to generate tweak.
+ # eighty7 = 0x010101..87
+ # vsrab tmp, tweak, seven # next tweak value, right shift 7 bits
+ # vand tmp, tmp, eighty7 # last byte with carry
+ # vaddubm tweak, tweak, tweak # left shift 1 bit (x2)
+ # xxlor vsx, 0, 0
+ # vpermxor tweak, tweak, tmp, vsx
+
+ vperm $in0,$inout,$inptail,$inpperm
+ subi $inp,$inp,31 # undo "caller"
+ vxor $twk0,$tweak,$rndkey0
+ vsrab $tmp,$tweak,$seven # next tweak value
+ vaddubm $tweak,$tweak,$tweak
+ vand $tmp,$tmp,$eighty7
+ vxor $out0,$in0,$twk0
+ xxlor 32+$in1, 0, 0
+ vpermxor $tweak, $tweak, $tmp, $in1
+
+ lvx_u $in1,$x10,$inp
+ vxor $twk1,$tweak,$rndkey0
+ vsrab $tmp,$tweak,$seven # next tweak value
+ vaddubm $tweak,$tweak,$tweak
+ le?vperm $in1,$in1,$in1,$leperm
+ vand $tmp,$tmp,$eighty7
+ vxor $out1,$in1,$twk1
+ xxlor 32+$in2, 0, 0
+ vpermxor $tweak, $tweak, $tmp, $in2
+
+ lvx_u $in2,$x20,$inp
+ andi. $taillen,$len,15
+ vxor $twk2,$tweak,$rndkey0
+ vsrab $tmp,$tweak,$seven # next tweak value
+ vaddubm $tweak,$tweak,$tweak
+ le?vperm $in2,$in2,$in2,$leperm
+ vand $tmp,$tmp,$eighty7
+ vxor $out2,$in2,$twk2
+ xxlor 32+$in3, 0, 0
+ vpermxor $tweak, $tweak, $tmp, $in3
+
+ lvx_u $in3,$x30,$inp
+ sub $len,$len,$taillen
+ vxor $twk3,$tweak,$rndkey0
+ vsrab $tmp,$tweak,$seven # next tweak value
+ vaddubm $tweak,$tweak,$tweak
+ le?vperm $in3,$in3,$in3,$leperm
+ vand $tmp,$tmp,$eighty7
+ vxor $out3,$in3,$twk3
+ xxlor 32+$in4, 0, 0
+ vpermxor $tweak, $tweak, $tmp, $in4
+
+ lvx_u $in4,$x40,$inp
+ subi $len,$len,0x60
+ vxor $twk4,$tweak,$rndkey0
+ vsrab $tmp,$tweak,$seven # next tweak value
+ vaddubm $tweak,$tweak,$tweak
+ le?vperm $in4,$in4,$in4,$leperm
+ vand $tmp,$tmp,$eighty7
+ vxor $out4,$in4,$twk4
+ xxlor 32+$in5, 0, 0
+ vpermxor $tweak, $tweak, $tmp, $in5
+
+ lvx_u $in5,$x50,$inp
+ addi $inp,$inp,0x60
+ vxor $twk5,$tweak,$rndkey0
+ vsrab $tmp,$tweak,$seven # next tweak value
+ vaddubm $tweak,$tweak,$tweak
+ le?vperm $in5,$in5,$in5,$leperm
+ vand $tmp,$tmp,$eighty7
+ vxor $out5,$in5,$twk5
+ xxlor 32+$in0, 0, 0
+ vpermxor $tweak, $tweak, $tmp, $in0
+
+ vxor v31,v31,$rndkey0
+ mtctr $rounds
+ b Loop_xts_enc6x
+
+.align 5
+Loop_xts_enc6x:
+ vcipher $out0,$out0,v24
+ vcipher $out1,$out1,v24
+ vcipher $out2,$out2,v24
+ vcipher $out3,$out3,v24
+ vcipher $out4,$out4,v24
+ vcipher $out5,$out5,v24
+ lvx v24,$x20,$key_ # round[3]
+ addi $key_,$key_,0x20
+
+ vcipher $out0,$out0,v25
+ vcipher $out1,$out1,v25
+ vcipher $out2,$out2,v25
+ vcipher $out3,$out3,v25
+ vcipher $out4,$out4,v25
+ vcipher $out5,$out5,v25
+ lvx v25,$x10,$key_ # round[4]
+ bdnz Loop_xts_enc6x
+
+ xxlor 32+$eighty7, 1, 1 # 0x010101..87
+
+ subic $len,$len,96 # $len-=96
+ vxor $in0,$twk0,v31 # xor with last round key
+ vcipher $out0,$out0,v24
+ vcipher $out1,$out1,v24
+ vsrab $tmp,$tweak,$seven # next tweak value
+ vxor $twk0,$tweak,$rndkey0
+ vaddubm $tweak,$tweak,$tweak
+ vcipher $out2,$out2,v24
+ vcipher $out3,$out3,v24
+ vcipher $out4,$out4,v24
+ vcipher $out5,$out5,v24
+
+ subfe. r0,r0,r0 # borrow?-1:0
+ vand $tmp,$tmp,$eighty7
+ vcipher $out0,$out0,v25
+ vcipher $out1,$out1,v25
+ xxlor 32+$in1, 0, 0
+ vpermxor $tweak, $tweak, $tmp, $in1
+ vcipher $out2,$out2,v25
+ vcipher $out3,$out3,v25
+ vxor $in1,$twk1,v31
+ vsrab $tmp,$tweak,$seven # next tweak value
+ vxor $twk1,$tweak,$rndkey0
+ vcipher $out4,$out4,v25
+ vcipher $out5,$out5,v25
+
+ and r0,r0,$len
+ vaddubm $tweak,$tweak,$tweak
+ vcipher $out0,$out0,v26
+ vcipher $out1,$out1,v26
+ vand $tmp,$tmp,$eighty7
+ vcipher $out2,$out2,v26
+ vcipher $out3,$out3,v26
+ xxlor 32+$in2, 0, 0
+ vpermxor $tweak, $tweak, $tmp, $in2
+ vcipher $out4,$out4,v26
+ vcipher $out5,$out5,v26
+
+ add $inp,$inp,r0 # $inp is adjusted in such
+ # way that at exit from the
+ # loop inX-in5 are loaded
+ # with last "words"
+ vxor $in2,$twk2,v31
+ vsrab $tmp,$tweak,$seven # next tweak value
+ vxor $twk2,$tweak,$rndkey0
+ vaddubm $tweak,$tweak,$tweak
+ vcipher $out0,$out0,v27
+ vcipher $out1,$out1,v27
+ vcipher $out2,$out2,v27
+ vcipher $out3,$out3,v27
+ vand $tmp,$tmp,$eighty7
+ vcipher $out4,$out4,v27
+ vcipher $out5,$out5,v27
+
+ addi $key_,$sp,$FRAME+15 # rewind $key_
+ xxlor 32+$in3, 0, 0
+ vpermxor $tweak, $tweak, $tmp, $in3
+ vcipher $out0,$out0,v28
+ vcipher $out1,$out1,v28
+ vxor $in3,$twk3,v31
+ vsrab $tmp,$tweak,$seven # next tweak value
+ vxor $twk3,$tweak,$rndkey0
+ vcipher $out2,$out2,v28
+ vcipher $out3,$out3,v28
+ vaddubm $tweak,$tweak,$tweak
+ vcipher $out4,$out4,v28
+ vcipher $out5,$out5,v28
+ lvx v24,$x00,$key_ # re-pre-load round[1]
+ vand $tmp,$tmp,$eighty7
+
+ vcipher $out0,$out0,v29
+ vcipher $out1,$out1,v29
+ xxlor 32+$in4, 0, 0
+ vpermxor $tweak, $tweak, $tmp, $in4
+ vcipher $out2,$out2,v29
+ vcipher $out3,$out3,v29
+ vxor $in4,$twk4,v31
+ vsrab $tmp,$tweak,$seven # next tweak value
+ vxor $twk4,$tweak,$rndkey0
+ vcipher $out4,$out4,v29
+ vcipher $out5,$out5,v29
+ lvx v25,$x10,$key_ # re-pre-load round[2]
+ vaddubm $tweak,$tweak,$tweak
+
+ vcipher $out0,$out0,v30
+ vcipher $out1,$out1,v30
+ vand $tmp,$tmp,$eighty7
+ vcipher $out2,$out2,v30
+ vcipher $out3,$out3,v30
+ xxlor 32+$in5, 0, 0
+ vpermxor $tweak, $tweak, $tmp, $in5
+ vcipher $out4,$out4,v30
+ vcipher $out5,$out5,v30
+ vxor $in5,$twk5,v31
+ vsrab $tmp,$tweak,$seven # next tweak value
+ vxor $twk5,$tweak,$rndkey0
+
+ vcipherlast $out0,$out0,$in0
+ lvx_u $in0,$x00,$inp # load next input block
+ vaddubm $tweak,$tweak,$tweak
+ vcipherlast $out1,$out1,$in1
+ lvx_u $in1,$x10,$inp
+ vcipherlast $out2,$out2,$in2
+ le?vperm $in0,$in0,$in0,$leperm
+ lvx_u $in2,$x20,$inp
+ vand $tmp,$tmp,$eighty7
+ vcipherlast $out3,$out3,$in3
+ le?vperm $in1,$in1,$in1,$leperm
+ lvx_u $in3,$x30,$inp
+ vcipherlast $out4,$out4,$in4
+ le?vperm $in2,$in2,$in2,$leperm
+ lvx_u $in4,$x40,$inp
+ xxlor 10, 32+$in0, 32+$in0
+ xxlor 32+$in0, 0, 0
+ vpermxor $tweak, $tweak, $tmp, $in0
+ xxlor 32+$in0, 10, 10
+ vcipherlast $tmp,$out5,$in5 # last block might be needed
+ # in stealing mode
+ le?vperm $in3,$in3,$in3,$leperm
+ lvx_u $in5,$x50,$inp
+ addi $inp,$inp,0x60
+ le?vperm $in4,$in4,$in4,$leperm
+ le?vperm $in5,$in5,$in5,$leperm
+
+ le?vperm $out0,$out0,$out0,$leperm
+ le?vperm $out1,$out1,$out1,$leperm
+ stvx_u $out0,$x00,$out # store output
+ vxor $out0,$in0,$twk0
+ le?vperm $out2,$out2,$out2,$leperm
+ stvx_u $out1,$x10,$out
+ vxor $out1,$in1,$twk1
+ le?vperm $out3,$out3,$out3,$leperm
+ stvx_u $out2,$x20,$out
+ vxor $out2,$in2,$twk2
+ le?vperm $out4,$out4,$out4,$leperm
+ stvx_u $out3,$x30,$out
+ vxor $out3,$in3,$twk3
+ le?vperm $out5,$tmp,$tmp,$leperm
+ stvx_u $out4,$x40,$out
+ vxor $out4,$in4,$twk4
+ le?stvx_u $out5,$x50,$out
+ be?stvx_u $tmp, $x50,$out
+ vxor $out5,$in5,$twk5
+ addi $out,$out,0x60
+
+ mtctr $rounds
+ beq Loop_xts_enc6x # did $len-=96 borrow?
+
+ xxlor 32+$eighty7, 2, 2 # 0x010101..87
+
+ addic. $len,$len,0x60
+ beq Lxts_enc6x_zero
+ cmpwi $len,0x20
+ blt Lxts_enc6x_one
+ nop
+ beq Lxts_enc6x_two
+ cmpwi $len,0x40
+ blt Lxts_enc6x_three
+ nop
+ beq Lxts_enc6x_four
+
+Lxts_enc6x_five:
+ vxor $out0,$in1,$twk0
+ vxor $out1,$in2,$twk1
+ vxor $out2,$in3,$twk2
+ vxor $out3,$in4,$twk3
+ vxor $out4,$in5,$twk4
+
+ bl _aesp8_xts_enc5x
+
+ le?vperm $out0,$out0,$out0,$leperm
+ vmr $twk0,$twk5 # unused tweak
+ le?vperm $out1,$out1,$out1,$leperm
+ stvx_u $out0,$x00,$out # store output
+ le?vperm $out2,$out2,$out2,$leperm
+ stvx_u $out1,$x10,$out
+ le?vperm $out3,$out3,$out3,$leperm
+ stvx_u $out2,$x20,$out
+ vxor $tmp,$out4,$twk5 # last block prep for stealing
+ le?vperm $out4,$out4,$out4,$leperm
+ stvx_u $out3,$x30,$out
+ stvx_u $out4,$x40,$out
+ addi $out,$out,0x50
+ bne Lxts_enc6x_steal
+ b Lxts_enc6x_done
+
+.align 4
+Lxts_enc6x_four:
+ vxor $out0,$in2,$twk0
+ vxor $out1,$in3,$twk1
+ vxor $out2,$in4,$twk2
+ vxor $out3,$in5,$twk3
+ vxor $out4,$out4,$out4
+
+ bl _aesp8_xts_enc5x
+
+ le?vperm $out0,$out0,$out0,$leperm
+ vmr $twk0,$twk4 # unused tweak
+ le?vperm $out1,$out1,$out1,$leperm
+ stvx_u $out0,$x00,$out # store output
+ le?vperm $out2,$out2,$out2,$leperm
+ stvx_u $out1,$x10,$out
+ vxor $tmp,$out3,$twk4 # last block prep for stealing
+ le?vperm $out3,$out3,$out3,$leperm
+ stvx_u $out2,$x20,$out
+ stvx_u $out3,$x30,$out
+ addi $out,$out,0x40
+ bne Lxts_enc6x_steal
+ b Lxts_enc6x_done
+
+.align 4
+Lxts_enc6x_three:
+ vxor $out0,$in3,$twk0
+ vxor $out1,$in4,$twk1
+ vxor $out2,$in5,$twk2
+ vxor $out3,$out3,$out3
+ vxor $out4,$out4,$out4
+
+ bl _aesp8_xts_enc5x
+
+ le?vperm $out0,$out0,$out0,$leperm
+ vmr $twk0,$twk3 # unused tweak
+ le?vperm $out1,$out1,$out1,$leperm
+ stvx_u $out0,$x00,$out # store output
+ vxor $tmp,$out2,$twk3 # last block prep for stealing
+ le?vperm $out2,$out2,$out2,$leperm
+ stvx_u $out1,$x10,$out
+ stvx_u $out2,$x20,$out
+ addi $out,$out,0x30
+ bne Lxts_enc6x_steal
+ b Lxts_enc6x_done
+
+.align 4
+Lxts_enc6x_two:
+ vxor $out0,$in4,$twk0
+ vxor $out1,$in5,$twk1
+ vxor $out2,$out2,$out2
+ vxor $out3,$out3,$out3
+ vxor $out4,$out4,$out4
+
+ bl _aesp8_xts_enc5x
+
+ le?vperm $out0,$out0,$out0,$leperm
+ vmr $twk0,$twk2 # unused tweak
+ vxor $tmp,$out1,$twk2 # last block prep for stealing
+ le?vperm $out1,$out1,$out1,$leperm
+ stvx_u $out0,$x00,$out # store output
+ stvx_u $out1,$x10,$out
+ addi $out,$out,0x20
+ bne Lxts_enc6x_steal
+ b Lxts_enc6x_done
+
+.align 4
+Lxts_enc6x_one:
+ vxor $out0,$in5,$twk0
+ nop
+Loop_xts_enc1x:
+ vcipher $out0,$out0,v24
+ lvx v24,$x20,$key_ # round[3]
+ addi $key_,$key_,0x20
+
+ vcipher $out0,$out0,v25
+ lvx v25,$x10,$key_ # round[4]
+ bdnz Loop_xts_enc1x
+
+ add $inp,$inp,$taillen
+ cmpwi $taillen,0
+ vcipher $out0,$out0,v24
+
+ subi $inp,$inp,16
+ vcipher $out0,$out0,v25
+
+ lvsr $inpperm,0,$taillen
+ vcipher $out0,$out0,v26
+
+ lvx_u $in0,0,$inp
+ vcipher $out0,$out0,v27
+
+ addi $key_,$sp,$FRAME+15 # rewind $key_
+ vcipher $out0,$out0,v28
+ lvx v24,$x00,$key_ # re-pre-load round[1]
+
+ vcipher $out0,$out0,v29
+ lvx v25,$x10,$key_ # re-pre-load round[2]
+ vxor $twk0,$twk0,v31
+
+ le?vperm $in0,$in0,$in0,$leperm
+ vcipher $out0,$out0,v30
+
+ vperm $in0,$in0,$in0,$inpperm
+ vcipherlast $out0,$out0,$twk0
+
+ vmr $twk0,$twk1 # unused tweak
+ vxor $tmp,$out0,$twk1 # last block prep for stealing
+ le?vperm $out0,$out0,$out0,$leperm
+ stvx_u $out0,$x00,$out # store output
+ addi $out,$out,0x10
+ bne Lxts_enc6x_steal
+ b Lxts_enc6x_done
+
+.align 4
+Lxts_enc6x_zero:
+ cmpwi $taillen,0
+ beq Lxts_enc6x_done
+
+ add $inp,$inp,$taillen
+ subi $inp,$inp,16
+ lvx_u $in0,0,$inp
+ lvsr $inpperm,0,$taillen # $in5 is no more
+ le?vperm $in0,$in0,$in0,$leperm
+ vperm $in0,$in0,$in0,$inpperm
+ vxor $tmp,$tmp,$twk0
+Lxts_enc6x_steal:
+ vxor $in0,$in0,$twk0
+ vxor $out0,$out0,$out0
+ vspltisb $out1,-1
+ vperm $out0,$out0,$out1,$inpperm
+ vsel $out0,$in0,$tmp,$out0 # $tmp is last block, remember?
+
+ subi r30,$out,17
+ subi $out,$out,16
+ mtctr $taillen
+Loop_xts_enc6x_steal:
+ lbzu r0,1(r30)
+ stb r0,16(r30)
+ bdnz Loop_xts_enc6x_steal
+
+ li $taillen,0
+ mtctr $rounds
+ b Loop_xts_enc1x # one more time...
+
+.align 4
+Lxts_enc6x_done:
+ ${UCMP}i $ivp,0
+ beq Lxts_enc6x_ret
+
+ vxor $tweak,$twk0,$rndkey0
+ le?vperm $tweak,$tweak,$tweak,$leperm
+ stvx_u $tweak,0,$ivp
+
+Lxts_enc6x_ret:
+ mtlr r11
+ li r10,`$FRAME+15`
+ li r11,`$FRAME+31`
+ stvx $seven,r10,$sp # wipe copies of round keys
+ addi r10,r10,32
+ stvx $seven,r11,$sp
+ addi r11,r11,32
+ stvx $seven,r10,$sp
+ addi r10,r10,32
+ stvx $seven,r11,$sp
+ addi r11,r11,32
+ stvx $seven,r10,$sp
+ addi r10,r10,32
+ stvx $seven,r11,$sp
+ addi r11,r11,32
+ stvx $seven,r10,$sp
+ addi r10,r10,32
+ stvx $seven,r11,$sp
+ addi r11,r11,32
+
+ mtspr 256,$vrsave
+ lvx v20,r10,$sp # ABI says so
+ addi r10,r10,32
+ lvx v21,r11,$sp
+ addi r11,r11,32
+ lvx v22,r10,$sp
+ addi r10,r10,32
+ lvx v23,r11,$sp
+ addi r11,r11,32
+ lvx v24,r10,$sp
+ addi r10,r10,32
+ lvx v25,r11,$sp
+ addi r11,r11,32
+ lvx v26,r10,$sp
+ addi r10,r10,32
+ lvx v27,r11,$sp
+ addi r11,r11,32
+ lvx v28,r10,$sp
+ addi r10,r10,32
+ lvx v29,r11,$sp
+ addi r11,r11,32
+ lvx v30,r10,$sp
+ lvx v31,r11,$sp
+ $POP r26,`$FRAME+21*16+0*$SIZE_T`($sp)
+ $POP r27,`$FRAME+21*16+1*$SIZE_T`($sp)
+ $POP r28,`$FRAME+21*16+2*$SIZE_T`($sp)
+ $POP r29,`$FRAME+21*16+3*$SIZE_T`($sp)
+ $POP r30,`$FRAME+21*16+4*$SIZE_T`($sp)
+ $POP r31,`$FRAME+21*16+5*$SIZE_T`($sp)
+ addi $sp,$sp,`$FRAME+21*16+6*$SIZE_T`
+ blr
+ .long 0
+ .byte 0,12,0x04,1,0x80,6,6,0
+ .long 0
+
+.align 5
+_aesp8_xts_enc5x:
+ vcipher $out0,$out0,v24
+ vcipher $out1,$out1,v24
+ vcipher $out2,$out2,v24
+ vcipher $out3,$out3,v24
+ vcipher $out4,$out4,v24
+ lvx v24,$x20,$key_ # round[3]
+ addi $key_,$key_,0x20
+
+ vcipher $out0,$out0,v25
+ vcipher $out1,$out1,v25
+ vcipher $out2,$out2,v25
+ vcipher $out3,$out3,v25
+ vcipher $out4,$out4,v25
+ lvx v25,$x10,$key_ # round[4]
+ bdnz _aesp8_xts_enc5x
+
+ add $inp,$inp,$taillen
+ cmpwi $taillen,0
+ vcipher $out0,$out0,v24
+ vcipher $out1,$out1,v24
+ vcipher $out2,$out2,v24
+ vcipher $out3,$out3,v24
+ vcipher $out4,$out4,v24
+
+ subi $inp,$inp,16
+ vcipher $out0,$out0,v25
+ vcipher $out1,$out1,v25
+ vcipher $out2,$out2,v25
+ vcipher $out3,$out3,v25
+ vcipher $out4,$out4,v25
+ vxor $twk0,$twk0,v31
+
+ vcipher $out0,$out0,v26
+ lvsr $inpperm,r0,$taillen # $in5 is no more
+ vcipher $out1,$out1,v26
+ vcipher $out2,$out2,v26
+ vcipher $out3,$out3,v26
+ vcipher $out4,$out4,v26
+ vxor $in1,$twk1,v31
+
+ vcipher $out0,$out0,v27
+ lvx_u $in0,0,$inp
+ vcipher $out1,$out1,v27
+ vcipher $out2,$out2,v27
+ vcipher $out3,$out3,v27
+ vcipher $out4,$out4,v27
+ vxor $in2,$twk2,v31
+
+ addi $key_,$sp,$FRAME+15 # rewind $key_
+ vcipher $out0,$out0,v28
+ vcipher $out1,$out1,v28
+ vcipher $out2,$out2,v28
+ vcipher $out3,$out3,v28
+ vcipher $out4,$out4,v28
+ lvx v24,$x00,$key_ # re-pre-load round[1]
+ vxor $in3,$twk3,v31
+
+ vcipher $out0,$out0,v29
+ le?vperm $in0,$in0,$in0,$leperm
+ vcipher $out1,$out1,v29
+ vcipher $out2,$out2,v29
+ vcipher $out3,$out3,v29
+ vcipher $out4,$out4,v29
+ lvx v25,$x10,$key_ # re-pre-load round[2]
+ vxor $in4,$twk4,v31
+
+ vcipher $out0,$out0,v30
+ vperm $in0,$in0,$in0,$inpperm
+ vcipher $out1,$out1,v30
+ vcipher $out2,$out2,v30
+ vcipher $out3,$out3,v30
+ vcipher $out4,$out4,v30
+
+ vcipherlast $out0,$out0,$twk0
+ vcipherlast $out1,$out1,$in1
+ vcipherlast $out2,$out2,$in2
+ vcipherlast $out3,$out3,$in3
+ vcipherlast $out4,$out4,$in4
+ blr
+ .long 0
+ .byte 0,12,0x14,0,0,0,0,0
+
+.align 5
+_aesp8_xts_decrypt6x:
+ $STU $sp,-`($FRAME+21*16+6*$SIZE_T)`($sp)
+ mflr r11
+ li r7,`$FRAME+8*16+15`
+ li r3,`$FRAME+8*16+31`
+ $PUSH r11,`$FRAME+21*16+6*$SIZE_T+$LRSAVE`($sp)
+ stvx v20,r7,$sp # ABI says so
+ addi r7,r7,32
+ stvx v21,r3,$sp
+ addi r3,r3,32
+ stvx v22,r7,$sp
+ addi r7,r7,32
+ stvx v23,r3,$sp
+ addi r3,r3,32
+ stvx v24,r7,$sp
+ addi r7,r7,32
+ stvx v25,r3,$sp
+ addi r3,r3,32
+ stvx v26,r7,$sp
+ addi r7,r7,32
+ stvx v27,r3,$sp
+ addi r3,r3,32
+ stvx v28,r7,$sp
+ addi r7,r7,32
+ stvx v29,r3,$sp
+ addi r3,r3,32
+ stvx v30,r7,$sp
+ stvx v31,r3,$sp
+ li r0,-1
+ stw $vrsave,`$FRAME+21*16-4`($sp) # save vrsave
+ li $x10,0x10
+ $PUSH r26,`$FRAME+21*16+0*$SIZE_T`($sp)
+ li $x20,0x20
+ $PUSH r27,`$FRAME+21*16+1*$SIZE_T`($sp)
+ li $x30,0x30
+ $PUSH r28,`$FRAME+21*16+2*$SIZE_T`($sp)
+ li $x40,0x40
+ $PUSH r29,`$FRAME+21*16+3*$SIZE_T`($sp)
+ li $x50,0x50
+ $PUSH r30,`$FRAME+21*16+4*$SIZE_T`($sp)
+ li $x60,0x60
+ $PUSH r31,`$FRAME+21*16+5*$SIZE_T`($sp)
+ li $x70,0x70
+ mtspr 256,r0
+
+ xxlor 2, 32+$eighty7, 32+$eighty7
+ vsldoi $eighty7,$tmp,$eighty7,1 # 0x010101..87
+ xxlor 1, 32+$eighty7, 32+$eighty7
+
+ # Load XOR Lconsts.
+ mr $x70, r6
+ bl Lconsts
+ lxvw4x 0, $x40, r6 # load XOR contents
+ mr r6, $x70
+ li $x70,0x70
+
+ subi $rounds,$rounds,3 # -4 in total
+
+ lvx $rndkey0,$x00,$key1 # load key schedule
+ lvx v30,$x10,$key1
+ addi $key1,$key1,0x20
+ lvx v31,$x00,$key1
+ ?vperm $rndkey0,$rndkey0,v30,$keyperm
+ addi $key_,$sp,$FRAME+15
+ mtctr $rounds
+
+Load_xts_dec_key:
+ ?vperm v24,v30,v31,$keyperm
+ lvx v30,$x10,$key1
+ addi $key1,$key1,0x20
+ stvx v24,$x00,$key_ # off-load round[1]
+ ?vperm v25,v31,v30,$keyperm
+ lvx v31,$x00,$key1
+ stvx v25,$x10,$key_ # off-load round[2]
+ addi $key_,$key_,0x20
+ bdnz Load_xts_dec_key
+
+ lvx v26,$x10,$key1
+ ?vperm v24,v30,v31,$keyperm
+ lvx v27,$x20,$key1
+ stvx v24,$x00,$key_ # off-load round[3]
+ ?vperm v25,v31,v26,$keyperm
+ lvx v28,$x30,$key1
+ stvx v25,$x10,$key_ # off-load round[4]
+ addi $key_,$sp,$FRAME+15 # rewind $key_
+ ?vperm v26,v26,v27,$keyperm
+ lvx v29,$x40,$key1
+ ?vperm v27,v27,v28,$keyperm
+ lvx v30,$x50,$key1
+ ?vperm v28,v28,v29,$keyperm
+ lvx v31,$x60,$key1
+ ?vperm v29,v29,v30,$keyperm
+ lvx $twk5,$x70,$key1 # borrow $twk5
+ ?vperm v30,v30,v31,$keyperm
+ lvx v24,$x00,$key_ # pre-load round[1]
+ ?vperm v31,v31,$twk5,$keyperm
+ lvx v25,$x10,$key_ # pre-load round[2]
+
+ vperm $in0,$inout,$inptail,$inpperm
+ subi $inp,$inp,31 # undo "caller"
+ vxor $twk0,$tweak,$rndkey0
+ vsrab $tmp,$tweak,$seven # next tweak value
+ vaddubm $tweak,$tweak,$tweak
+ vand $tmp,$tmp,$eighty7
+ vxor $out0,$in0,$twk0
+ xxlor 32+$in1, 0, 0
+ vpermxor $tweak, $tweak, $tmp, $in1
+
+ lvx_u $in1,$x10,$inp
+ vxor $twk1,$tweak,$rndkey0
+ vsrab $tmp,$tweak,$seven # next tweak value
+ vaddubm $tweak,$tweak,$tweak
+ le?vperm $in1,$in1,$in1,$leperm
+ vand $tmp,$tmp,$eighty7
+ vxor $out1,$in1,$twk1
+ xxlor 32+$in2, 0, 0
+ vpermxor $tweak, $tweak, $tmp, $in2
+
+ lvx_u $in2,$x20,$inp
+ andi. $taillen,$len,15
+ vxor $twk2,$tweak,$rndkey0
+ vsrab $tmp,$tweak,$seven # next tweak value
+ vaddubm $tweak,$tweak,$tweak
+ le?vperm $in2,$in2,$in2,$leperm
+ vand $tmp,$tmp,$eighty7
+ vxor $out2,$in2,$twk2
+ xxlor 32+$in3, 0, 0
+ vpermxor $tweak, $tweak, $tmp, $in3
+
+ lvx_u $in3,$x30,$inp
+ sub $len,$len,$taillen
+ vxor $twk3,$tweak,$rndkey0
+ vsrab $tmp,$tweak,$seven # next tweak value
+ vaddubm $tweak,$tweak,$tweak
+ le?vperm $in3,$in3,$in3,$leperm
+ vand $tmp,$tmp,$eighty7
+ vxor $out3,$in3,$twk3
+ xxlor 32+$in4, 0, 0
+ vpermxor $tweak, $tweak, $tmp, $in4
+
+ lvx_u $in4,$x40,$inp
+ subi $len,$len,0x60
+ vxor $twk4,$tweak,$rndkey0
+ vsrab $tmp,$tweak,$seven # next tweak value
+ vaddubm $tweak,$tweak,$tweak
+ le?vperm $in4,$in4,$in4,$leperm
+ vand $tmp,$tmp,$eighty7
+ vxor $out4,$in4,$twk4
+ xxlor 32+$in5, 0, 0
+ vpermxor $tweak, $tweak, $tmp, $in5
+
+ lvx_u $in5,$x50,$inp
+ addi $inp,$inp,0x60
+ vxor $twk5,$tweak,$rndkey0
+ vsrab $tmp,$tweak,$seven # next tweak value
+ vaddubm $tweak,$tweak,$tweak
+ le?vperm $in5,$in5,$in5,$leperm
+ vand $tmp,$tmp,$eighty7
+ vxor $out5,$in5,$twk5
+ xxlor 32+$in0, 0, 0
+ vpermxor $tweak, $tweak, $tmp, $in0
+
+ vxor v31,v31,$rndkey0
+ mtctr $rounds
+ b Loop_xts_dec6x
+
+.align 5
+Loop_xts_dec6x:
+ vncipher $out0,$out0,v24
+ vncipher $out1,$out1,v24
+ vncipher $out2,$out2,v24
+ vncipher $out3,$out3,v24
+ vncipher $out4,$out4,v24
+ vncipher $out5,$out5,v24
+ lvx v24,$x20,$key_ # round[3]
+ addi $key_,$key_,0x20
+
+ vncipher $out0,$out0,v25
+ vncipher $out1,$out1,v25
+ vncipher $out2,$out2,v25
+ vncipher $out3,$out3,v25
+ vncipher $out4,$out4,v25
+ vncipher $out5,$out5,v25
+ lvx v25,$x10,$key_ # round[4]
+ bdnz Loop_xts_dec6x
+
+ xxlor 32+$eighty7, 1, 1 # 0x010101..87
+
+ subic $len,$len,96 # $len-=96
+ vxor $in0,$twk0,v31 # xor with last round key
+ vncipher $out0,$out0,v24
+ vncipher $out1,$out1,v24
+ vsrab $tmp,$tweak,$seven # next tweak value
+ vxor $twk0,$tweak,$rndkey0
+ vaddubm $tweak,$tweak,$tweak
+ vncipher $out2,$out2,v24
+ vncipher $out3,$out3,v24
+ vncipher $out4,$out4,v24
+ vncipher $out5,$out5,v24
+
+ subfe. r0,r0,r0 # borrow?-1:0
+ vand $tmp,$tmp,$eighty7
+ vncipher $out0,$out0,v25
+ vncipher $out1,$out1,v25
+ xxlor 32+$in1, 0, 0
+ vpermxor $tweak, $tweak, $tmp, $in1
+ vncipher $out2,$out2,v25
+ vncipher $out3,$out3,v25
+ vxor $in1,$twk1,v31
+ vsrab $tmp,$tweak,$seven # next tweak value
+ vxor $twk1,$tweak,$rndkey0
+ vncipher $out4,$out4,v25
+ vncipher $out5,$out5,v25
+
+ and r0,r0,$len
+ vaddubm $tweak,$tweak,$tweak
+ vncipher $out0,$out0,v26
+ vncipher $out1,$out1,v26
+ vand $tmp,$tmp,$eighty7
+ vncipher $out2,$out2,v26
+ vncipher $out3,$out3,v26
+ xxlor 32+$in2, 0, 0
+ vpermxor $tweak, $tweak, $tmp, $in2
+ vncipher $out4,$out4,v26
+ vncipher $out5,$out5,v26
+
+ add $inp,$inp,r0 # $inp is adjusted in such
+ # way that at exit from the
+ # loop inX-in5 are loaded
+ # with last "words"
+ vxor $in2,$twk2,v31
+ vsrab $tmp,$tweak,$seven # next tweak value
+ vxor $twk2,$tweak,$rndkey0
+ vaddubm $tweak,$tweak,$tweak
+ vncipher $out0,$out0,v27
+ vncipher $out1,$out1,v27
+ vncipher $out2,$out2,v27
+ vncipher $out3,$out3,v27
+ vand $tmp,$tmp,$eighty7
+ vncipher $out4,$out4,v27
+ vncipher $out5,$out5,v27
+
+ addi $key_,$sp,$FRAME+15 # rewind $key_
+ xxlor 32+$in3, 0, 0
+ vpermxor $tweak, $tweak, $tmp, $in3
+ vncipher $out0,$out0,v28
+ vncipher $out1,$out1,v28
+ vxor $in3,$twk3,v31
+ vsrab $tmp,$tweak,$seven # next tweak value
+ vxor $twk3,$tweak,$rndkey0
+ vncipher $out2,$out2,v28
+ vncipher $out3,$out3,v28
+ vaddubm $tweak,$tweak,$tweak
+ vncipher $out4,$out4,v28
+ vncipher $out5,$out5,v28
+ lvx v24,$x00,$key_ # re-pre-load round[1]
+ vand $tmp,$tmp,$eighty7
+
+ vncipher $out0,$out0,v29
+ vncipher $out1,$out1,v29
+ xxlor 32+$in4, 0, 0
+ vpermxor $tweak, $tweak, $tmp, $in4
+ vncipher $out2,$out2,v29
+ vncipher $out3,$out3,v29
+ vxor $in4,$twk4,v31
+ vsrab $tmp,$tweak,$seven # next tweak value
+ vxor $twk4,$tweak,$rndkey0
+ vncipher $out4,$out4,v29
+ vncipher $out5,$out5,v29
+ lvx v25,$x10,$key_ # re-pre-load round[2]
+ vaddubm $tweak,$tweak,$tweak
+
+ vncipher $out0,$out0,v30
+ vncipher $out1,$out1,v30
+ vand $tmp,$tmp,$eighty7
+ vncipher $out2,$out2,v30
+ vncipher $out3,$out3,v30
+ xxlor 32+$in5, 0, 0
+ vpermxor $tweak, $tweak, $tmp, $in5
+ vncipher $out4,$out4,v30
+ vncipher $out5,$out5,v30
+ vxor $in5,$twk5,v31
+ vsrab $tmp,$tweak,$seven # next tweak value
+ vxor $twk5,$tweak,$rndkey0
+
+ vncipherlast $out0,$out0,$in0
+ lvx_u $in0,$x00,$inp # load next input block
+ vaddubm $tweak,$tweak,$tweak
+ vncipherlast $out1,$out1,$in1
+ lvx_u $in1,$x10,$inp
+ vncipherlast $out2,$out2,$in2
+ le?vperm $in0,$in0,$in0,$leperm
+ lvx_u $in2,$x20,$inp
+ vand $tmp,$tmp,$eighty7
+ vncipherlast $out3,$out3,$in3
+ le?vperm $in1,$in1,$in1,$leperm
+ lvx_u $in3,$x30,$inp
+ vncipherlast $out4,$out4,$in4
+ le?vperm $in2,$in2,$in2,$leperm
+ lvx_u $in4,$x40,$inp
+ xxlor 10, 32+$in0, 32+$in0
+ xxlor 32+$in0, 0, 0
+ vpermxor $tweak, $tweak, $tmp, $in0
+ xxlor 32+$in0, 10, 10
+ vncipherlast $out5,$out5,$in5
+ le?vperm $in3,$in3,$in3,$leperm
+ lvx_u $in5,$x50,$inp
+ addi $inp,$inp,0x60
+ le?vperm $in4,$in4,$in4,$leperm
+ le?vperm $in5,$in5,$in5,$leperm
+
+ le?vperm $out0,$out0,$out0,$leperm
+ le?vperm $out1,$out1,$out1,$leperm
+ stvx_u $out0,$x00,$out # store output
+ vxor $out0,$in0,$twk0
+ le?vperm $out2,$out2,$out2,$leperm
+ stvx_u $out1,$x10,$out
+ vxor $out1,$in1,$twk1
+ le?vperm $out3,$out3,$out3,$leperm
+ stvx_u $out2,$x20,$out
+ vxor $out2,$in2,$twk2
+ le?vperm $out4,$out4,$out4,$leperm
+ stvx_u $out3,$x30,$out
+ vxor $out3,$in3,$twk3
+ le?vperm $out5,$out5,$out5,$leperm
+ stvx_u $out4,$x40,$out
+ vxor $out4,$in4,$twk4
+ stvx_u $out5,$x50,$out
+ vxor $out5,$in5,$twk5
+ addi $out,$out,0x60
+
+ mtctr $rounds
+ beq Loop_xts_dec6x # did $len-=96 borrow?
+
+ xxlor 32+$eighty7, 2, 2 # 0x010101..87
+
+ addic. $len,$len,0x60
+ beq Lxts_dec6x_zero
+ cmpwi $len,0x20
+ blt Lxts_dec6x_one
+ nop
+ beq Lxts_dec6x_two
+ cmpwi $len,0x40
+ blt Lxts_dec6x_three
+ nop
+ beq Lxts_dec6x_four
+
+Lxts_dec6x_five:
+ vxor $out0,$in1,$twk0
+ vxor $out1,$in2,$twk1
+ vxor $out2,$in3,$twk2
+ vxor $out3,$in4,$twk3
+ vxor $out4,$in5,$twk4
+
+ bl _aesp8_xts_dec5x
+
+ le?vperm $out0,$out0,$out0,$leperm
+ vmr $twk0,$twk5 # unused tweak
+ vxor $twk1,$tweak,$rndkey0
+ le?vperm $out1,$out1,$out1,$leperm
+ stvx_u $out0,$x00,$out # store output
+ vxor $out0,$in0,$twk1
+ le?vperm $out2,$out2,$out2,$leperm
+ stvx_u $out1,$x10,$out
+ le?vperm $out3,$out3,$out3,$leperm
+ stvx_u $out2,$x20,$out
+ le?vperm $out4,$out4,$out4,$leperm
+ stvx_u $out3,$x30,$out
+ stvx_u $out4,$x40,$out
+ addi $out,$out,0x50
+ bne Lxts_dec6x_steal
+ b Lxts_dec6x_done
+
+.align 4
+Lxts_dec6x_four:
+ vxor $out0,$in2,$twk0
+ vxor $out1,$in3,$twk1
+ vxor $out2,$in4,$twk2
+ vxor $out3,$in5,$twk3
+ vxor $out4,$out4,$out4
+
+ bl _aesp8_xts_dec5x
+
+ le?vperm $out0,$out0,$out0,$leperm
+ vmr $twk0,$twk4 # unused tweak
+ vmr $twk1,$twk5
+ le?vperm $out1,$out1,$out1,$leperm
+ stvx_u $out0,$x00,$out # store output
+ vxor $out0,$in0,$twk5
+ le?vperm $out2,$out2,$out2,$leperm
+ stvx_u $out1,$x10,$out
+ le?vperm $out3,$out3,$out3,$leperm
+ stvx_u $out2,$x20,$out
+ stvx_u $out3,$x30,$out
+ addi $out,$out,0x40
+ bne Lxts_dec6x_steal
+ b Lxts_dec6x_done
+
+.align 4
+Lxts_dec6x_three:
+ vxor $out0,$in3,$twk0
+ vxor $out1,$in4,$twk1
+ vxor $out2,$in5,$twk2
+ vxor $out3,$out3,$out3
+ vxor $out4,$out4,$out4
+
+ bl _aesp8_xts_dec5x
+
+ le?vperm $out0,$out0,$out0,$leperm
+ vmr $twk0,$twk3 # unused tweak
+ vmr $twk1,$twk4
+ le?vperm $out1,$out1,$out1,$leperm
+ stvx_u $out0,$x00,$out # store output
+ vxor $out0,$in0,$twk4
+ le?vperm $out2,$out2,$out2,$leperm
+ stvx_u $out1,$x10,$out
+ stvx_u $out2,$x20,$out
+ addi $out,$out,0x30
+ bne Lxts_dec6x_steal
+ b Lxts_dec6x_done
+
+.align 4
+Lxts_dec6x_two:
+ vxor $out0,$in4,$twk0
+ vxor $out1,$in5,$twk1
+ vxor $out2,$out2,$out2
+ vxor $out3,$out3,$out3
+ vxor $out4,$out4,$out4
+
+ bl _aesp8_xts_dec5x
+
+ le?vperm $out0,$out0,$out0,$leperm
+ vmr $twk0,$twk2 # unused tweak
+ vmr $twk1,$twk3
+ le?vperm $out1,$out1,$out1,$leperm
+ stvx_u $out0,$x00,$out # store output
+ vxor $out0,$in0,$twk3
+ stvx_u $out1,$x10,$out
+ addi $out,$out,0x20
+ bne Lxts_dec6x_steal
+ b Lxts_dec6x_done
+
+.align 4
+Lxts_dec6x_one:
+ vxor $out0,$in5,$twk0
+ nop
+Loop_xts_dec1x:
+ vncipher $out0,$out0,v24
+ lvx v24,$x20,$key_ # round[3]
+ addi $key_,$key_,0x20
+
+ vncipher $out0,$out0,v25
+ lvx v25,$x10,$key_ # round[4]
+ bdnz Loop_xts_dec1x
+
+ subi r0,$taillen,1
+ vncipher $out0,$out0,v24
+
+ andi. r0,r0,16
+ cmpwi $taillen,0
+ vncipher $out0,$out0,v25
+
+ sub $inp,$inp,r0
+ vncipher $out0,$out0,v26
+
+ lvx_u $in0,0,$inp
+ vncipher $out0,$out0,v27
+
+ addi $key_,$sp,$FRAME+15 # rewind $key_
+ vncipher $out0,$out0,v28
+ lvx v24,$x00,$key_ # re-pre-load round[1]
+
+ vncipher $out0,$out0,v29
+ lvx v25,$x10,$key_ # re-pre-load round[2]
+ vxor $twk0,$twk0,v31
+
+ le?vperm $in0,$in0,$in0,$leperm
+ vncipher $out0,$out0,v30
+
+ mtctr $rounds
+ vncipherlast $out0,$out0,$twk0
+
+ vmr $twk0,$twk1 # unused tweak
+ vmr $twk1,$twk2
+ le?vperm $out0,$out0,$out0,$leperm
+ stvx_u $out0,$x00,$out # store output
+ addi $out,$out,0x10
+ vxor $out0,$in0,$twk2
+ bne Lxts_dec6x_steal
+ b Lxts_dec6x_done
+
+.align 4
+Lxts_dec6x_zero:
+ cmpwi $taillen,0
+ beq Lxts_dec6x_done
+
+ lvx_u $in0,0,$inp
+ le?vperm $in0,$in0,$in0,$leperm
+ vxor $out0,$in0,$twk1
+Lxts_dec6x_steal:
+ vncipher $out0,$out0,v24
+ lvx v24,$x20,$key_ # round[3]
+ addi $key_,$key_,0x20
+
+ vncipher $out0,$out0,v25
+ lvx v25,$x10,$key_ # round[4]
+ bdnz Lxts_dec6x_steal
+
+ add $inp,$inp,$taillen
+ vncipher $out0,$out0,v24
+
+ cmpwi $taillen,0
+ vncipher $out0,$out0,v25
+
+ lvx_u $in0,0,$inp
+ vncipher $out0,$out0,v26
+
+ lvsr $inpperm,0,$taillen # $in5 is no more
+ vncipher $out0,$out0,v27
+
+ addi $key_,$sp,$FRAME+15 # rewind $key_
+ vncipher $out0,$out0,v28
+ lvx v24,$x00,$key_ # re-pre-load round[1]
+
+ vncipher $out0,$out0,v29
+ lvx v25,$x10,$key_ # re-pre-load round[2]
+ vxor $twk1,$twk1,v31
+
+ le?vperm $in0,$in0,$in0,$leperm
+ vncipher $out0,$out0,v30
+
+ vperm $in0,$in0,$in0,$inpperm
+ vncipherlast $tmp,$out0,$twk1
+
+ le?vperm $out0,$tmp,$tmp,$leperm
+ le?stvx_u $out0,0,$out
+ be?stvx_u $tmp,0,$out
+
+ vxor $out0,$out0,$out0
+ vspltisb $out1,-1
+ vperm $out0,$out0,$out1,$inpperm
+ vsel $out0,$in0,$tmp,$out0
+ vxor $out0,$out0,$twk0
+
+ subi r30,$out,1
+ mtctr $taillen
+Loop_xts_dec6x_steal:
+ lbzu r0,1(r30)
+ stb r0,16(r30)
+ bdnz Loop_xts_dec6x_steal
+
+ li $taillen,0
+ mtctr $rounds
+ b Loop_xts_dec1x # one more time...
+
+.align 4
+Lxts_dec6x_done:
+ ${UCMP}i $ivp,0
+ beq Lxts_dec6x_ret
+
+ vxor $tweak,$twk0,$rndkey0
+ le?vperm $tweak,$tweak,$tweak,$leperm
+ stvx_u $tweak,0,$ivp
+
+Lxts_dec6x_ret:
+ mtlr r11
+ li r10,`$FRAME+15`
+ li r11,`$FRAME+31`
+ stvx $seven,r10,$sp # wipe copies of round keys
+ addi r10,r10,32
+ stvx $seven,r11,$sp
+ addi r11,r11,32
+ stvx $seven,r10,$sp
+ addi r10,r10,32
+ stvx $seven,r11,$sp
+ addi r11,r11,32
+ stvx $seven,r10,$sp
+ addi r10,r10,32
+ stvx $seven,r11,$sp
+ addi r11,r11,32
+ stvx $seven,r10,$sp
+ addi r10,r10,32
+ stvx $seven,r11,$sp
+ addi r11,r11,32
+
+ mtspr 256,$vrsave
+ lvx v20,r10,$sp # ABI says so
+ addi r10,r10,32
+ lvx v21,r11,$sp
+ addi r11,r11,32
+ lvx v22,r10,$sp
+ addi r10,r10,32
+ lvx v23,r11,$sp
+ addi r11,r11,32
+ lvx v24,r10,$sp
+ addi r10,r10,32
+ lvx v25,r11,$sp
+ addi r11,r11,32
+ lvx v26,r10,$sp
+ addi r10,r10,32
+ lvx v27,r11,$sp
+ addi r11,r11,32
+ lvx v28,r10,$sp
+ addi r10,r10,32
+ lvx v29,r11,$sp
+ addi r11,r11,32
+ lvx v30,r10,$sp
+ lvx v31,r11,$sp
+ $POP r26,`$FRAME+21*16+0*$SIZE_T`($sp)
+ $POP r27,`$FRAME+21*16+1*$SIZE_T`($sp)
+ $POP r28,`$FRAME+21*16+2*$SIZE_T`($sp)
+ $POP r29,`$FRAME+21*16+3*$SIZE_T`($sp)
+ $POP r30,`$FRAME+21*16+4*$SIZE_T`($sp)
+ $POP r31,`$FRAME+21*16+5*$SIZE_T`($sp)
+ addi $sp,$sp,`$FRAME+21*16+6*$SIZE_T`
+ blr
+ .long 0
+ .byte 0,12,0x04,1,0x80,6,6,0
+ .long 0
+
+.align 5
+_aesp8_xts_dec5x:
+ vncipher $out0,$out0,v24
+ vncipher $out1,$out1,v24
+ vncipher $out2,$out2,v24
+ vncipher $out3,$out3,v24
+ vncipher $out4,$out4,v24
+ lvx v24,$x20,$key_ # round[3]
+ addi $key_,$key_,0x20
+
+ vncipher $out0,$out0,v25
+ vncipher $out1,$out1,v25
+ vncipher $out2,$out2,v25
+ vncipher $out3,$out3,v25
+ vncipher $out4,$out4,v25
+ lvx v25,$x10,$key_ # round[4]
+ bdnz _aesp8_xts_dec5x
+
+ subi r0,$taillen,1
+ vncipher $out0,$out0,v24
+ vncipher $out1,$out1,v24
+ vncipher $out2,$out2,v24
+ vncipher $out3,$out3,v24
+ vncipher $out4,$out4,v24
+
+ andi. r0,r0,16
+ cmpwi $taillen,0
+ vncipher $out0,$out0,v25
+ vncipher $out1,$out1,v25
+ vncipher $out2,$out2,v25
+ vncipher $out3,$out3,v25
+ vncipher $out4,$out4,v25
+ vxor $twk0,$twk0,v31
+
+ sub $inp,$inp,r0
+ vncipher $out0,$out0,v26
+ vncipher $out1,$out1,v26
+ vncipher $out2,$out2,v26
+ vncipher $out3,$out3,v26
+ vncipher $out4,$out4,v26
+ vxor $in1,$twk1,v31
+
+ vncipher $out0,$out0,v27
+ lvx_u $in0,0,$inp
+ vncipher $out1,$out1,v27
+ vncipher $out2,$out2,v27
+ vncipher $out3,$out3,v27
+ vncipher $out4,$out4,v27
+ vxor $in2,$twk2,v31
+
+ addi $key_,$sp,$FRAME+15 # rewind $key_
+ vncipher $out0,$out0,v28
+ vncipher $out1,$out1,v28
+ vncipher $out2,$out2,v28
+ vncipher $out3,$out3,v28
+ vncipher $out4,$out4,v28
+ lvx v24,$x00,$key_ # re-pre-load round[1]
+ vxor $in3,$twk3,v31
+
+ vncipher $out0,$out0,v29
+ le?vperm $in0,$in0,$in0,$leperm
+ vncipher $out1,$out1,v29
+ vncipher $out2,$out2,v29
+ vncipher $out3,$out3,v29
+ vncipher $out4,$out4,v29
+ lvx v25,$x10,$key_ # re-pre-load round[2]
+ vxor $in4,$twk4,v31
+
+ vncipher $out0,$out0,v30
+ vncipher $out1,$out1,v30
+ vncipher $out2,$out2,v30
+ vncipher $out3,$out3,v30
+ vncipher $out4,$out4,v30
+
+ vncipherlast $out0,$out0,$twk0
+ vncipherlast $out1,$out1,$in1
+ vncipherlast $out2,$out2,$in2
+ vncipherlast $out3,$out3,$in3
+ vncipherlast $out4,$out4,$in4
+ mtctr $rounds
+ blr
+ .long 0
+ .byte 0,12,0x14,0,0,0,0,0
+___
+}} }}}
+
+my $consts=1;
+foreach(split("\n",$code)) {
+ s/\`([^\`]*)\`/eval($1)/geo;
+
+ # constants table endian-specific conversion
+ if ($consts && m/\.(long|byte)\s+(.+)\s+(\?[a-z]*)$/o) {
+ my $conv=$3;
+ my @bytes=();
+
+ # convert to endian-agnostic format
+ if ($1 eq "long") {
+ foreach (split(/,\s*/,$2)) {
+ my $l = /^0/?oct:int;
+ push @bytes,($l>>24)&0xff,($l>>16)&0xff,($l>>8)&0xff,$l&0xff;
+ }
+ } else {
+ @bytes = map(/^0/?oct:int,split(/,\s*/,$2));
+ }
+
+ # little-endian conversion
+ if ($flavour =~ /le$/o) {
+ SWITCH: for($conv) {
+ /\?inv/ && do { @bytes=map($_^0xf,@bytes); last; };
+ /\?rev/ && do { @bytes=reverse(@bytes); last; };
+ }
+ }
+
+ #emit
+ print ".byte\t",join(',',map (sprintf("0x%02x",$_),@bytes)),"\n";
+ next;
+ }
+ $consts=0 if (m/Lconsts:/o); # end of table
+
+ # instructions prefixed with '?' are endian-specific and need
+ # to be adjusted accordingly...
+ if ($flavour =~ /le$/o) { # little-endian
+ s/le\?//o or
+ s/be\?/#be#/o or
+ s/\?lvsr/lvsl/o or
+ s/\?lvsl/lvsr/o or
+ s/\?(vperm\s+v[0-9]+,\s*)(v[0-9]+,\s*)(v[0-9]+,\s*)(v[0-9]+)/$1$3$2$4/o or
+ s/\?(vsldoi\s+v[0-9]+,\s*)(v[0-9]+,)\s*(v[0-9]+,\s*)([0-9]+)/$1$3$2 16-$4/o or
+ s/\?(vspltw\s+v[0-9]+,\s*)(v[0-9]+,)\s*([0-9])/$1$2 3-$3/o;
+ } else { # big-endian
+ s/le\?/#le#/o or
+ s/be\?//o or
+ s/\?([a-z]+)/$1/o;
+ }
+
+ print $_,"\n";
+}
+
+close STDOUT;
diff --git a/arch/powerpc/crypto/ghash.c b/arch/powerpc/crypto/ghash.c
new file mode 100644
index 000000000000..77eca20bc7ac
--- /dev/null
+++ b/arch/powerpc/crypto/ghash.c
@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * GHASH routines supporting VMX instructions on the Power 8
+ *
+ * Copyright (C) 2015, 2019 International Business Machines Inc.
+ *
+ * Author: Marcelo Henrique Cerri <mhcerri@br.ibm.com>
+ *
+ * Extended by Daniel Axtens <dja@axtens.net> to replace the fallback
+ * mechanism. The new approach is based on arm64 code, which is:
+ * Copyright (C) 2014 - 2018 Linaro Ltd. <ard.biesheuvel@linaro.org>
+ */
+
+#include <linux/types.h>
+#include <linux/err.h>
+#include <linux/crypto.h>
+#include <linux/delay.h>
+#include <asm/simd.h>
+#include <asm/switch_to.h>
+#include <crypto/aes.h>
+#include <crypto/ghash.h>
+#include <crypto/scatterwalk.h>
+#include <crypto/internal/hash.h>
+#include <crypto/internal/simd.h>
+#include <crypto/b128ops.h>
+#include "aesp8-ppc.h"
+
+void gcm_init_p8(u128 htable[16], const u64 Xi[2]);
+void gcm_gmult_p8(u64 Xi[2], const u128 htable[16]);
+void gcm_ghash_p8(u64 Xi[2], const u128 htable[16],
+ const u8 *in, size_t len);
+
+struct p8_ghash_ctx {
+ /* key used by vector asm */
+ u128 htable[16];
+ /* key used by software fallback */
+ be128 key;
+};
+
+struct p8_ghash_desc_ctx {
+ u64 shash[2];
+ u8 buffer[GHASH_DIGEST_SIZE];
+ int bytes;
+};
+
+static int p8_ghash_init(struct shash_desc *desc)
+{
+ struct p8_ghash_desc_ctx *dctx = shash_desc_ctx(desc);
+
+ dctx->bytes = 0;
+ memset(dctx->shash, 0, GHASH_DIGEST_SIZE);
+ return 0;
+}
+
+static int p8_ghash_setkey(struct crypto_shash *tfm, const u8 *key,
+ unsigned int keylen)
+{
+ struct p8_ghash_ctx *ctx = crypto_tfm_ctx(crypto_shash_tfm(tfm));
+
+ if (keylen != GHASH_BLOCK_SIZE)
+ return -EINVAL;
+
+ preempt_disable();
+ pagefault_disable();
+ enable_kernel_vsx();
+ gcm_init_p8(ctx->htable, (const u64 *) key);
+ disable_kernel_vsx();
+ pagefault_enable();
+ preempt_enable();
+
+ memcpy(&ctx->key, key, GHASH_BLOCK_SIZE);
+
+ return 0;
+}
+
+static inline void __ghash_block(struct p8_ghash_ctx *ctx,
+ struct p8_ghash_desc_ctx *dctx)
+{
+ if (crypto_simd_usable()) {
+ preempt_disable();
+ pagefault_disable();
+ enable_kernel_vsx();
+ gcm_ghash_p8(dctx->shash, ctx->htable,
+ dctx->buffer, GHASH_DIGEST_SIZE);
+ disable_kernel_vsx();
+ pagefault_enable();
+ preempt_enable();
+ } else {
+ crypto_xor((u8 *)dctx->shash, dctx->buffer, GHASH_BLOCK_SIZE);
+ gf128mul_lle((be128 *)dctx->shash, &ctx->key);
+ }
+}
+
+static inline void __ghash_blocks(struct p8_ghash_ctx *ctx,
+ struct p8_ghash_desc_ctx *dctx,
+ const u8 *src, unsigned int srclen)
+{
+ if (crypto_simd_usable()) {
+ preempt_disable();
+ pagefault_disable();
+ enable_kernel_vsx();
+ gcm_ghash_p8(dctx->shash, ctx->htable,
+ src, srclen);
+ disable_kernel_vsx();
+ pagefault_enable();
+ preempt_enable();
+ } else {
+ while (srclen >= GHASH_BLOCK_SIZE) {
+ crypto_xor((u8 *)dctx->shash, src, GHASH_BLOCK_SIZE);
+ gf128mul_lle((be128 *)dctx->shash, &ctx->key);
+ srclen -= GHASH_BLOCK_SIZE;
+ src += GHASH_BLOCK_SIZE;
+ }
+ }
+}
+
+static int p8_ghash_update(struct shash_desc *desc,
+ const u8 *src, unsigned int srclen)
+{
+ unsigned int len;
+ struct p8_ghash_ctx *ctx = crypto_tfm_ctx(crypto_shash_tfm(desc->tfm));
+ struct p8_ghash_desc_ctx *dctx = shash_desc_ctx(desc);
+
+ if (dctx->bytes) {
+ if (dctx->bytes + srclen < GHASH_DIGEST_SIZE) {
+ memcpy(dctx->buffer + dctx->bytes, src,
+ srclen);
+ dctx->bytes += srclen;
+ return 0;
+ }
+ memcpy(dctx->buffer + dctx->bytes, src,
+ GHASH_DIGEST_SIZE - dctx->bytes);
+
+ __ghash_block(ctx, dctx);
+
+ src += GHASH_DIGEST_SIZE - dctx->bytes;
+ srclen -= GHASH_DIGEST_SIZE - dctx->bytes;
+ dctx->bytes = 0;
+ }
+ len = srclen & ~(GHASH_DIGEST_SIZE - 1);
+ if (len) {
+ __ghash_blocks(ctx, dctx, src, len);
+ src += len;
+ srclen -= len;
+ }
+ if (srclen) {
+ memcpy(dctx->buffer, src, srclen);
+ dctx->bytes = srclen;
+ }
+ return 0;
+}
+
+static int p8_ghash_final(struct shash_desc *desc, u8 *out)
+{
+ int i;
+ struct p8_ghash_ctx *ctx = crypto_tfm_ctx(crypto_shash_tfm(desc->tfm));
+ struct p8_ghash_desc_ctx *dctx = shash_desc_ctx(desc);
+
+ if (dctx->bytes) {
+ for (i = dctx->bytes; i < GHASH_DIGEST_SIZE; i++)
+ dctx->buffer[i] = 0;
+ __ghash_block(ctx, dctx);
+ dctx->bytes = 0;
+ }
+ memcpy(out, dctx->shash, GHASH_DIGEST_SIZE);
+ return 0;
+}
+
+struct shash_alg p8_ghash_alg = {
+ .digestsize = GHASH_DIGEST_SIZE,
+ .init = p8_ghash_init,
+ .update = p8_ghash_update,
+ .final = p8_ghash_final,
+ .setkey = p8_ghash_setkey,
+ .descsize = sizeof(struct p8_ghash_desc_ctx)
+ + sizeof(struct ghash_desc_ctx),
+ .base = {
+ .cra_name = "ghash",
+ .cra_driver_name = "p8_ghash",
+ .cra_priority = 1000,
+ .cra_blocksize = GHASH_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct p8_ghash_ctx),
+ .cra_module = THIS_MODULE,
+ },
+};
diff --git a/arch/powerpc/crypto/ghashp8-ppc.pl b/arch/powerpc/crypto/ghashp8-ppc.pl
new file mode 100644
index 000000000000..041e633c214f
--- /dev/null
+++ b/arch/powerpc/crypto/ghashp8-ppc.pl
@@ -0,0 +1,243 @@
+#!/usr/bin/env perl
+# SPDX-License-Identifier: GPL-2.0
+
+# This code is taken from the OpenSSL project but the author (Andy Polyakov)
+# has relicensed it under the GPLv2. 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.
+#
+# The original headers, including the original license headers, are
+# included below for completeness.
+
+# ====================================================================
+# 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/.
+# ====================================================================
+#
+# GHASH for PowerISA v2.07.
+#
+# July 2014
+#
+# Accurate performance measurements are problematic, because it's
+# always virtualized setup with possibly throttled processor.
+# Relative comparison is therefore more informative. This initial
+# version is ~2.1x slower than hardware-assisted AES-128-CTR, ~12x
+# faster than "4-bit" integer-only compiler-generated 64-bit code.
+# "Initial version" means that there is room for futher improvement.
+
+$flavour=shift;
+$output =shift;
+
+if ($flavour =~ /64/) {
+ $SIZE_T=8;
+ $LRSAVE=2*$SIZE_T;
+ $STU="stdu";
+ $POP="ld";
+ $PUSH="std";
+} elsif ($flavour =~ /32/) {
+ $SIZE_T=4;
+ $LRSAVE=$SIZE_T;
+ $STU="stwu";
+ $POP="lwz";
+ $PUSH="stw";
+} else { die "nonsense $flavour"; }
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
+die "can't locate ppc-xlate.pl";
+
+open STDOUT,"| $^X $xlate $flavour $output" || die "can't call $xlate: $!";
+
+my ($Xip,$Htbl,$inp,$len)=map("r$_",(3..6)); # argument block
+
+my ($Xl,$Xm,$Xh,$IN)=map("v$_",(0..3));
+my ($zero,$t0,$t1,$t2,$xC2,$H,$Hh,$Hl,$lemask)=map("v$_",(4..12));
+my $vrsave="r12";
+
+$code=<<___;
+.machine "any"
+
+.text
+
+.globl .gcm_init_p8
+ lis r0,0xfff0
+ li r8,0x10
+ mfspr $vrsave,256
+ li r9,0x20
+ mtspr 256,r0
+ li r10,0x30
+ lvx_u $H,0,r4 # load H
+ le?xor r7,r7,r7
+ le?addi r7,r7,0x8 # need a vperm start with 08
+ le?lvsr 5,0,r7
+ le?vspltisb 6,0x0f
+ le?vxor 5,5,6 # set a b-endian mask
+ le?vperm $H,$H,$H,5
+
+ vspltisb $xC2,-16 # 0xf0
+ vspltisb $t0,1 # one
+ vaddubm $xC2,$xC2,$xC2 # 0xe0
+ vxor $zero,$zero,$zero
+ vor $xC2,$xC2,$t0 # 0xe1
+ vsldoi $xC2,$xC2,$zero,15 # 0xe1...
+ vsldoi $t1,$zero,$t0,1 # ...1
+ vaddubm $xC2,$xC2,$xC2 # 0xc2...
+ vspltisb $t2,7
+ vor $xC2,$xC2,$t1 # 0xc2....01
+ vspltb $t1,$H,0 # most significant byte
+ vsl $H,$H,$t0 # H<<=1
+ vsrab $t1,$t1,$t2 # broadcast carry bit
+ vand $t1,$t1,$xC2
+ vxor $H,$H,$t1 # twisted H
+
+ vsldoi $H,$H,$H,8 # twist even more ...
+ vsldoi $xC2,$zero,$xC2,8 # 0xc2.0
+ vsldoi $Hl,$zero,$H,8 # ... and split
+ vsldoi $Hh,$H,$zero,8
+
+ stvx_u $xC2,0,r3 # save pre-computed table
+ stvx_u $Hl,r8,r3
+ stvx_u $H, r9,r3
+ stvx_u $Hh,r10,r3
+
+ mtspr 256,$vrsave
+ blr
+ .long 0
+ .byte 0,12,0x14,0,0,0,2,0
+ .long 0
+.size .gcm_init_p8,.-.gcm_init_p8
+
+.globl .gcm_gmult_p8
+ lis r0,0xfff8
+ li r8,0x10
+ mfspr $vrsave,256
+ li r9,0x20
+ mtspr 256,r0
+ li r10,0x30
+ lvx_u $IN,0,$Xip # load Xi
+
+ lvx_u $Hl,r8,$Htbl # load pre-computed table
+ le?lvsl $lemask,r0,r0
+ lvx_u $H, r9,$Htbl
+ le?vspltisb $t0,0x07
+ lvx_u $Hh,r10,$Htbl
+ le?vxor $lemask,$lemask,$t0
+ lvx_u $xC2,0,$Htbl
+ le?vperm $IN,$IN,$IN,$lemask
+ vxor $zero,$zero,$zero
+
+ vpmsumd $Xl,$IN,$Hl # H.lo·Xi.lo
+ vpmsumd $Xm,$IN,$H # H.hi·Xi.lo+H.lo·Xi.hi
+ vpmsumd $Xh,$IN,$Hh # H.hi·Xi.hi
+
+ vpmsumd $t2,$Xl,$xC2 # 1st phase
+
+ vsldoi $t0,$Xm,$zero,8
+ vsldoi $t1,$zero,$Xm,8
+ vxor $Xl,$Xl,$t0
+ vxor $Xh,$Xh,$t1
+
+ vsldoi $Xl,$Xl,$Xl,8
+ vxor $Xl,$Xl,$t2
+
+ vsldoi $t1,$Xl,$Xl,8 # 2nd phase
+ vpmsumd $Xl,$Xl,$xC2
+ vxor $t1,$t1,$Xh
+ vxor $Xl,$Xl,$t1
+
+ le?vperm $Xl,$Xl,$Xl,$lemask
+ stvx_u $Xl,0,$Xip # write out Xi
+
+ mtspr 256,$vrsave
+ blr
+ .long 0
+ .byte 0,12,0x14,0,0,0,2,0
+ .long 0
+.size .gcm_gmult_p8,.-.gcm_gmult_p8
+
+.globl .gcm_ghash_p8
+ lis r0,0xfff8
+ li r8,0x10
+ mfspr $vrsave,256
+ li r9,0x20
+ mtspr 256,r0
+ li r10,0x30
+ lvx_u $Xl,0,$Xip # load Xi
+
+ lvx_u $Hl,r8,$Htbl # load pre-computed table
+ le?lvsl $lemask,r0,r0
+ lvx_u $H, r9,$Htbl
+ le?vspltisb $t0,0x07
+ lvx_u $Hh,r10,$Htbl
+ le?vxor $lemask,$lemask,$t0
+ lvx_u $xC2,0,$Htbl
+ le?vperm $Xl,$Xl,$Xl,$lemask
+ vxor $zero,$zero,$zero
+
+ lvx_u $IN,0,$inp
+ addi $inp,$inp,16
+ subi $len,$len,16
+ le?vperm $IN,$IN,$IN,$lemask
+ vxor $IN,$IN,$Xl
+ b Loop
+
+.align 5
+Loop:
+ subic $len,$len,16
+ vpmsumd $Xl,$IN,$Hl # H.lo·Xi.lo
+ subfe. r0,r0,r0 # borrow?-1:0
+ vpmsumd $Xm,$IN,$H # H.hi·Xi.lo+H.lo·Xi.hi
+ and r0,r0,$len
+ vpmsumd $Xh,$IN,$Hh # H.hi·Xi.hi
+ add $inp,$inp,r0
+
+ vpmsumd $t2,$Xl,$xC2 # 1st phase
+
+ vsldoi $t0,$Xm,$zero,8
+ vsldoi $t1,$zero,$Xm,8
+ vxor $Xl,$Xl,$t0
+ vxor $Xh,$Xh,$t1
+
+ vsldoi $Xl,$Xl,$Xl,8
+ vxor $Xl,$Xl,$t2
+ lvx_u $IN,0,$inp
+ addi $inp,$inp,16
+
+ vsldoi $t1,$Xl,$Xl,8 # 2nd phase
+ vpmsumd $Xl,$Xl,$xC2
+ le?vperm $IN,$IN,$IN,$lemask
+ vxor $t1,$t1,$Xh
+ vxor $IN,$IN,$t1
+ vxor $IN,$IN,$Xl
+ beq Loop # did $len-=16 borrow?
+
+ vxor $Xl,$Xl,$t1
+ le?vperm $Xl,$Xl,$Xl,$lemask
+ stvx_u $Xl,0,$Xip # write out Xi
+
+ mtspr 256,$vrsave
+ blr
+ .long 0
+ .byte 0,12,0x14,0,0,0,4,0
+ .long 0
+.size .gcm_ghash_p8,.-.gcm_ghash_p8
+
+.asciz "GHASH for PowerISA 2.07, CRYPTOGAMS by <appro\@openssl.org>"
+.align 2
+___
+
+foreach (split("\n",$code)) {
+ if ($flavour =~ /le$/o) { # little-endian
+ s/le\?//o or
+ s/be\?/#be#/o;
+ } else {
+ s/le\?/#le#/o or
+ s/be\?//o;
+ }
+ print $_,"\n";
+}
+
+close STDOUT; # enforce flush
diff --git a/arch/powerpc/crypto/vmx.c b/arch/powerpc/crypto/vmx.c
new file mode 100644
index 000000000000..7eb713cc87c8
--- /dev/null
+++ b/arch/powerpc/crypto/vmx.c
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Routines supporting VMX instructions on the Power 8
+ *
+ * Copyright (C) 2015 International Business Machines Inc.
+ *
+ * Author: Marcelo Henrique Cerri <mhcerri@br.ibm.com>
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
+#include <linux/err.h>
+#include <linux/cpufeature.h>
+#include <linux/crypto.h>
+#include <asm/cputable.h>
+#include <crypto/internal/hash.h>
+#include <crypto/internal/skcipher.h>
+
+#include "aesp8-ppc.h"
+
+static int __init p8_init(void)
+{
+ int ret;
+
+ ret = crypto_register_shash(&p8_ghash_alg);
+ if (ret)
+ goto err;
+
+ ret = crypto_register_alg(&p8_aes_alg);
+ if (ret)
+ goto err_unregister_ghash;
+
+ ret = crypto_register_skcipher(&p8_aes_cbc_alg);
+ if (ret)
+ goto err_unregister_aes;
+
+ ret = crypto_register_skcipher(&p8_aes_ctr_alg);
+ if (ret)
+ goto err_unregister_aes_cbc;
+
+ ret = crypto_register_skcipher(&p8_aes_xts_alg);
+ if (ret)
+ goto err_unregister_aes_ctr;
+
+ return 0;
+
+err_unregister_aes_ctr:
+ crypto_unregister_skcipher(&p8_aes_ctr_alg);
+err_unregister_aes_cbc:
+ crypto_unregister_skcipher(&p8_aes_cbc_alg);
+err_unregister_aes:
+ crypto_unregister_alg(&p8_aes_alg);
+err_unregister_ghash:
+ crypto_unregister_shash(&p8_ghash_alg);
+err:
+ return ret;
+}
+
+static void __exit p8_exit(void)
+{
+ crypto_unregister_skcipher(&p8_aes_xts_alg);
+ crypto_unregister_skcipher(&p8_aes_ctr_alg);
+ crypto_unregister_skcipher(&p8_aes_cbc_alg);
+ crypto_unregister_alg(&p8_aes_alg);
+ crypto_unregister_shash(&p8_ghash_alg);
+}
+
+module_cpu_feature_match(PPC_MODULE_FEATURE_VEC_CRYPTO, p8_init);
+module_exit(p8_exit);
+
+MODULE_AUTHOR("Marcelo Cerri<mhcerri@br.ibm.com>");
+MODULE_DESCRIPTION("IBM VMX cryptographic acceleration instructions "
+ "support on Power 8");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("1.0.0");
+MODULE_IMPORT_NS(CRYPTO_INTERNAL);
diff --git a/arch/powerpc/include/asm/backlight.h b/arch/powerpc/include/asm/backlight.h
index 1b5eab62ed04..061a910d7492 100644
--- a/arch/powerpc/include/asm/backlight.h
+++ b/arch/powerpc/include/asm/backlight.h
@@ -10,15 +10,14 @@
#define __ASM_POWERPC_BACKLIGHT_H
#ifdef __KERNEL__
-#include <linux/fb.h>
#include <linux/mutex.h>
+struct backlight_device;
+
/* For locking instructions, see the implementation file */
extern struct backlight_device *pmac_backlight;
extern struct mutex pmac_backlight_mutex;
-extern int pmac_backlight_curve_lookup(struct fb_info *info, int value);
-
extern int pmac_has_backlight_type(const char *type);
extern void pmac_backlight_key(int direction);
diff --git a/arch/powerpc/include/asm/book3s/64/hash.h b/arch/powerpc/include/asm/book3s/64/hash.h
index 6e70ae511631..faf3e3b4e4b2 100644
--- a/arch/powerpc/include/asm/book3s/64/hash.h
+++ b/arch/powerpc/include/asm/book3s/64/hash.h
@@ -269,8 +269,6 @@ int hash__create_section_mapping(unsigned long start, unsigned long end,
int nid, pgprot_t prot);
int hash__remove_section_mapping(unsigned long start, unsigned long end);
-void hash__kernel_map_pages(struct page *page, int numpages, int enable);
-
#endif /* !__ASSEMBLY__ */
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_BOOK3S_64_HASH_H */
diff --git a/arch/powerpc/include/asm/book3s/64/pgtable-64k.h b/arch/powerpc/include/asm/book3s/64/pgtable-64k.h
index 2fce3498b000..ced7ee8b42fc 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable-64k.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable-64k.h
@@ -45,9 +45,9 @@ static inline int hugepd_ok(hugepd_t hpd)
/*
* This should never get called
*/
-static inline int get_hugepd_cache_index(int index)
+static __always_inline int get_hugepd_cache_index(int index)
{
- BUG();
+ 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 927d585652bc..fac5615e6bc5 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -1027,16 +1027,6 @@ static inline void vmemmap_remove_mapping(unsigned long start,
}
#endif
-#if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_KFENCE)
-static inline void __kernel_map_pages(struct page *page, int numpages, int enable)
-{
- if (radix_enabled())
- radix__kernel_map_pages(page, numpages, enable);
- else
- hash__kernel_map_pages(page, numpages, enable);
-}
-#endif
-
static inline pte_t pmd_pte(pmd_t pmd)
{
return __pte_raw(pmd_raw(pmd));
@@ -1158,20 +1148,6 @@ pud_hugepage_update(struct mm_struct *mm, unsigned long addr, pud_t *pudp,
}
/*
- * returns true for pmd migration entries, THP, devmap, hugetlb
- * But compile time dependent on THP config
- */
-static inline int pmd_large(pmd_t pmd)
-{
- return !!(pmd_raw(pmd) & cpu_to_be64(_PAGE_PTE));
-}
-
-static inline int pud_large(pud_t pud)
-{
- return !!(pud_raw(pud) & cpu_to_be64(_PAGE_PTE));
-}
-
-/*
* For radix we should always find H_PAGE_HASHPTE zero. Hence
* the below will work for radix too
*/
@@ -1451,18 +1427,16 @@ static inline bool is_pte_rw_upgrade(unsigned long old_val, unsigned long new_va
}
/*
- * Like pmd_huge() and pmd_large(), but works regardless of config options
+ * Like pmd_huge(), but works regardless of config options
*/
-#define pmd_is_leaf pmd_is_leaf
-#define pmd_leaf pmd_is_leaf
-static inline bool pmd_is_leaf(pmd_t pmd)
+#define pmd_leaf pmd_leaf
+static inline bool pmd_leaf(pmd_t pmd)
{
return !!(pmd_raw(pmd) & cpu_to_be64(_PAGE_PTE));
}
-#define pud_is_leaf pud_is_leaf
-#define pud_leaf pud_is_leaf
-static inline bool pud_is_leaf(pud_t pud)
+#define pud_leaf pud_leaf
+static inline bool pud_leaf(pud_t pud)
{
return !!(pud_raw(pud) & cpu_to_be64(_PAGE_PTE));
}
diff --git a/arch/powerpc/include/asm/book3s/64/radix.h b/arch/powerpc/include/asm/book3s/64/radix.h
index 357e23a403d3..8f55ff74bb68 100644
--- a/arch/powerpc/include/asm/book3s/64/radix.h
+++ b/arch/powerpc/include/asm/book3s/64/radix.h
@@ -362,8 +362,6 @@ int radix__create_section_mapping(unsigned long start, unsigned long end,
int radix__remove_section_mapping(unsigned long start, unsigned long end);
#endif /* CONFIG_MEMORY_HOTPLUG */
-void radix__kernel_map_pages(struct page *page, int numpages, int enable);
-
#ifdef CONFIG_ARCH_WANT_OPTIMIZE_DAX_VMEMMAP
#define vmemmap_can_optimize vmemmap_can_optimize
bool vmemmap_can_optimize(struct vmem_altmap *altmap, struct dev_pagemap *pgmap);
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index 8765d5158324..07a204d21034 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -454,6 +454,9 @@ static inline void cpu_feature_keys_init(void) { }
CPU_FTR_ARCH_300 | CPU_FTR_ARCH_31 | \
CPU_FTR_DAWR | CPU_FTR_DAWR1 | \
CPU_FTR_DEXCR_NPHIE)
+
+#define CPU_FTRS_POWER11 CPU_FTRS_POWER10
+
#define CPU_FTRS_CELL (CPU_FTR_LWSYNC | \
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
@@ -542,19 +545,20 @@ enum {
#define CPU_FTRS_DT_CPU_BASE (~0ul)
#endif
+/* pseries may disable DBELL with ibm,pi-features */
#ifdef CONFIG_CPU_LITTLE_ENDIAN
#define CPU_FTRS_ALWAYS \
- (CPU_FTRS_POSSIBLE & ~CPU_FTR_HVMODE & CPU_FTRS_POWER7 & \
- CPU_FTRS_POWER8E & CPU_FTRS_POWER8 & CPU_FTRS_POWER9 & \
- CPU_FTRS_POWER9_DD2_1 & CPU_FTRS_POWER9_DD2_2 & \
+ (CPU_FTRS_POSSIBLE & ~CPU_FTR_HVMODE & ~CPU_FTR_DBELL & \
+ CPU_FTRS_POWER7 & CPU_FTRS_POWER8E & CPU_FTRS_POWER8 & \
+ CPU_FTRS_POWER9 & CPU_FTRS_POWER9_DD2_1 & CPU_FTRS_POWER9_DD2_2 & \
CPU_FTRS_POWER10 & CPU_FTRS_DT_CPU_BASE)
#else
#define CPU_FTRS_ALWAYS \
(CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & \
CPU_FTRS_POWER6 & CPU_FTRS_POWER7 & CPU_FTRS_CELL & \
CPU_FTRS_PA6T & CPU_FTRS_POWER8 & CPU_FTRS_POWER8E & \
- ~CPU_FTR_HVMODE & CPU_FTRS_POSSIBLE & CPU_FTRS_POWER9 & \
- CPU_FTRS_POWER9_DD2_1 & CPU_FTRS_POWER9_DD2_2 & \
+ ~CPU_FTR_HVMODE & ~CPU_FTR_DBELL & CPU_FTRS_POSSIBLE & \
+ CPU_FTRS_POWER9 & CPU_FTRS_POWER9_DD2_1 & CPU_FTRS_POWER9_DD2_2 & \
CPU_FTRS_POWER10 & CPU_FTRS_DT_CPU_BASE)
#endif /* CONFIG_CPU_LITTLE_ENDIAN */
#endif
diff --git a/arch/powerpc/include/asm/ibmebus.h b/arch/powerpc/include/asm/ibmebus.h
index 6f33253a364a..46fe406f461c 100644
--- a/arch/powerpc/include/asm/ibmebus.h
+++ b/arch/powerpc/include/asm/ibmebus.h
@@ -48,7 +48,7 @@
struct platform_driver;
-extern struct bus_type ibmebus_bus_type;
+extern const struct bus_type ibmebus_bus_type;
int ibmebus_register_driver(struct platform_driver *drv);
void ibmebus_unregister_driver(struct platform_driver *drv);
diff --git a/arch/powerpc/include/asm/interrupt.h b/arch/powerpc/include/asm/interrupt.h
index a4196ab1d016..7b610864b364 100644
--- a/arch/powerpc/include/asm/interrupt.h
+++ b/arch/powerpc/include/asm/interrupt.h
@@ -97,7 +97,7 @@ DECLARE_STATIC_KEY_FALSE(interrupt_exit_not_reentrant);
static inline bool is_implicit_soft_masked(struct pt_regs *regs)
{
- if (regs->msr & MSR_PR)
+ if (user_mode(regs))
return false;
if (regs->nip >= (unsigned long)__end_soft_masked)
diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h
index e1b43aa12175..fdb90e24dc74 100644
--- a/arch/powerpc/include/asm/kexec.h
+++ b/arch/powerpc/include/asm/kexec.h
@@ -55,59 +55,18 @@
typedef void (*crash_shutdown_t)(void);
#ifdef CONFIG_KEXEC_CORE
-
-/*
- * This function is responsible for capturing register states if coming
- * via panic or invoking dump using sysrq-trigger.
- */
-static inline void crash_setup_regs(struct pt_regs *newregs,
- struct pt_regs *oldregs)
-{
- if (oldregs)
- memcpy(newregs, oldregs, sizeof(*newregs));
- else
- ppc_save_regs(newregs);
-}
+struct kimage;
+struct pt_regs;
extern void kexec_smp_wait(void); /* get and clear naca physid, wait for
master to copy new code to 0 */
-extern int crashing_cpu;
-extern void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *));
-extern void crash_ipi_callback(struct pt_regs *);
-extern int crash_wake_offline;
-
-struct kimage;
-struct pt_regs;
extern void default_machine_kexec(struct kimage *image);
-extern void default_machine_crash_shutdown(struct pt_regs *regs);
-extern int crash_shutdown_register(crash_shutdown_t handler);
-extern int crash_shutdown_unregister(crash_shutdown_t handler);
-
-extern void crash_kexec_prepare(void);
-extern void crash_kexec_secondary(struct pt_regs *regs);
-int __init overlaps_crashkernel(unsigned long start, unsigned long size);
-extern void reserve_crashkernel(void);
extern void machine_kexec_mask_interrupts(void);
-static inline bool kdump_in_progress(void)
-{
- return crashing_cpu >= 0;
-}
-
void relocate_new_kernel(unsigned long indirection_page, unsigned long reboot_code_buffer,
unsigned long start_address) __noreturn;
-
void kexec_copy_flush(struct kimage *image);
-#if defined(CONFIG_CRASH_DUMP)
-bool is_kdump_kernel(void);
-#define is_kdump_kernel is_kdump_kernel
-#if defined(CONFIG_PPC_RTAS)
-void crash_free_reserved_phys_range(unsigned long begin, unsigned long end);
-#define crash_free_reserved_phys_range crash_free_reserved_phys_range
-#endif /* CONFIG_PPC_RTAS */
-#endif /* CONFIG_CRASH_DUMP */
-
#ifdef CONFIG_KEXEC_FILE
extern const struct kexec_file_ops kexec_elf64_ops;
@@ -152,15 +111,56 @@ int setup_new_fdt_ppc64(const struct kimage *image, void *fdt,
#endif /* CONFIG_KEXEC_FILE */
-#else /* !CONFIG_KEXEC_CORE */
-static inline void crash_kexec_secondary(struct pt_regs *regs) { }
+#endif /* CONFIG_KEXEC_CORE */
+
+#ifdef CONFIG_CRASH_RESERVE
+int __init overlaps_crashkernel(unsigned long start, unsigned long size);
+extern void reserve_crashkernel(void);
+#else
+static inline void reserve_crashkernel(void) {}
+static inline int overlaps_crashkernel(unsigned long start, unsigned long size) { return 0; }
+#endif
-static inline int overlaps_crashkernel(unsigned long start, unsigned long size)
+#if defined(CONFIG_CRASH_DUMP)
+/*
+ * This function is responsible for capturing register states if coming
+ * via panic or invoking dump using sysrq-trigger.
+ */
+static inline void crash_setup_regs(struct pt_regs *newregs,
+ struct pt_regs *oldregs)
{
- return 0;
+ if (oldregs)
+ memcpy(newregs, oldregs, sizeof(*newregs));
+ else
+ ppc_save_regs(newregs);
+}
+
+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);
+extern int crash_wake_offline;
+
+extern int crash_shutdown_register(crash_shutdown_t handler);
+extern int crash_shutdown_unregister(crash_shutdown_t handler);
+extern void default_machine_crash_shutdown(struct pt_regs *regs);
+
+extern void crash_kexec_prepare(void);
+extern void crash_kexec_secondary(struct pt_regs *regs);
+
+static inline bool kdump_in_progress(void)
+{
+ return crashing_cpu >= 0;
}
-static inline void reserve_crashkernel(void) { ; }
+bool is_kdump_kernel(void);
+#define is_kdump_kernel is_kdump_kernel
+#if defined(CONFIG_PPC_RTAS)
+void crash_free_reserved_phys_range(unsigned long begin, unsigned long end);
+#define crash_free_reserved_phys_range crash_free_reserved_phys_range
+#endif /* CONFIG_PPC_RTAS */
+
+#else /* !CONFIG_CRASH_DUMP */
+static inline void crash_kexec_secondary(struct pt_regs *regs) { }
static inline int crash_shutdown_register(crash_shutdown_t handler)
{
@@ -183,7 +183,7 @@ static inline void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *))
{
}
-#endif /* CONFIG_KEXEC_CORE */
+#endif /* CONFIG_CRASH_DUMP */
#ifdef CONFIG_PPC_BOOK3S_64
#include <asm/book3s/64/kexec.h>
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index d31a5ec1550d..1862f94335ee 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -22,6 +22,7 @@ struct pci_host_bridge;
struct machdep_calls {
const char *name;
const char *compatible;
+ const char * const *compatibles;
#ifdef CONFIG_PPC64
#ifdef CONFIG_PM
void (*iommu_restore)(void);
diff --git a/arch/powerpc/include/asm/macio.h b/arch/powerpc/include/asm/macio.h
index 3a07c62973aa..9203ff6acbf6 100644
--- a/arch/powerpc/include/asm/macio.h
+++ b/arch/powerpc/include/asm/macio.h
@@ -6,7 +6,7 @@
#include <linux/of.h>
#include <linux/platform_device.h>
-extern struct bus_type macio_bus_type;
+extern const struct bus_type macio_bus_type;
/* MacIO device driver is defined later */
struct macio_driver;
@@ -126,7 +126,7 @@ static inline struct pci_dev *macio_get_pci_dev(struct macio_dev *mdev)
struct macio_driver
{
int (*probe)(struct macio_dev* dev, const struct of_device_id *match);
- int (*remove)(struct macio_dev* dev);
+ void (*remove)(struct macio_dev *dev);
int (*suspend)(struct macio_dev* dev, pm_message_t state);
int (*resume)(struct macio_dev* dev);
diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
index d8b7e246a32f..3b72c7ed24cf 100644
--- a/arch/powerpc/include/asm/mmu.h
+++ b/arch/powerpc/include/asm/mmu.h
@@ -133,6 +133,7 @@
#define MMU_FTRS_POWER8 MMU_FTRS_POWER6
#define MMU_FTRS_POWER9 MMU_FTRS_POWER6
#define MMU_FTRS_POWER10 MMU_FTRS_POWER6
+#define MMU_FTRS_POWER11 MMU_FTRS_POWER6
#define MMU_FTRS_CELL MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \
MMU_FTR_CI_LARGE_PAGE
#define MMU_FTRS_PA6T MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \
@@ -330,17 +331,10 @@ static __always_inline bool early_radix_enabled(void)
return early_mmu_has_feature(MMU_FTR_TYPE_RADIX);
}
-#ifdef CONFIG_STRICT_KERNEL_RWX
static inline bool strict_kernel_rwx_enabled(void)
{
- return rodata_enabled;
+ return IS_ENABLED(CONFIG_STRICT_KERNEL_RWX) && rodata_enabled;
}
-#else
-static inline bool strict_kernel_rwx_enabled(void)
-{
- return false;
-}
-#endif
static inline bool strict_module_rwx_enabled(void)
{
diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h
index 58353c5bd3fb..0c03a98986cd 100644
--- a/arch/powerpc/include/asm/mpic.h
+++ b/arch/powerpc/include/asm/mpic.h
@@ -336,7 +336,7 @@ struct mpic
#endif
};
-extern struct bus_type mpic_subsys;
+extern const struct bus_type mpic_subsys;
/*
* MPIC flags (passed to mpic_alloc)
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
index e667d455ecb4..1d58da946739 100644
--- a/arch/powerpc/include/asm/paca.h
+++ b/arch/powerpc/include/asm/paca.h
@@ -163,9 +163,7 @@ struct paca_struct {
u64 kstack; /* Saved Kernel stack addr */
u64 saved_r1; /* r1 save for RTAS calls or PM or EE=0 */
u64 saved_msr; /* MSR saved here by enter_rtas */
-#ifdef CONFIG_PPC64
u64 exit_save_r1; /* Syscall/interrupt R1 save */
-#endif
#ifdef CONFIG_PPC_BOOK3E_64
u16 trap_save; /* Used when bad stack is encountered */
#endif
@@ -214,8 +212,6 @@ struct paca_struct {
/* Non-maskable exceptions that are not performance critical */
u64 exnmi[EX_SIZE]; /* used for system reset (nmi) */
u64 exmc[EX_SIZE]; /* used for machine checks */
-#endif
-#ifdef CONFIG_PPC_BOOK3S_64
/* Exclusive stacks for system reset and machine check exception. */
void *nmi_emergency_sp;
void *mc_emergency_sp;
diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
index e5fcc79b5bfb..e411e5a70ea3 100644
--- a/arch/powerpc/include/asm/page.h
+++ b/arch/powerpc/include/asm/page.h
@@ -21,7 +21,7 @@
* page size. When using 64K pages however, whether we are really supporting
* 64K pages in HW or not is irrelevant to those definitions.
*/
-#define PAGE_SHIFT CONFIG_PPC_PAGE_SHIFT
+#define PAGE_SHIFT CONFIG_PAGE_SHIFT
#define PAGE_SIZE (ASM_CONST(1) << PAGE_SHIFT)
#ifndef __ASSEMBLY__
diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h
index 9224f23065ff..239709a2f68e 100644
--- a/arch/powerpc/include/asm/pgtable.h
+++ b/arch/powerpc/include/asm/pgtable.h
@@ -41,6 +41,8 @@ struct mm_struct;
#ifndef __ASSEMBLY__
+#define PFN_PTE_SHIFT PTE_RPN_SHIFT
+
void set_ptes(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
pte_t pte, unsigned int nr);
#define set_ptes set_ptes
@@ -99,10 +101,6 @@ void poking_init(void);
extern unsigned long ioremap_bot;
extern const pgprot_t protection_map[16];
-#ifndef CONFIG_TRANSPARENT_HUGEPAGE
-#define pmd_large(pmd) 0
-#endif
-
/* can we use this in kvm */
unsigned long vmalloc_to_phys(void *vmalloc_addr);
@@ -180,30 +178,6 @@ static inline void pte_frag_set(mm_context_t *ctx, void *p)
}
#endif
-#ifndef pmd_is_leaf
-#define pmd_is_leaf pmd_is_leaf
-static inline bool pmd_is_leaf(pmd_t pmd)
-{
- return false;
-}
-#endif
-
-#ifndef pud_is_leaf
-#define pud_is_leaf pud_is_leaf
-static inline bool pud_is_leaf(pud_t pud)
-{
- return false;
-}
-#endif
-
-#ifndef p4d_is_leaf
-#define p4d_is_leaf p4d_is_leaf
-static inline bool p4d_is_leaf(p4d_t p4d)
-{
- return false;
-}
-#endif
-
#define pmd_pgtable pmd_pgtable
static inline pgtable_t pmd_pgtable(pmd_t pmd)
{
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h
index e7792aa13510..1d1018c1e482 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -201,11 +201,13 @@
#ifdef CONFIG_PPC64_ELF_ABI_V2
#define STK_GOT 24
-#define __STK_PARAM(i) (32 + ((i)-3)*8)
+#define STK_PARAM_AREA 32
#else
#define STK_GOT 40
-#define __STK_PARAM(i) (48 + ((i)-3)*8)
+#define STK_PARAM_AREA 48
#endif
+
+#define __STK_PARAM(i) (STK_PARAM_AREA + ((i)-3)*8)
#define STK_PARAM(i) __STK_PARAM(__REG_##i)
#ifdef CONFIG_PPC64_ELF_ABI_V2
@@ -506,7 +508,25 @@ END_FTR_SECTION_NESTED(CPU_FTR_CELL_TB_BUG, CPU_FTR_CELL_TB_BUG, 96)
*/
#define DCBT_BOOK3S_STOP_ALL_STREAM_IDS(scratch) \
lis scratch,0x60000000@h; \
- dcbt 0,scratch,0b01010
+ .machine push; \
+ .machine power4; \
+ dcbt 0,scratch,0b01010; \
+ .machine pop;
+
+#define DCBT_SETUP_STREAMS(from, from_parms, to, to_parms, scratch) \
+ lis scratch,0x8000; /* GO=1 */ \
+ clrldi scratch,scratch,32; \
+ .machine push; \
+ .machine power4; \
+ /* setup read stream 0 */ \
+ dcbt 0,from,0b01000; /* addr from */ \
+ dcbt 0,from_parms,0b01010; /* length and depth from */ \
+ /* setup write stream 1 */ \
+ dcbtst 0,to,0b01000; /* addr to */ \
+ dcbtst 0,to_parms,0b01010; /* length and depth to */ \
+ eieio; \
+ dcbt 0,scratch,0b01010; /* all streams GO */ \
+ .machine pop;
/*
* toreal/fromreal/tophys/tovirt macros. 32-bit BookE makes them
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index bb47af9054a9..d3d1aea009b4 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -1366,6 +1366,7 @@
#define PVR_HX_C2000 0x0066
#define PVR_POWER9 0x004E
#define PVR_POWER10 0x0080
+#define PVR_POWER11 0x0082
#define PVR_BE 0x0070
#define PVR_PA6T 0x0090
@@ -1377,6 +1378,7 @@
#define PVR_ARCH_207 0x0f000004
#define PVR_ARCH_300 0x0f000005
#define PVR_ARCH_31 0x0f000006
+#define PVR_ARCH_31_P11 0x0f000007
/* Macros for setting and retrieving special purpose registers */
#ifndef __ASSEMBLY__
diff --git a/arch/powerpc/include/asm/reg_fsl_emb.h b/arch/powerpc/include/asm/reg_fsl_emb.h
index a21f529c43d9..9893d2001b68 100644
--- a/arch/powerpc/include/asm/reg_fsl_emb.h
+++ b/arch/powerpc/include/asm/reg_fsl_emb.h
@@ -11,10 +11,27 @@
#ifndef __ASSEMBLY__
/* Performance Monitor Registers */
-#define mfpmr(rn) ({unsigned int rval; \
- asm volatile("mfpmr %0," __stringify(rn) \
- : "=r" (rval)); rval;})
-#define mtpmr(rn, v) asm volatile("mtpmr " __stringify(rn) ",%0" : : "r" (v))
+static __always_inline unsigned int mfpmr(unsigned int rn)
+{
+ unsigned int rval;
+
+ asm (".machine push; "
+ ".machine e300; "
+ "mfpmr %[rval], %[rn];"
+ ".machine pop;"
+ : [rval] "=r" (rval) : [rn] "i" (rn));
+
+ return rval;
+}
+
+static __always_inline void mtpmr(unsigned int rn, unsigned int val)
+{
+ asm (".machine push; "
+ ".machine e300; "
+ "mtpmr %[rn], %[val];"
+ ".machine pop;"
+ : [val] "=r" (val) : [rn] "i" (rn));
+}
#endif /* __ASSEMBLY__ */
/* Freescale Book E Performance Monitor APU Registers */
diff --git a/arch/powerpc/include/asm/set_memory.h b/arch/powerpc/include/asm/set_memory.h
index 7ebc807aa8cc..9a025b776a4b 100644
--- a/arch/powerpc/include/asm/set_memory.h
+++ b/arch/powerpc/include/asm/set_memory.h
@@ -8,6 +8,7 @@
#define SET_MEMORY_X 3
#define SET_MEMORY_NP 4 /* Set memory non present */
#define SET_MEMORY_P 5 /* Set memory present */
+#define SET_MEMORY_ROX 6
int change_memory_attr(unsigned long addr, int numpages, long action);
@@ -41,4 +42,10 @@ static inline int set_memory_p(unsigned long addr, int numpages)
return change_memory_attr(addr, numpages, SET_MEMORY_P);
}
+static inline int set_memory_rox(unsigned long addr, int numpages)
+{
+ return change_memory_attr(addr, numpages, SET_MEMORY_ROX);
+}
+#define set_memory_rox set_memory_rox
+
#endif
diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
index aaaa576d0e15..b77927ccb0ab 100644
--- a/arch/powerpc/include/asm/smp.h
+++ b/arch/powerpc/include/asm/smp.h
@@ -27,6 +27,7 @@
extern int boot_cpuid;
extern int boot_cpu_hwid; /* PPC64 only */
+extern int boot_core_hwid;
extern int spinning_secondaries;
extern u32 *cpu_to_phys_id;
extern bool coregroup_enabled;
diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h
index aee25e3ebf96..fc933807ddc8 100644
--- a/arch/powerpc/include/asm/switch_to.h
+++ b/arch/powerpc/include/asm/switch_to.h
@@ -48,6 +48,10 @@ static inline void disable_kernel_fp(void)
#else
static inline void save_fpu(struct task_struct *t) { }
static inline void flush_fp_to_thread(struct task_struct *t) { }
+static inline void enable_kernel_fp(void)
+{
+ BUILD_BUG();
+}
#endif
#ifdef CONFIG_ALTIVEC
diff --git a/arch/powerpc/include/asm/tlb.h b/arch/powerpc/include/asm/tlb.h
index b3de6102a907..1ca7d4c4b90d 100644
--- a/arch/powerpc/include/asm/tlb.h
+++ b/arch/powerpc/include/asm/tlb.h
@@ -19,6 +19,8 @@
#include <linux/pagemap.h>
+static inline void __tlb_remove_tlb_entry(struct mmu_gather *tlb, pte_t *ptep,
+ unsigned long address);
#define __tlb_remove_tlb_entry __tlb_remove_tlb_entry
#define tlb_flush tlb_flush
diff --git a/arch/powerpc/include/asm/trace.h b/arch/powerpc/include/asm/trace.h
index 82cc2c6704e6..d9ac3a4f46e1 100644
--- a/arch/powerpc/include/asm/trace.h
+++ b/arch/powerpc/include/asm/trace.h
@@ -267,6 +267,7 @@ TRACE_EVENT_FN(opal_exit,
);
#endif
+#ifdef CONFIG_PPC_64S_HASH_MMU
TRACE_EVENT(hash_fault,
TP_PROTO(unsigned long addr, unsigned long access, unsigned long trap),
@@ -286,7 +287,7 @@ TRACE_EVENT(hash_fault,
TP_printk("hash fault with addr 0x%lx and access = 0x%lx trap = 0x%lx",
__entry->addr, __entry->access, __entry->trap)
);
-
+#endif
TRACE_EVENT(tlbie,
diff --git a/arch/powerpc/include/asm/vdso/gettimeofday.h b/arch/powerpc/include/asm/vdso/gettimeofday.h
index f0a4cf01e85c..78302f6c2580 100644
--- a/arch/powerpc/include/asm/vdso/gettimeofday.h
+++ b/arch/powerpc/include/asm/vdso/gettimeofday.h
@@ -4,7 +4,6 @@
#ifndef __ASSEMBLY__
-#include <asm/page.h>
#include <asm/vdso/timebase.h>
#include <asm/barrier.h>
#include <asm/unistd.h>
@@ -95,7 +94,7 @@ const struct vdso_data *__arch_get_vdso_data(void);
static __always_inline
const struct vdso_data *__arch_get_timens_vdso_data(const struct vdso_data *vd)
{
- return (void *)vd + PAGE_SIZE;
+ return (void *)vd + (1U << CONFIG_PAGE_SHIFT);
}
#endif
diff --git a/arch/powerpc/include/asm/vio.h b/arch/powerpc/include/asm/vio.h
index cc9b787627ad..6faf2a931755 100644
--- a/arch/powerpc/include/asm/vio.h
+++ b/arch/powerpc/include/asm/vio.h
@@ -39,7 +39,7 @@
*/
#define VIO_CMO_MIN_ENT 1562624
-extern struct bus_type vio_bus_type;
+extern const struct bus_type vio_bus_type;
struct iommu_table;
diff --git a/arch/powerpc/include/asm/vmalloc.h b/arch/powerpc/include/asm/vmalloc.h
index 4c69ece52a31..59ed89890c90 100644
--- a/arch/powerpc/include/asm/vmalloc.h
+++ b/arch/powerpc/include/asm/vmalloc.h
@@ -7,14 +7,14 @@
#ifdef CONFIG_HAVE_ARCH_HUGE_VMAP
#define arch_vmap_pud_supported arch_vmap_pud_supported
-static inline bool arch_vmap_pud_supported(pgprot_t prot)
+static __always_inline bool arch_vmap_pud_supported(pgprot_t prot)
{
/* HPT does not cope with large pages in the vmalloc area */
return radix_enabled();
}
#define arch_vmap_pmd_supported arch_vmap_pmd_supported
-static inline bool arch_vmap_pmd_supported(pgprot_t prot)
+static __always_inline bool arch_vmap_pmd_supported(pgprot_t prot)
{
return radix_enabled();
}
diff --git a/arch/powerpc/include/asm/word-at-a-time.h b/arch/powerpc/include/asm/word-at-a-time.h
index 30a12d208687..54653a863414 100644
--- a/arch/powerpc/include/asm/word-at-a-time.h
+++ b/arch/powerpc/include/asm/word-at-a-time.h
@@ -4,8 +4,8 @@
/*
* Word-at-a-time interfaces for PowerPC.
*/
-
-#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/wordpart.h>
#include <asm/asm-compat.h>
#include <asm/extable.h>
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index 9f18fa090f1f..1691297a766a 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -28,7 +28,6 @@
#define __KVM_HAVE_PPC_SMT
#define __KVM_HAVE_IRQCHIP
#define __KVM_HAVE_IRQ_LINE
-#define __KVM_HAVE_GUEST_DEBUG
/* Not always available, but if it is, this is the correct offset. */
#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
@@ -733,4 +732,48 @@ struct kvm_ppc_xive_eq {
#define KVM_XIVE_TIMA_PAGE_OFFSET 0
#define KVM_XIVE_ESB_PAGE_OFFSET 4
+/* for KVM_PPC_GET_PVINFO */
+
+#define KVM_PPC_PVINFO_FLAGS_EV_IDLE (1<<0)
+
+struct kvm_ppc_pvinfo {
+ /* out */
+ __u32 flags;
+ __u32 hcall[4];
+ __u8 pad[108];
+};
+
+/* for KVM_PPC_GET_SMMU_INFO */
+#define KVM_PPC_PAGE_SIZES_MAX_SZ 8
+
+struct kvm_ppc_one_page_size {
+ __u32 page_shift; /* Page shift (or 0) */
+ __u32 pte_enc; /* Encoding in the HPTE (>>12) */
+};
+
+struct kvm_ppc_one_seg_page_size {
+ __u32 page_shift; /* Base page shift of segment (or 0) */
+ __u32 slb_enc; /* SLB encoding for BookS */
+ struct kvm_ppc_one_page_size enc[KVM_PPC_PAGE_SIZES_MAX_SZ];
+};
+
+#define KVM_PPC_PAGE_SIZES_REAL 0x00000001
+#define KVM_PPC_1T_SEGMENTS 0x00000002
+#define KVM_PPC_NO_HASH 0x00000004
+
+struct kvm_ppc_smmu_info {
+ __u64 flags;
+ __u32 slb_size;
+ __u16 data_keys; /* # storage keys supported for data */
+ __u16 instr_keys; /* # storage keys supported for instructions */
+ struct kvm_ppc_one_seg_page_size sps[KVM_PPC_PAGE_SIZES_MAX_SZ];
+};
+
+/* for KVM_PPC_RESIZE_HPT_{PREPARE,COMMIT} */
+struct kvm_ppc_resize_hpt {
+ __u64 flags;
+ __u32 shift;
+ __u32 pad;
+};
+
#endif /* __LINUX_KVM_POWERPC_H */
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 2919433be355..d3282fbea4f2 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -55,7 +55,6 @@ CFLAGS_btext.o += -DDISABLE_BRANCH_PROFILING
endif
KCSAN_SANITIZE_early_32.o := n
-KCSAN_SANITIZE_early_64.o := n
KCSAN_SANITIZE_cputable.o := n
KCSAN_SANITIZE_btext.o := n
KCSAN_SANITIZE_paca.o := n
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 9f14d95b8b32..f029755f9e69 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -246,9 +246,7 @@ int main(void)
OFFSET(PACAHWCPUID, paca_struct, hw_cpu_id);
OFFSET(PACAKEXECSTATE, paca_struct, kexec_state);
OFFSET(PACA_DSCR_DEFAULT, paca_struct, dscr_default);
-#ifdef CONFIG_PPC64
OFFSET(PACA_EXIT_SAVE_R1, paca_struct, exit_save_r1);
-#endif
#ifdef CONFIG_PPC_BOOK3E_64
OFFSET(PACA_TRAP_SAVE, paca_struct, trap_save);
#endif
diff --git a/arch/powerpc/kernel/cpu_specs_book3s_64.h b/arch/powerpc/kernel/cpu_specs_book3s_64.h
index 3ff9757df4c0..98d4274a1b6b 100644
--- a/arch/powerpc/kernel/cpu_specs_book3s_64.h
+++ b/arch/powerpc/kernel/cpu_specs_book3s_64.h
@@ -60,6 +60,9 @@
PPC_FEATURE2_ISEL | PPC_FEATURE2_TAR | \
PPC_FEATURE2_VEC_CRYPTO)
+#define COMMON_USER_POWER11 COMMON_USER_POWER10
+#define COMMON_USER2_POWER11 COMMON_USER2_POWER10
+
static struct cpu_spec cpu_specs[] __initdata = {
{ /* PPC970 */
.pvr_mask = 0xffff0000,
@@ -281,6 +284,20 @@ static struct cpu_spec cpu_specs[] __initdata = {
.cpu_restore = __restore_cpu_power10,
.platform = "power10",
},
+ { /* 3.1-compliant processor, i.e. Power11 "architected" mode */
+ .pvr_mask = 0xffffffff,
+ .pvr_value = 0x0f000007,
+ .cpu_name = "Power11 (architected)",
+ .cpu_features = CPU_FTRS_POWER11,
+ .cpu_user_features = COMMON_USER_POWER11,
+ .cpu_user_features2 = COMMON_USER2_POWER11,
+ .mmu_features = MMU_FTRS_POWER11,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .cpu_setup = __setup_cpu_power10,
+ .cpu_restore = __restore_cpu_power10,
+ .platform = "power11",
+ },
{ /* Power7 */
.pvr_mask = 0xffff0000,
.pvr_value = 0x003f0000,
@@ -451,6 +468,23 @@ static struct cpu_spec cpu_specs[] __initdata = {
.machine_check_early = __machine_check_early_realmode_p10,
.platform = "power10",
},
+ { /* Power11 */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x00820000,
+ .cpu_name = "Power11 (raw)",
+ .cpu_features = CPU_FTRS_POWER11,
+ .cpu_user_features = COMMON_USER_POWER11,
+ .cpu_user_features2 = COMMON_USER2_POWER11,
+ .mmu_features = MMU_FTRS_POWER11,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 6,
+ .pmc_type = PPC_PMC_IBM,
+ .cpu_setup = __setup_cpu_power10,
+ .cpu_restore = __restore_cpu_power10,
+ .machine_check_early = __machine_check_early_realmode_p10,
+ .platform = "power11",
+ },
{ /* Cell Broadband Engine */
.pvr_mask = 0xffff0000,
.pvr_value = 0x00700000,
diff --git a/arch/powerpc/kernel/dt_cpu_ftrs.c b/arch/powerpc/kernel/dt_cpu_ftrs.c
index c3fb9fdf5bd7..af4263594eb2 100644
--- a/arch/powerpc/kernel/dt_cpu_ftrs.c
+++ b/arch/powerpc/kernel/dt_cpu_ftrs.c
@@ -458,6 +458,14 @@ static int __init feat_enable_mce_power10(struct dt_cpu_feature *f)
return 1;
}
+static int __init feat_enable_mce_power11(struct dt_cpu_feature *f)
+{
+ cur_cpu_spec->platform = "power11";
+ cur_cpu_spec->machine_check_early = __machine_check_early_realmode_p10;
+
+ return 1;
+}
+
static int __init feat_enable_tm(struct dt_cpu_feature *f)
{
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
@@ -648,8 +656,10 @@ static struct dt_cpu_feature_match __initdata
{"pc-relative-addressing", feat_enable, 0},
{"machine-check-power9", feat_enable_mce_power9, 0},
{"machine-check-power10", feat_enable_mce_power10, 0},
+ {"machine-check-power11", feat_enable_mce_power11, 0},
{"performance-monitor-power9", feat_enable_pmu_power9, 0},
{"performance-monitor-power10", feat_enable_pmu_power10, 0},
+ {"performance-monitor-power11", feat_enable_pmu_power10, 0},
{"event-based-branch-v3", feat_enable, 0},
{"random-number-generator", feat_enable, 0},
{"system-call-vectored", feat_disable, 0},
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 6f7d4edaa0bc..7504ceec5c58 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -284,15 +284,14 @@ static __always_inline void call_do_irq(struct pt_regs *regs, void *sp)
void __do_IRQ(struct pt_regs *regs)
{
struct pt_regs *old_regs = set_irq_regs(regs);
- void *cursp, *irqsp, *sirqsp;
+ void *cursp, *irqsp;
/* Switch to the irq stack to handle this */
cursp = (void *)(current_stack_pointer & ~(THREAD_SIZE - 1));
irqsp = hardirq_ctx[raw_smp_processor_id()];
- sirqsp = softirq_ctx[raw_smp_processor_id()];
/* Already there ? If not switch stack and call */
- if (unlikely(cursp == irqsp || cursp == sirqsp))
+ if (unlikely(cursp == irqsp))
__do_irq(regs, current_stack_pointer);
else
call_do_irq(regs, irqsp);
diff --git a/arch/powerpc/kernel/isa-bridge.c b/arch/powerpc/kernel/isa-bridge.c
index 48e0eaf1ad61..5c064485197a 100644
--- a/arch/powerpc/kernel/isa-bridge.c
+++ b/arch/powerpc/kernel/isa-bridge.c
@@ -46,8 +46,8 @@ static void remap_isa_base(phys_addr_t pa, unsigned long size)
WARN_ON_ONCE(size & ~PAGE_MASK);
if (slab_is_available()) {
- if (ioremap_page_range(ISA_IO_BASE, ISA_IO_BASE + size, pa,
- pgprot_noncached(PAGE_KERNEL)))
+ if (vmap_page_range(ISA_IO_BASE, ISA_IO_BASE + size, pa,
+ pgprot_noncached(PAGE_KERNEL)))
vunmap_range(ISA_IO_BASE, ISA_IO_BASE + size);
} else {
early_ioremap_range(ISA_IO_BASE, pa, size,
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index b20ee72e873a..bbca90a5e2ec 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -134,10 +134,16 @@ void *alloc_insn_page(void)
if (!page)
return NULL;
- if (strict_module_rwx_enabled())
- set_memory_rox((unsigned long)page, 1);
+ 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)
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 0b5878c3125b..cd8d8883de90 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -151,6 +151,9 @@ static void __init move_device_tree(void)
* pa-features property is missing, or a 1/0 to indicate if the feature
* is supported/not supported. Note that the bit numbers are
* big-endian to match the definition in PAPR.
+ * Note: the 'clear' flag clears the feature if the bit is set in the
+ * ibm,pa/pi-features property, it does not set the feature if the
+ * bit is clear.
*/
struct ibm_feature {
unsigned long cpu_features; /* CPU_FTR_xxx bit */
@@ -159,7 +162,7 @@ struct ibm_feature {
unsigned int cpu_user_ftrs2; /* PPC_FEATURE2_xxx bit */
unsigned char pabyte; /* byte number in ibm,pa/pi-features */
unsigned char pabit; /* bit number (big-endian) */
- unsigned char invert; /* if 1, pa bit set => clear feature */
+ unsigned char clear; /* if 1, pa bit set => clear feature */
};
static struct ibm_feature ibm_pa_features[] __initdata = {
@@ -193,6 +196,7 @@ static struct ibm_feature ibm_pa_features[] __initdata = {
*/
static struct ibm_feature ibm_pi_features[] __initdata = {
{ .pabyte = 0, .pabit = 3, .mmu_features = MMU_FTR_NX_DSI },
+ { .pabyte = 0, .pabit = 4, .cpu_features = CPU_FTR_DBELL, .clear = 1 },
};
static void __init scan_features(unsigned long node, const unsigned char *ftrs,
@@ -220,12 +224,12 @@ static void __init scan_features(unsigned long node, const unsigned char *ftrs,
if (fp->pabyte >= ftrs[0])
continue;
bit = (ftrs[2 + fp->pabyte] >> (7 - fp->pabit)) & 1;
- if (bit ^ fp->invert) {
+ if (bit && !fp->clear) {
cur_cpu_spec->cpu_features |= fp->cpu_features;
cur_cpu_spec->cpu_user_features |= fp->cpu_user_ftrs;
cur_cpu_spec->cpu_user_features2 |= fp->cpu_user_ftrs2;
cur_cpu_spec->mmu_features |= fp->mmu_features;
- } else {
+ } else if (bit == fp->clear) {
cur_cpu_spec->cpu_features &= ~fp->cpu_features;
cur_cpu_spec->cpu_user_features &= ~fp->cpu_user_ftrs;
cur_cpu_spec->cpu_user_features2 &= ~fp->cpu_user_ftrs2;
@@ -368,13 +372,31 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
if (found < 0)
return 0;
- DBG("boot cpu: logical %d physical %d\n", found,
- be32_to_cpu(intserv[found_thread]));
boot_cpuid = found;
if (IS_ENABLED(CONFIG_PPC64))
boot_cpu_hwid = be32_to_cpu(intserv[found_thread]);
+ if (nr_cpu_ids % nthreads != 0) {
+ set_nr_cpu_ids(ALIGN(nr_cpu_ids, nthreads));
+ pr_warn("nr_cpu_ids was not a multiple of threads_per_core, adjusted to %d\n",
+ nr_cpu_ids);
+ }
+
+ if (boot_cpuid >= nr_cpu_ids) {
+ // Remember boot core for smp_setup_cpu_maps()
+ boot_core_hwid = be32_to_cpu(intserv[0]);
+
+ pr_warn("Boot CPU %d (core hwid %d) >= nr_cpu_ids, adjusted boot CPU to %d\n",
+ boot_cpuid, boot_core_hwid, found_thread);
+
+ // Adjust boot CPU to appear on logical core 0
+ boot_cpuid = found_thread;
+ }
+
+ DBG("boot cpu: logical %d physical %d\n", boot_cpuid,
+ be32_to_cpu(intserv[found_thread]));
+
/*
* PAPR defines "logical" PVR values for cpus that
* meet various levels of the architecture:
@@ -453,7 +475,7 @@ static int __init early_init_dt_scan_chosen_ppc(unsigned long node,
tce_alloc_end = *lprop;
#endif
-#ifdef CONFIG_KEXEC_CORE
+#ifdef CONFIG_CRASH_RESERVE
lprop = of_get_flat_dt_prop(node, "linux,crashkernel-base", NULL);
if (lprop)
crashk_res.start = *lprop;
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index e67effdba85c..0ef358285337 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -947,7 +947,7 @@ struct option_vector7 {
} __packed;
struct ibm_arch_vec {
- struct { __be32 mask, val; } pvrs[14];
+ struct { __be32 mask, val; } pvrs[16];
u8 num_vectors;
@@ -1008,6 +1008,14 @@ static const struct ibm_arch_vec ibm_architecture_vec_template __initconst = {
.val = cpu_to_be32(0x00800000),
},
{
+ .mask = cpu_to_be32(0xffff0000), /* POWER11 */
+ .val = cpu_to_be32(0x00820000),
+ },
+ {
+ .mask = cpu_to_be32(0xffffffff), /* P11 compliant */
+ .val = cpu_to_be32(0x0f000007),
+ },
+ {
.mask = cpu_to_be32(0xffffffff), /* all 3.1-compliant */
.val = cpu_to_be32(0x0f000006),
},
diff --git a/arch/powerpc/kernel/secure_boot.c b/arch/powerpc/kernel/secure_boot.c
index f9af305d9579..9e0efb657f39 100644
--- a/arch/powerpc/kernel/secure_boot.c
+++ b/arch/powerpc/kernel/secure_boot.c
@@ -32,8 +32,10 @@ bool is_ppc_secureboot_enabled(void)
if (enabled)
goto out;
- if (!of_property_read_u32(of_root, "ibm,secure-boot", &secureboot))
+ node = of_find_node_by_path("/");
+ if (!of_property_read_u32(node, "ibm,secure-boot", &secureboot))
enabled = (secureboot > 1);
+ of_node_put(node);
out:
pr_info("Secure boot mode %s\n", enabled ? "enabled" : "disabled");
@@ -54,8 +56,10 @@ bool is_ppc_trustedboot_enabled(void)
if (enabled)
goto out;
- if (!of_property_read_u32(of_root, "ibm,trusted-boot", &trustedboot))
+ node = of_find_node_by_path("/");
+ if (!of_property_read_u32(node, "ibm,trusted-boot", &trustedboot))
enabled = (trustedboot > 0);
+ of_node_put(node);
out:
pr_info("Trusted boot mode %s\n", enabled ? "enabled" : "disabled");
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 9b142b9d5187..01ed1263e1a9 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -85,6 +85,7 @@ EXPORT_SYMBOL(machine_id);
int boot_cpuid = -1;
EXPORT_SYMBOL_GPL(boot_cpuid);
+int __initdata boot_core_hwid = -1;
#ifdef CONFIG_PPC64
int boot_cpu_hwid = -1;
@@ -109,7 +110,7 @@ int ppc_do_canonicalize_irqs;
EXPORT_SYMBOL(ppc_do_canonicalize_irqs);
#endif
-#ifdef CONFIG_CRASH_CORE
+#ifdef CONFIG_CRASH_DUMP
/* This keeps a track of which one is the crashing cpu. */
int crashing_cpu = -1;
#endif
@@ -411,6 +412,25 @@ static void __init cpu_init_thread_core_maps(int tpc)
u32 *cpu_to_phys_id = NULL;
+static int assign_threads(unsigned int cpu, unsigned int nthreads, bool present,
+ const __be32 *hw_ids)
+{
+ for (int i = 0; i < nthreads && cpu < nr_cpu_ids; i++) {
+ __be32 hwid;
+
+ hwid = be32_to_cpu(hw_ids[i]);
+
+ DBG(" thread %d -> cpu %d (hard id %d)\n", i, cpu, hwid);
+
+ set_cpu_present(cpu, present);
+ set_cpu_possible(cpu, true);
+ cpu_to_phys_id[cpu] = hwid;
+ cpu++;
+ }
+
+ return cpu;
+}
+
/**
* setup_cpu_maps - initialize the following cpu maps:
* cpu_possible_mask
@@ -446,7 +466,7 @@ void __init smp_setup_cpu_maps(void)
for_each_node_by_type(dn, "cpu") {
const __be32 *intserv;
__be32 cpu_be;
- int j, len;
+ int len;
DBG(" * %pOF...\n", dn);
@@ -468,27 +488,31 @@ void __init smp_setup_cpu_maps(void)
nthreads = len / sizeof(int);
- for (j = 0; j < nthreads && cpu < nr_cpu_ids; j++) {
- bool avail;
-
- DBG(" thread %d -> cpu %d (hard id %d)\n",
- j, cpu, be32_to_cpu(intserv[j]));
+ bool avail = of_device_is_available(dn);
+ if (!avail)
+ avail = !of_property_match_string(dn,
+ "enable-method", "spin-table");
- avail = of_device_is_available(dn);
- if (!avail)
- avail = !of_property_match_string(dn,
- "enable-method", "spin-table");
-
- set_cpu_present(cpu, avail);
- set_cpu_possible(cpu, true);
- cpu_to_phys_id[cpu] = be32_to_cpu(intserv[j]);
- cpu++;
- }
+ if (boot_core_hwid >= 0) {
+ if (cpu == 0) {
+ pr_info("Skipping CPU node %pOF to allow for boot core.\n", dn);
+ cpu = nthreads;
+ continue;
+ }
- if (cpu >= nr_cpu_ids) {
+ if (be32_to_cpu(intserv[0]) == boot_core_hwid) {
+ pr_info("Renumbered boot core %pOF to logical 0\n", dn);
+ assign_threads(0, nthreads, avail, intserv);
+ of_node_put(dn);
+ break;
+ }
+ } else if (cpu >= nr_cpu_ids) {
of_node_put(dn);
break;
}
+
+ if (cpu < nr_cpu_ids)
+ cpu = assign_threads(cpu, nthreads, avail, intserv);
}
/* If no SMT supported, nthreads is forced to 1 */
@@ -616,6 +640,8 @@ static __init void probe_machine(void)
DBG(" %s ...\n", machine_id->name);
if (machine_id->compatible && !of_machine_is_compatible(machine_id->compatible))
continue;
+ if (machine_id->compatibles && !of_machine_compatible_match(machine_id->compatibles))
+ continue;
memcpy(&ppc_md, machine_id, sizeof(struct machdep_calls));
if (ppc_md.probe && !ppc_md.probe())
continue;
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 693334c20d07..12e53b3d7923 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -588,7 +588,7 @@ void smp_send_debugger_break(void)
}
#endif
-#ifdef CONFIG_KEXEC_CORE
+#ifdef CONFIG_CRASH_DUMP
void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *))
{
int cpu;
@@ -631,7 +631,7 @@ void crash_smp_send_stop(void)
stopped = true;
-#ifdef CONFIG_KEXEC_CORE
+#ifdef CONFIG_CRASH_DUMP
if (kexec_crash_image) {
crash_kexec_prepare();
return;
@@ -984,7 +984,7 @@ static bool shared_caches __ro_after_init;
/* cpumask of CPUs with asymmetric SMT dependency */
static int powerpc_smt_flags(void)
{
- int flags = SD_SHARE_CPUCAPACITY | SD_SHARE_PKG_RESOURCES;
+ int flags = SD_SHARE_CPUCAPACITY | SD_SHARE_LLC;
if (cpu_has_feature(CPU_FTR_ASYM_SMT)) {
printk_once(KERN_INFO "Enabling Asymmetric SMT scheduling\n");
@@ -1010,9 +1010,9 @@ static __ro_after_init DEFINE_STATIC_KEY_FALSE(splpar_asym_pack);
static int powerpc_shared_cache_flags(void)
{
if (static_branch_unlikely(&splpar_asym_pack))
- return SD_SHARE_PKG_RESOURCES | SD_ASYM_PACKING;
+ return SD_SHARE_LLC | SD_ASYM_PACKING;
- return SD_SHARE_PKG_RESOURCES;
+ return SD_SHARE_LLC;
}
static int powerpc_shared_proc_flags(void)
diff --git a/arch/powerpc/kernel/syscall.c b/arch/powerpc/kernel/syscall.c
index 77fedb190c93..f6f868e817e6 100644
--- a/arch/powerpc/kernel/syscall.c
+++ b/arch/powerpc/kernel/syscall.c
@@ -31,7 +31,7 @@ notrace long system_call_exception(struct pt_regs *regs, unsigned long r0)
user_exit_irqoff();
BUG_ON(regs_is_unrecoverable(regs));
- BUG_ON(!(regs->msr & MSR_PR));
+ BUG_ON(!user_mode(regs));
BUG_ON(arch_irq_disabled_regs(regs));
#ifdef CONFIG_PPC_PKEY
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 11e062b47d3f..f23430adb68a 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -404,7 +404,7 @@ noinstr void hv_nmi_check_nonrecoverable(struct pt_regs *regs)
return;
if (!(regs->msr & MSR_HV))
return;
- if (regs->msr & MSR_PR)
+ if (user_mode(regs))
return;
/*
@@ -1510,7 +1510,7 @@ static void do_program_check(struct pt_regs *regs)
if (!is_kernel_addr(bugaddr) && !(regs->msr & MSR_IR))
bugaddr += PAGE_OFFSET;
- if (!(regs->msr & MSR_PR) && /* not user-mode */
+ if (!user_mode(regs) &&
report_bug(bugaddr, regs) == BUG_TRAP_TYPE_WARN) {
regs_add_return_ip(regs, 4);
return;
diff --git a/arch/powerpc/kexec/Makefile b/arch/powerpc/kexec/Makefile
index 0c2abe7f9908..8e469c4da3f8 100644
--- a/arch/powerpc/kexec/Makefile
+++ b/arch/powerpc/kexec/Makefile
@@ -3,11 +3,13 @@
# Makefile for the linux kernel.
#
-obj-y += core.o crash.o core_$(BITS).o
+obj-y += core.o core_$(BITS).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_VMCORE_INFO) += vmcore_info.o
+obj-$(CONFIG_CRASH_DUMP) += crash.o
# Disable GCOV, KCOV & sanitizers in odd or sensitive code
GCOV_PROFILE_core_$(BITS).o := n
diff --git a/arch/powerpc/kexec/core.c b/arch/powerpc/kexec/core.c
index 27fa9098a5b7..b8333a49ea5d 100644
--- a/arch/powerpc/kexec/core.c
+++ b/arch/powerpc/kexec/core.c
@@ -44,43 +44,17 @@ void machine_kexec_mask_interrupts(void) {
}
}
+#ifdef CONFIG_CRASH_DUMP
void machine_crash_shutdown(struct pt_regs *regs)
{
default_machine_crash_shutdown(regs);
}
+#endif
void machine_kexec_cleanup(struct kimage *image)
{
}
-void arch_crash_save_vmcoreinfo(void)
-{
-
-#ifdef CONFIG_NUMA
- VMCOREINFO_SYMBOL(node_data);
- VMCOREINFO_LENGTH(node_data, MAX_NUMNODES);
-#endif
-#ifndef CONFIG_NUMA
- VMCOREINFO_SYMBOL(contig_page_data);
-#endif
-#if defined(CONFIG_PPC64) && defined(CONFIG_SPARSEMEM_VMEMMAP)
- VMCOREINFO_SYMBOL(vmemmap_list);
- VMCOREINFO_SYMBOL(mmu_vmemmap_psize);
- VMCOREINFO_SYMBOL(mmu_psize_defs);
- VMCOREINFO_STRUCT_SIZE(vmemmap_backing);
- VMCOREINFO_OFFSET(vmemmap_backing, list);
- VMCOREINFO_OFFSET(vmemmap_backing, phys);
- VMCOREINFO_OFFSET(vmemmap_backing, virt_addr);
- VMCOREINFO_STRUCT_SIZE(mmu_psize_def);
- VMCOREINFO_OFFSET(mmu_psize_def, shift);
-#endif
- VMCOREINFO_SYMBOL(cur_cpu_spec);
- VMCOREINFO_OFFSET(cpu_spec, cpu_features);
- VMCOREINFO_OFFSET(cpu_spec, mmu_features);
- vmcoreinfo_append_str("NUMBER(RADIX_MMU)=%d\n", early_radix_enabled());
- vmcoreinfo_append_str("KERNELOFFSET=%lx\n", kaslr_offset());
-}
-
/*
* Do not allocate memory (or fail in any way) in machine_kexec().
* We are past the point of no return, committed to rebooting now.
@@ -105,6 +79,7 @@ void machine_kexec(struct kimage *image)
for(;;);
}
+#ifdef CONFIG_CRASH_RESERVE
void __init reserve_crashkernel(void)
{
unsigned long long crash_size, crash_base, total_mem_sz;
@@ -279,3 +254,4 @@ static int __init kexec_setup(void)
return 0;
}
late_initcall(kexec_setup);
+#endif /* CONFIG_CRASH_RESERVE */
diff --git a/arch/powerpc/kexec/elf_64.c b/arch/powerpc/kexec/elf_64.c
index 904016cf89ea..6d8951e8e966 100644
--- a/arch/powerpc/kexec/elf_64.c
+++ b/arch/powerpc/kexec/elf_64.c
@@ -47,7 +47,7 @@ static void *elf64_load(struct kimage *image, char *kernel_buf,
if (ret)
return ERR_PTR(ret);
- if (image->type == KEXEC_TYPE_CRASH) {
+ if (IS_ENABLED(CONFIG_CRASH_DUMP) && image->type == KEXEC_TYPE_CRASH) {
/* min & max buffer values for kdump case */
kbuf.buf_min = pbuf.buf_min = crashk_res.start;
kbuf.buf_max = pbuf.buf_max =
@@ -70,7 +70,7 @@ static void *elf64_load(struct kimage *image, char *kernel_buf,
kexec_dprintk("Loaded purgatory at 0x%lx\n", pbuf.mem);
/* Load additional segments needed for panic kernel */
- if (image->type == KEXEC_TYPE_CRASH) {
+ if (IS_ENABLED(CONFIG_CRASH_DUMP) && image->type == KEXEC_TYPE_CRASH) {
ret = load_crashdump_segments_ppc64(image, &kbuf);
if (ret) {
pr_err("Failed to load kdump kernel segments\n");
diff --git a/arch/powerpc/kexec/file_load_64.c b/arch/powerpc/kexec/file_load_64.c
index 5b4c5cb23354..1bc65de6174f 100644
--- a/arch/powerpc/kexec/file_load_64.c
+++ b/arch/powerpc/kexec/file_load_64.c
@@ -97,119 +97,6 @@ out:
}
/**
- * 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;
-}
-
-/**
* 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
@@ -434,6 +321,120 @@ static int locate_mem_hole_bottom_up_ppc64(struct kexec_buf *kbuf,
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.
+ */
+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.
@@ -863,6 +864,7 @@ int load_crashdump_segments_ppc64(struct kimage *image,
return 0;
}
+#endif
/**
* setup_purgatory_ppc64 - initialize PPC64 specific purgatory's global
@@ -972,26 +974,14 @@ static unsigned int cpu_node_size(void)
return size;
}
-/**
- * kexec_extra_fdt_size_ppc64 - Return the estimated additional size needed to
- * setup FDT for kexec/kdump kernel.
- * @image: kexec image being loaded.
- *
- * Returns the estimated extra size needed for kexec/kdump kernel FDT.
- */
-unsigned int kexec_extra_fdt_size_ppc64(struct kimage *image)
+static unsigned int kdump_extra_fdt_size_ppc64(struct kimage *image)
{
unsigned int cpu_nodes, extra_size = 0;
struct device_node *dn;
u64 usm_entries;
- // 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();
-
- if (image->type != KEXEC_TYPE_CRASH)
- return extra_size;
+ if (!IS_ENABLED(CONFIG_CRASH_DUMP) || image->type != KEXEC_TYPE_CRASH)
+ return 0;
/*
* For kdump kernel, account for linux,usable-memory and
@@ -1020,6 +1010,25 @@ unsigned int kexec_extra_fdt_size_ppc64(struct kimage *image)
}
/**
+ * kexec_extra_fdt_size_ppc64 - Return the estimated additional size needed to
+ * setup FDT for kexec/kdump kernel.
+ * @image: kexec image being loaded.
+ *
+ * Returns the estimated extra size needed for kexec/kdump kernel FDT.
+ */
+unsigned int kexec_extra_fdt_size_ppc64(struct kimage *image)
+{
+ unsigned int 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
@@ -1171,6 +1180,7 @@ int setup_new_fdt_ppc64(const struct kimage *image, void *fdt,
struct crash_mem *umem = NULL, *rmem = NULL;
int i, nr_ranges, ret;
+#ifdef CONFIG_CRASH_DUMP
/*
* Restrict memory usage for kdump kernel by setting up
* usable memory ranges and memory reserve map.
@@ -1207,6 +1217,7 @@ int setup_new_fdt_ppc64(const struct kimage *image, void *fdt,
goto out;
}
}
+#endif
/* Update cpus nodes information to account hotplug CPUs. */
ret = update_cpus_node(fdt);
@@ -1278,7 +1289,7 @@ int arch_kexec_locate_mem_hole(struct kexec_buf *kbuf)
buf_min = kbuf->buf_min;
buf_max = kbuf->buf_max;
/* Segments for kdump kernel should be within crashkernel region */
- if (kbuf->image->type == KEXEC_TYPE_CRASH) {
+ if (IS_ENABLED(CONFIG_CRASH_DUMP) && kbuf->image->type == KEXEC_TYPE_CRASH) {
buf_min = (buf_min < crashk_res.start ?
crashk_res.start : buf_min);
buf_max = (buf_max > crashk_res.end ?
diff --git a/arch/powerpc/kexec/ranges.c b/arch/powerpc/kexec/ranges.c
index fb3e12f15214..33b780049aaf 100644
--- a/arch/powerpc/kexec/ranges.c
+++ b/arch/powerpc/kexec/ranges.c
@@ -385,14 +385,16 @@ int add_opal_mem_range(struct crash_mem **mem_ranges)
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("/");
const __be32 *prop;
- prop = of_get_property(of_root, "reserved-ranges", &len);
+ prop = of_get_property(root, "reserved-ranges", &len);
+ n_mem_addr_cells = of_n_addr_cells(root);
+ n_mem_size_cells = of_n_size_cells(root);
+ of_node_put(root);
if (!prop)
return 0;
- n_mem_addr_cells = of_n_addr_cells(of_root);
- n_mem_size_cells = of_n_size_cells(of_root);
cells = n_mem_addr_cells + n_mem_size_cells;
/* Each reserved range is an (address,size) pair */
diff --git a/arch/powerpc/kexec/relocate_32.S b/arch/powerpc/kexec/relocate_32.S
index d9f0dd9b34ff..104c9911f406 100644
--- a/arch/powerpc/kexec/relocate_32.S
+++ b/arch/powerpc/kexec/relocate_32.S
@@ -8,6 +8,7 @@
* Author: Suzuki Poulose <suzuki@in.ibm.com>
*/
+#include <linux/objtool.h>
#include <asm/reg.h>
#include <asm/page.h>
#include <asm/mmu.h>
@@ -349,6 +350,7 @@ write_utlb:
cmpwi r10, PPC47x_TLB0_4K
bne 0f
li r10, 0x1000 /* r10 = 4k */
+ ANNOTATE_INTRA_FUNCTION_CALL
bl 1f
0:
diff --git a/arch/powerpc/kexec/vmcore_info.c b/arch/powerpc/kexec/vmcore_info.c
new file mode 100644
index 000000000000..2b65d2adca5e
--- /dev/null
+++ b/arch/powerpc/kexec/vmcore_info.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/vmcore_info.h>
+#include <asm/pgalloc.h>
+
+void arch_crash_save_vmcoreinfo(void)
+{
+
+#ifdef CONFIG_NUMA
+ VMCOREINFO_SYMBOL(node_data);
+ VMCOREINFO_LENGTH(node_data, MAX_NUMNODES);
+#endif
+#ifndef CONFIG_NUMA
+ VMCOREINFO_SYMBOL(contig_page_data);
+#endif
+#if defined(CONFIG_PPC64) && defined(CONFIG_SPARSEMEM_VMEMMAP)
+ VMCOREINFO_SYMBOL(vmemmap_list);
+ VMCOREINFO_SYMBOL(mmu_vmemmap_psize);
+ VMCOREINFO_SYMBOL(mmu_psize_defs);
+ VMCOREINFO_STRUCT_SIZE(vmemmap_backing);
+ VMCOREINFO_OFFSET(vmemmap_backing, list);
+ VMCOREINFO_OFFSET(vmemmap_backing, phys);
+ VMCOREINFO_OFFSET(vmemmap_backing, virt_addr);
+ VMCOREINFO_STRUCT_SIZE(mmu_psize_def);
+ VMCOREINFO_OFFSET(mmu_psize_def, shift);
+#endif
+ VMCOREINFO_SYMBOL(cur_cpu_spec);
+ VMCOREINFO_OFFSET(cpu_spec, cpu_features);
+ VMCOREINFO_OFFSET(cpu_spec, mmu_features);
+ vmcoreinfo_append_str("NUMBER(RADIX_MMU)=%d\n", early_radix_enabled());
+ vmcoreinfo_append_str("KERNELOFFSET=%lx\n", kaslr_offset());
+}
diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig
index 074263429faf..dbfdc126bf14 100644
--- a/arch/powerpc/kvm/Kconfig
+++ b/arch/powerpc/kvm/Kconfig
@@ -22,7 +22,6 @@ config KVM
select KVM_COMMON
select HAVE_KVM_VCPU_ASYNC_IOCTL
select KVM_VFIO
- select IRQ_BYPASS_MANAGER
select HAVE_KVM_IRQ_BYPASS
config KVM_BOOK3S_HANDLER
diff --git a/arch/powerpc/kvm/book3s_64_mmu_radix.c b/arch/powerpc/kvm/book3s_64_mmu_radix.c
index 4a1abb9f7c05..408d98f8a514 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_radix.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_radix.c
@@ -503,7 +503,7 @@ static void kvmppc_unmap_free_pmd(struct kvm *kvm, pmd_t *pmd, bool full,
for (im = 0; im < PTRS_PER_PMD; ++im, ++p) {
if (!pmd_present(*p))
continue;
- if (pmd_is_leaf(*p)) {
+ if (pmd_leaf(*p)) {
if (full) {
pmd_clear(p);
} else {
@@ -532,7 +532,7 @@ static void kvmppc_unmap_free_pud(struct kvm *kvm, pud_t *pud,
for (iu = 0; iu < PTRS_PER_PUD; ++iu, ++p) {
if (!pud_present(*p))
continue;
- if (pud_is_leaf(*p)) {
+ if (pud_leaf(*p)) {
pud_clear(p);
} else {
pmd_t *pmd;
@@ -635,12 +635,12 @@ int kvmppc_create_pte(struct kvm *kvm, pgd_t *pgtable, pte_t pte,
new_pud = pud_alloc_one(kvm->mm, gpa);
pmd = NULL;
- if (pud && pud_present(*pud) && !pud_is_leaf(*pud))
+ if (pud && pud_present(*pud) && !pud_leaf(*pud))
pmd = pmd_offset(pud, gpa);
else if (level <= 1)
new_pmd = kvmppc_pmd_alloc();
- if (level == 0 && !(pmd && pmd_present(*pmd) && !pmd_is_leaf(*pmd)))
+ if (level == 0 && !(pmd && pmd_present(*pmd) && !pmd_leaf(*pmd)))
new_ptep = kvmppc_pte_alloc();
/* Check if we might have been invalidated; let the guest retry if so */
@@ -658,7 +658,7 @@ int kvmppc_create_pte(struct kvm *kvm, pgd_t *pgtable, pte_t pte,
new_pud = NULL;
}
pud = pud_offset(p4d, gpa);
- if (pud_is_leaf(*pud)) {
+ if (pud_leaf(*pud)) {
unsigned long hgpa = gpa & PUD_MASK;
/* Check if we raced and someone else has set the same thing */
@@ -709,7 +709,7 @@ int kvmppc_create_pte(struct kvm *kvm, pgd_t *pgtable, pte_t pte,
new_pmd = NULL;
}
pmd = pmd_offset(pud, gpa);
- if (pmd_is_leaf(*pmd)) {
+ if (pmd_leaf(*pmd)) {
unsigned long lgpa = gpa & PMD_MASK;
/* Check if we raced and someone else has set the same thing */
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 0b921704da45..8e86eb577eb8 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -444,6 +444,7 @@ static int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat)
guest_pcr_bit = PCR_ARCH_300;
break;
case PVR_ARCH_31:
+ case PVR_ARCH_31_P11:
guest_pcr_bit = PCR_ARCH_31;
break;
default:
diff --git a/arch/powerpc/kvm/book3s_hv_nested.c b/arch/powerpc/kvm/book3s_hv_nested.c
index 5c375ec1a3c6..05f5220960c6 100644
--- a/arch/powerpc/kvm/book3s_hv_nested.c
+++ b/arch/powerpc/kvm/book3s_hv_nested.c
@@ -55,7 +55,7 @@ void kvmhv_save_hv_regs(struct kvm_vcpu *vcpu, struct hv_guest_state *hr)
hr->dawrx1 = vcpu->arch.dawrx1;
}
-/* Use noinline_for_stack due to https://bugs.llvm.org/show_bug.cgi?id=49610 */
+/* Use noinline_for_stack due to https://llvm.org/pr49610 */
static noinline_for_stack void byteswap_pt_regs(struct pt_regs *regs)
{
unsigned long *addr = (unsigned long *) regs;
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 23407fbd73c9..d32abe7fe6ab 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -2538,9 +2538,8 @@ void kvm_arch_create_vcpu_debugfs(struct kvm_vcpu *vcpu, struct dentry *debugfs_
vcpu->kvm->arch.kvm_ops->create_vcpu_debugfs(vcpu, debugfs_dentry);
}
-int kvm_arch_create_vm_debugfs(struct kvm *kvm)
+void kvm_arch_create_vm_debugfs(struct kvm *kvm)
{
if (kvm->arch.kvm_ops->create_vm_debugfs)
kvm->arch.kvm_ops->create_vm_debugfs(kvm);
- return 0;
}
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index 6eac63e79a89..0ab65eeb93ee 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -76,7 +76,7 @@ obj-$(CONFIG_PPC_LIB_RHEAP) += rheap.o
obj-$(CONFIG_FTR_FIXUP_SELFTEST) += feature-fixups-test.o
obj-$(CONFIG_ALTIVEC) += xor_vmx.o xor_vmx_glue.o
-CFLAGS_xor_vmx.o += -maltivec $(call cc-option,-mabi=altivec)
+CFLAGS_xor_vmx.o += -mhard-float -maltivec $(call cc-option,-mabi=altivec)
# Enable <altivec.h>
CFLAGS_xor_vmx.o += -isystem $(shell $(CC) -print-file-name=include)
diff --git a/arch/powerpc/lib/copypage_power7.S b/arch/powerpc/lib/copypage_power7.S
index a783973f1215..07e7cec4d135 100644
--- a/arch/powerpc/lib/copypage_power7.S
+++ b/arch/powerpc/lib/copypage_power7.S
@@ -27,17 +27,7 @@ _GLOBAL(copypage_power7)
#endif
ori r10,r7,1 /* stream=1 */
- lis r8,0x8000 /* GO=1 */
- clrldi r8,r8,32
-
- /* setup read stream 0 */
- dcbt 0,r4,0b01000 /* addr from */
- dcbt 0,r7,0b01010 /* length and depth from */
- /* setup write stream 1 */
- dcbtst 0,r9,0b01000 /* addr to */
- dcbtst 0,r10,0b01010 /* length and depth to */
- eieio
- dcbt 0,r8,0b01010 /* all streams GO */
+ DCBT_SETUP_STREAMS(r4, r7, r9, r10, r8)
#ifdef CONFIG_ALTIVEC
mflr r0
diff --git a/arch/powerpc/lib/copyuser_power7.S b/arch/powerpc/lib/copyuser_power7.S
index ac41053c3a5a..8474c682a178 100644
--- a/arch/powerpc/lib/copyuser_power7.S
+++ b/arch/powerpc/lib/copyuser_power7.S
@@ -298,17 +298,7 @@ err1; stb r0,0(r3)
or r7,r7,r0
ori r10,r7,1 /* stream=1 */
- lis r8,0x8000 /* GO=1 */
- clrldi r8,r8,32
-
- /* setup read stream 0 */
- dcbt 0,r6,0b01000 /* addr from */
- dcbt 0,r7,0b01010 /* length and depth from */
- /* setup write stream 1 */
- dcbtst 0,r9,0b01000 /* addr to */
- dcbtst 0,r10,0b01010 /* length and depth to */
- eieio
- dcbt 0,r8,0b01010 /* all streams GO */
+ DCBT_SETUP_STREAMS(r6, r7, r9, r10, r8)
beq cr1,.Lunwind_stack_nonvmx_copy
diff --git a/arch/powerpc/lib/memcpy_power7.S b/arch/powerpc/lib/memcpy_power7.S
index 9398b2b746c4..b7c5e7fca8b9 100644
--- a/arch/powerpc/lib/memcpy_power7.S
+++ b/arch/powerpc/lib/memcpy_power7.S
@@ -244,15 +244,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
or r7,r7,r0
ori r10,r7,1 /* stream=1 */
- lis r8,0x8000 /* GO=1 */
- clrldi r8,r8,32
-
- dcbt 0,r6,0b01000
- dcbt 0,r7,0b01010
- dcbtst 0,r9,0b01000
- dcbtst 0,r10,0b01010
- eieio
- dcbt 0,r8,0b01010 /* GO */
+ DCBT_SETUP_STREAMS(r6, r7, r9, r10, r8)
beq cr1,.Lunwind_stack_nonvmx_copy
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index 5766180f5380..e65f3fb68d06 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -1429,7 +1429,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
return 1;
case 18: /* rfid, scary */
- if (regs->msr & MSR_PR)
+ if (user_mode(regs))
goto priv;
op->type = RFI;
return 0;
@@ -1742,13 +1742,13 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
return 1;
#endif
case 83: /* mfmsr */
- if (regs->msr & MSR_PR)
+ if (user_mode(regs))
goto priv;
op->type = MFMSR;
op->reg = rd;
return 0;
case 146: /* mtmsr */
- if (regs->msr & MSR_PR)
+ if (user_mode(regs))
goto priv;
op->type = MTMSR;
op->reg = rd;
@@ -1756,7 +1756,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs,
return 0;
#ifdef CONFIG_PPC64
case 178: /* mtmsrd */
- if (regs->msr & MSR_PR)
+ if (user_mode(regs))
goto priv;
op->type = MTMSR;
op->reg = rd;
@@ -3437,14 +3437,14 @@ int emulate_loadstore(struct pt_regs *regs, struct instruction_op *op)
* stored in the thread_struct. If the instruction is in
* the kernel, we must not touch the state in the thread_struct.
*/
- if (!(regs->msr & MSR_PR) && !(regs->msr & MSR_FP))
+ if (!user_mode(regs) && !(regs->msr & MSR_FP))
return 0;
err = do_fp_load(op, ea, regs, cross_endian);
break;
#endif
#ifdef CONFIG_ALTIVEC
case LOAD_VMX:
- if (!(regs->msr & MSR_PR) && !(regs->msr & MSR_VEC))
+ if (!user_mode(regs) && !(regs->msr & MSR_VEC))
return 0;
err = do_vec_load(op->reg, ea, size, regs, cross_endian);
break;
@@ -3459,7 +3459,7 @@ int emulate_loadstore(struct pt_regs *regs, struct instruction_op *op)
*/
if (op->reg >= 32 && (op->vsx_flags & VSX_CHECK_VEC))
msrbit = MSR_VEC;
- if (!(regs->msr & MSR_PR) && !(regs->msr & msrbit))
+ if (!user_mode(regs) && !(regs->msr & msrbit))
return 0;
err = do_vsx_load(op, ea, regs, cross_endian);
break;
@@ -3495,8 +3495,7 @@ int emulate_loadstore(struct pt_regs *regs, struct instruction_op *op)
}
#endif
if ((op->type & UPDATE) && size == sizeof(long) &&
- op->reg == 1 && op->update_reg == 1 &&
- !(regs->msr & MSR_PR) &&
+ op->reg == 1 && op->update_reg == 1 && !user_mode(regs) &&
ea >= regs->gpr[1] - STACK_INT_FRAME_SIZE) {
err = handle_stack_update(ea, regs);
break;
@@ -3508,14 +3507,14 @@ int emulate_loadstore(struct pt_regs *regs, struct instruction_op *op)
#ifdef CONFIG_PPC_FPU
case STORE_FP:
- if (!(regs->msr & MSR_PR) && !(regs->msr & MSR_FP))
+ if (!user_mode(regs) && !(regs->msr & MSR_FP))
return 0;
err = do_fp_store(op, ea, regs, cross_endian);
break;
#endif
#ifdef CONFIG_ALTIVEC
case STORE_VMX:
- if (!(regs->msr & MSR_PR) && !(regs->msr & MSR_VEC))
+ if (!user_mode(regs) && !(regs->msr & MSR_VEC))
return 0;
err = do_vec_store(op->reg, ea, size, regs, cross_endian);
break;
@@ -3530,7 +3529,7 @@ int emulate_loadstore(struct pt_regs *regs, struct instruction_op *op)
*/
if (op->reg >= 32 && (op->vsx_flags & VSX_CHECK_VEC))
msrbit = MSR_VEC;
- if (!(regs->msr & MSR_PR) && !(regs->msr & msrbit))
+ if (!user_mode(regs) && !(regs->msr & msrbit))
return 0;
err = do_vsx_store(op, ea, regs, cross_endian);
break;
diff --git a/arch/powerpc/mm/book3s32/mmu.c b/arch/powerpc/mm/book3s32/mmu.c
index 5445587bfe84..100f999871bc 100644
--- a/arch/powerpc/mm/book3s32/mmu.c
+++ b/arch/powerpc/mm/book3s32/mmu.c
@@ -193,7 +193,7 @@ static bool is_module_segment(unsigned long addr)
return true;
}
-void mmu_mark_initmem_nx(void)
+int mmu_mark_initmem_nx(void)
{
int nb = mmu_has_feature(MMU_FTR_USE_HIGH_BATS) ? 8 : 4;
int i;
@@ -230,9 +230,10 @@ void mmu_mark_initmem_nx(void)
mtsr(mfsr(i << 28) | 0x10000000, i << 28);
}
+ return 0;
}
-void mmu_mark_rodata_ro(void)
+int mmu_mark_rodata_ro(void)
{
int nb = mmu_has_feature(MMU_FTR_USE_HIGH_BATS) ? 8 : 4;
int i;
@@ -245,6 +246,8 @@ void mmu_mark_rodata_ro(void)
}
update_bats();
+
+ return 0;
}
/*
diff --git a/arch/powerpc/mm/book3s64/hash_hugepage.c b/arch/powerpc/mm/book3s64/hash_hugepage.c
index c0fabe6c5a12..15d6f3ea7178 100644
--- a/arch/powerpc/mm/book3s64/hash_hugepage.c
+++ b/arch/powerpc/mm/book3s64/hash_hugepage.c
@@ -59,16 +59,13 @@ int __hash_page_thp(unsigned long ea, unsigned long access, unsigned long vsid,
rflags = htab_convert_pte_flags(new_pmd, flags);
-#if 0
- if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) {
+ /*
+ * THPs are only supported on platforms that can do mixed page size
+ * segments (MPSS) and all such platforms have coherent icache. Hence we
+ * don't need to do lazy icache flush (hash_page_do_lazy_icache()) on
+ * noexecute fault.
+ */
- /*
- * No CPU has hugepages but lacks no execute, so we
- * don't need to worry about that case
- */
- rflags = hash_page_do_lazy_icache(rflags, __pte(old_pte), trap);
- }
-#endif
/*
* Find the slot index details for this ea, using base page size.
*/
diff --git a/arch/powerpc/mm/book3s64/hash_utils.c b/arch/powerpc/mm/book3s64/hash_utils.c
index 0626a25b0d72..01c3b4b65241 100644
--- a/arch/powerpc/mm/book3s64/hash_utils.c
+++ b/arch/powerpc/mm/book3s64/hash_utils.c
@@ -2172,7 +2172,7 @@ static void kernel_unmap_linear_page(unsigned long vaddr, unsigned long lmi)
mmu_kernel_ssize, 0);
}
-void hash__kernel_map_pages(struct page *page, int numpages, int enable)
+int hash__kernel_map_pages(struct page *page, int numpages, int enable)
{
unsigned long flags, vaddr, lmi;
int i;
@@ -2189,6 +2189,7 @@ void hash__kernel_map_pages(struct page *page, int numpages, int enable)
kernel_unmap_linear_page(vaddr, lmi);
}
local_irq_restore(flags);
+ return 0;
}
#endif /* CONFIG_DEBUG_PAGEALLOC || CONFIG_KFENCE */
diff --git a/arch/powerpc/mm/book3s64/pgtable.c b/arch/powerpc/mm/book3s64/pgtable.c
index 3438ab72c346..83823db3488b 100644
--- a/arch/powerpc/mm/book3s64/pgtable.c
+++ b/arch/powerpc/mm/book3s64/pgtable.c
@@ -113,7 +113,7 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr,
WARN_ON(pte_hw_valid(pmd_pte(*pmdp)) && !pte_protnone(pmd_pte(*pmdp)));
assert_spin_locked(pmd_lockptr(mm, pmdp));
- WARN_ON(!(pmd_large(pmd)));
+ WARN_ON(!(pmd_leaf(pmd)));
#endif
trace_hugepage_set_pmd(addr, pmd_val(pmd));
return set_pte_at(mm, addr, pmdp_ptep(pmdp), pmd_pte(pmd));
@@ -130,7 +130,7 @@ void set_pud_at(struct mm_struct *mm, unsigned long addr,
WARN_ON(pte_hw_valid(pud_pte(*pudp)));
assert_spin_locked(pud_lockptr(mm, pudp));
- WARN_ON(!(pud_large(pud)));
+ WARN_ON(!(pud_leaf(pud)));
#endif
trace_hugepage_set_pud(addr, pud_val(pud));
return set_pte_at(mm, addr, pudp_ptep(pudp), pud_pte(pud));
diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c
index c6a4ac766b2b..15e88f1439ec 100644
--- a/arch/powerpc/mm/book3s64/radix_pgtable.c
+++ b/arch/powerpc/mm/book3s64/radix_pgtable.c
@@ -204,14 +204,14 @@ static void radix__change_memory_range(unsigned long start, unsigned long end,
pudp = pud_alloc(&init_mm, p4dp, idx);
if (!pudp)
continue;
- if (pud_is_leaf(*pudp)) {
+ if (pud_leaf(*pudp)) {
ptep = (pte_t *)pudp;
goto update_the_pte;
}
pmdp = pmd_alloc(&init_mm, pudp, idx);
if (!pmdp)
continue;
- if (pmd_is_leaf(*pmdp)) {
+ if (pmd_leaf(*pmdp)) {
ptep = pmdp_ptep(pmdp);
goto update_the_pte;
}
@@ -767,7 +767,7 @@ static void __meminit remove_pmd_table(pmd_t *pmd_start, unsigned long addr,
if (!pmd_present(*pmd))
continue;
- if (pmd_is_leaf(*pmd)) {
+ if (pmd_leaf(*pmd)) {
if (IS_ALIGNED(addr, PMD_SIZE) &&
IS_ALIGNED(next, PMD_SIZE)) {
if (!direct)
@@ -807,7 +807,7 @@ static void __meminit remove_pud_table(pud_t *pud_start, unsigned long addr,
if (!pud_present(*pud))
continue;
- if (pud_is_leaf(*pud)) {
+ if (pud_leaf(*pud)) {
if (!IS_ALIGNED(addr, PUD_SIZE) ||
!IS_ALIGNED(next, PUD_SIZE)) {
WARN_ONCE(1, "%s: unaligned range\n", __func__);
@@ -845,7 +845,7 @@ remove_pagetable(unsigned long start, unsigned long end, bool direct,
if (!p4d_present(*p4d))
continue;
- if (p4d_is_leaf(*p4d)) {
+ if (p4d_leaf(*p4d)) {
if (!IS_ALIGNED(addr, P4D_SIZE) ||
!IS_ALIGNED(next, P4D_SIZE)) {
WARN_ONCE(1, "%s: unaligned range\n", __func__);
@@ -924,7 +924,7 @@ bool vmemmap_can_optimize(struct vmem_altmap *altmap, struct dev_pagemap *pgmap)
int __meminit vmemmap_check_pmd(pmd_t *pmdp, int node,
unsigned long addr, unsigned long next)
{
- int large = pmd_large(*pmdp);
+ int large = pmd_leaf(*pmdp);
if (large)
vmemmap_verify(pmdp_ptep(pmdp), node, addr, next);
@@ -1339,20 +1339,6 @@ void __ref radix__vmemmap_free(unsigned long start, unsigned long end,
#endif
#endif
-#if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_KFENCE)
-void radix__kernel_map_pages(struct page *page, int numpages, int enable)
-{
- unsigned long addr;
-
- addr = (unsigned long)page_address(page);
-
- if (enable)
- set_memory_p(addr, numpages);
- else
- set_memory_np(addr, numpages);
-}
-#endif
-
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
unsigned long radix__pmd_hugepage_update(struct mm_struct *mm, unsigned long addr,
@@ -1554,7 +1540,7 @@ int pud_set_huge(pud_t *pud, phys_addr_t addr, pgprot_t prot)
int pud_clear_huge(pud_t *pud)
{
- if (pud_is_leaf(*pud)) {
+ if (pud_leaf(*pud)) {
pud_clear(pud);
return 1;
}
@@ -1601,7 +1587,7 @@ int pmd_set_huge(pmd_t *pmd, phys_addr_t addr, pgprot_t prot)
int pmd_clear_huge(pmd_t *pmd)
{
- if (pmd_is_leaf(*pmd)) {
+ if (pmd_leaf(*pmd)) {
pmd_clear(pmd);
return 1;
}
diff --git a/arch/powerpc/mm/drmem.c b/arch/powerpc/mm/drmem.c
index fde7790277f7..c110ab8fa8a3 100644
--- a/arch/powerpc/mm/drmem.c
+++ b/arch/powerpc/mm/drmem.c
@@ -393,17 +393,17 @@ static const __be32 *of_get_usable_memory(struct device_node *dn)
int walk_drmem_lmbs(struct device_node *dn, void *data,
int (*func)(struct drmem_lmb *, const __be32 **, void *))
{
+ struct device_node *root = of_find_node_by_path("/");
const __be32 *prop, *usm;
int ret = -ENODEV;
- if (!of_root)
+ if (!root)
return ret;
/* Get the address & size cells */
- of_node_get(of_root);
- n_root_addr_cells = of_n_addr_cells(of_root);
- n_root_size_cells = of_n_size_cells(of_root);
- of_node_put(of_root);
+ n_root_addr_cells = of_n_addr_cells(root);
+ n_root_size_cells = of_n_size_cells(root);
+ of_node_put(root);
if (init_drmem_lmb_size(dn))
return ret;
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 0a540b37aab6..594a4b7b2ca2 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -226,7 +226,7 @@ static int __init pseries_alloc_bootmem_huge_page(struct hstate *hstate)
return 0;
m = phys_to_virt(gpage_freearray[--nr_gpages]);
gpage_freearray[nr_gpages] = 0;
- list_add(&m->list, &huge_boot_pages);
+ list_add(&m->list, &huge_boot_pages[0]);
m->hstate = hstate;
return 1;
}
@@ -614,8 +614,6 @@ void __init gigantic_hugetlb_cma_reserve(void)
*/
order = mmu_psize_to_shift(MMU_PAGE_16G) - PAGE_SHIFT;
- if (order) {
- VM_WARN_ON(order <= MAX_PAGE_ORDER);
+ if (order)
hugetlb_cma_reserve(order);
- }
}
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index 72341b9fb552..6949c2c937e7 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -160,23 +160,17 @@ static inline unsigned long p_block_mapped(phys_addr_t pa) { return 0; }
#endif
#if defined(CONFIG_PPC_BOOK3S_32) || defined(CONFIG_PPC_8xx) || defined(CONFIG_PPC_E500)
-void mmu_mark_initmem_nx(void);
-void mmu_mark_rodata_ro(void);
+int mmu_mark_initmem_nx(void);
+int mmu_mark_rodata_ro(void);
#else
-static inline void mmu_mark_initmem_nx(void) { }
-static inline void mmu_mark_rodata_ro(void) { }
+static inline int mmu_mark_initmem_nx(void) { return 0; }
+static inline int mmu_mark_rodata_ro(void) { return 0; }
#endif
#ifdef CONFIG_PPC_8xx
void __init mmu_mapin_immr(void);
#endif
-#ifdef CONFIG_DEBUG_WX
-void ptdump_check_wx(void);
-#else
-static inline void ptdump_check_wx(void) { }
-#endif
-
static inline bool debug_pagealloc_enabled_or_kfence(void)
{
return IS_ENABLED(CONFIG_KFENCE) || debug_pagealloc_enabled();
@@ -186,3 +180,5 @@ static inline bool debug_pagealloc_enabled_or_kfence(void)
int create_section_mapping(unsigned long start, unsigned long end,
int nid, pgprot_t prot);
#endif
+
+int hash__kernel_map_pages(struct page *page, int numpages, int enable);
diff --git a/arch/powerpc/mm/nohash/8xx.c b/arch/powerpc/mm/nohash/8xx.c
index 6be6421086ed..43d4842bb1c7 100644
--- a/arch/powerpc/mm/nohash/8xx.c
+++ b/arch/powerpc/mm/nohash/8xx.c
@@ -119,23 +119,26 @@ void __init mmu_mapin_immr(void)
PAGE_KERNEL_NCG, MMU_PAGE_512K, true);
}
-static void mmu_mapin_ram_chunk(unsigned long offset, unsigned long top,
- pgprot_t prot, bool new)
+static int mmu_mapin_ram_chunk(unsigned long offset, unsigned long top,
+ pgprot_t prot, bool new)
{
unsigned long v = PAGE_OFFSET + offset;
unsigned long p = offset;
+ int err = 0;
WARN_ON(!IS_ALIGNED(offset, SZ_512K) || !IS_ALIGNED(top, SZ_512K));
- for (; p < ALIGN(p, SZ_8M) && p < top; p += SZ_512K, v += SZ_512K)
- __early_map_kernel_hugepage(v, p, prot, MMU_PAGE_512K, new);
- for (; p < ALIGN_DOWN(top, SZ_8M) && p < top; p += SZ_8M, v += SZ_8M)
- __early_map_kernel_hugepage(v, p, prot, MMU_PAGE_8M, new);
- for (; p < ALIGN_DOWN(top, SZ_512K) && p < top; p += SZ_512K, v += SZ_512K)
- __early_map_kernel_hugepage(v, p, prot, MMU_PAGE_512K, new);
+ for (; p < ALIGN(p, SZ_8M) && p < top && !err; p += SZ_512K, v += SZ_512K)
+ err = __early_map_kernel_hugepage(v, p, prot, MMU_PAGE_512K, new);
+ for (; p < ALIGN_DOWN(top, SZ_8M) && p < top && !err; p += SZ_8M, v += SZ_8M)
+ err = __early_map_kernel_hugepage(v, p, prot, MMU_PAGE_8M, new);
+ for (; p < ALIGN_DOWN(top, SZ_512K) && p < top && !err; p += SZ_512K, v += SZ_512K)
+ err = __early_map_kernel_hugepage(v, p, prot, MMU_PAGE_512K, new);
if (!new)
flush_tlb_kernel_range(PAGE_OFFSET + v, PAGE_OFFSET + top);
+
+ return err;
}
unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top)
@@ -166,27 +169,33 @@ unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top)
return top;
}
-void mmu_mark_initmem_nx(void)
+int mmu_mark_initmem_nx(void)
{
unsigned long etext8 = ALIGN(__pa(_etext), SZ_8M);
unsigned long sinittext = __pa(_sinittext);
unsigned long boundary = strict_kernel_rwx_enabled() ? sinittext : etext8;
unsigned long einittext8 = ALIGN(__pa(_einittext), SZ_8M);
+ int err = 0;
if (!debug_pagealloc_enabled_or_kfence())
- mmu_mapin_ram_chunk(boundary, einittext8, PAGE_KERNEL, false);
+ err = mmu_mapin_ram_chunk(boundary, einittext8, PAGE_KERNEL, false);
mmu_pin_tlb(block_mapped_ram, false);
+
+ return err;
}
#ifdef CONFIG_STRICT_KERNEL_RWX
-void mmu_mark_rodata_ro(void)
+int mmu_mark_rodata_ro(void)
{
unsigned long sinittext = __pa(_sinittext);
+ int err;
- mmu_mapin_ram_chunk(0, sinittext, PAGE_KERNEL_ROX, false);
+ err = mmu_mapin_ram_chunk(0, sinittext, PAGE_KERNEL_ROX, false);
if (IS_ENABLED(CONFIG_PIN_TLB_DATA))
mmu_pin_tlb(block_mapped_ram, true);
+
+ return err;
}
#endif
diff --git a/arch/powerpc/mm/nohash/e500.c b/arch/powerpc/mm/nohash/e500.c
index 921c3521ec11..266fb22131fc 100644
--- a/arch/powerpc/mm/nohash/e500.c
+++ b/arch/powerpc/mm/nohash/e500.c
@@ -285,19 +285,23 @@ void __init adjust_total_lowmem(void)
}
#ifdef CONFIG_STRICT_KERNEL_RWX
-void mmu_mark_rodata_ro(void)
+int mmu_mark_rodata_ro(void)
{
unsigned long remapped;
remapped = map_mem_in_cams(__max_low_memory, CONFIG_LOWMEM_CAM_NUM, false, false);
- WARN_ON(__max_low_memory != remapped);
+ if (WARN_ON(__max_low_memory != remapped))
+ return -EINVAL;
+
+ return 0;
}
#endif
-void mmu_mark_initmem_nx(void)
+int mmu_mark_initmem_nx(void)
{
/* Everything is done in mmu_mark_rodata_ro() */
+ return 0;
}
void setup_initial_memory_limit(phys_addr_t first_memblock_base,
diff --git a/arch/powerpc/mm/nohash/kaslr_booke.c b/arch/powerpc/mm/nohash/kaslr_booke.c
index b4f2786a7d2b..cdff129abb14 100644
--- a/arch/powerpc/mm/nohash/kaslr_booke.c
+++ b/arch/powerpc/mm/nohash/kaslr_booke.c
@@ -13,7 +13,7 @@
#include <linux/delay.h>
#include <linux/memblock.h>
#include <linux/libfdt.h>
-#include <linux/crash_core.h>
+#include <linux/crash_reserve.h>
#include <linux/of.h>
#include <linux/of_fdt.h>
#include <asm/cacheflush.h>
@@ -173,7 +173,7 @@ static __init bool overlaps_region(const void *fdt, u32 start,
static void __init get_crash_kernel(void *fdt, unsigned long size)
{
-#ifdef CONFIG_CRASH_CORE
+#ifdef CONFIG_CRASH_RESERVE
unsigned long long crash_size, crash_base;
int ret;
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index f6c4ace3b221..a490724e84ad 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -1111,7 +1111,7 @@ static void __init setup_node_data(int nid, u64 start_pfn, u64 end_pfn)
static void __init find_possible_nodes(void)
{
- struct device_node *rtas;
+ struct device_node *rtas, *root;
const __be32 *domains = NULL;
int prop_length, max_nodes;
u32 i;
@@ -1132,10 +1132,12 @@ static void __init find_possible_nodes(void)
* If the LPAR is migratable, new nodes might be activated after a LPM,
* so we should consider the max number in that case.
*/
- if (!of_get_property(of_root, "ibm,migratable-partition", NULL))
+ root = of_find_node_by_path("/");
+ if (!of_get_property(root, "ibm,migratable-partition", NULL))
domains = of_get_property(rtas,
"ibm,current-associativity-domains",
&prop_length);
+ of_node_put(root);
if (!domains) {
domains = of_get_property(rtas, "ibm,max-associativity-domains",
&prop_length);
diff --git a/arch/powerpc/mm/pageattr.c b/arch/powerpc/mm/pageattr.c
index 6163e484bc6d..ac22bf28086f 100644
--- a/arch/powerpc/mm/pageattr.c
+++ b/arch/powerpc/mm/pageattr.c
@@ -14,6 +14,7 @@
#include <asm/page.h>
#include <asm/pgtable.h>
+#include <mm/mmu_decl.h>
static pte_basic_t pte_update_delta(pte_t *ptep, unsigned long addr,
unsigned long old, unsigned long new)
@@ -38,6 +39,10 @@ static int change_page_attr(pte_t *ptep, unsigned long addr, void *data)
/* Don't clear DIRTY bit */
pte_update_delta(ptep, addr, _PAGE_KERNEL_RW & ~_PAGE_DIRTY, _PAGE_KERNEL_RO);
break;
+ case SET_MEMORY_ROX:
+ /* Don't clear DIRTY bit */
+ pte_update_delta(ptep, addr, _PAGE_KERNEL_RW & ~_PAGE_DIRTY, _PAGE_KERNEL_ROX);
+ break;
case SET_MEMORY_RW:
pte_update_delta(ptep, addr, _PAGE_KERNEL_RO, _PAGE_KERNEL_RW);
break;
@@ -97,3 +102,26 @@ int change_memory_attr(unsigned long addr, int numpages, long action)
return apply_to_existing_page_range(&init_mm, start, size,
change_page_attr, (void *)action);
}
+
+#if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_KFENCE)
+#ifdef CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC
+void __kernel_map_pages(struct page *page, int numpages, int enable)
+{
+ int err;
+ unsigned long addr = (unsigned long)page_address(page);
+
+ if (PageHighMem(page))
+ return;
+
+ if (IS_ENABLED(CONFIG_PPC_BOOK3S_64) && !radix_enabled())
+ err = hash__kernel_map_pages(page, numpages, enable);
+ else if (enable)
+ err = set_memory_p(addr, numpages);
+ else
+ err = set_memory_np(addr, numpages);
+
+ if (err)
+ panic("%s: changing memory protections failed\n", __func__);
+}
+#endif
+#endif
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index a04ae4449a02..9e7ba9c3851f 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -220,10 +220,7 @@ void set_ptes(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
break;
ptep++;
addr += PAGE_SIZE;
- /*
- * increment the pfn.
- */
- pte = pfn_pte(pte_pfn(pte) + 1, pte_pgprot((pte)));
+ pte = pte_next_pfn(pte);
}
}
@@ -413,7 +410,7 @@ pte_t *__find_linux_pte(pgd_t *pgdir, unsigned long ea,
if (p4d_none(p4d))
return NULL;
- if (p4d_is_leaf(p4d)) {
+ if (p4d_leaf(p4d)) {
ret_pte = (pte_t *)p4dp;
goto out;
}
@@ -435,7 +432,7 @@ pte_t *__find_linux_pte(pgd_t *pgdir, unsigned long ea,
if (pud_none(pud))
return NULL;
- if (pud_is_leaf(pud)) {
+ if (pud_leaf(pud)) {
ret_pte = (pte_t *)pudp;
goto out;
}
@@ -474,7 +471,7 @@ pte_t *__find_linux_pte(pgd_t *pgdir, unsigned long ea,
goto out;
}
- if (pmd_is_leaf(pmd)) {
+ if (pmd_leaf(pmd)) {
ret_pte = (pte_t *)pmdp;
goto out;
}
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 5c02fd08d61e..cfd622ebf774 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -130,32 +130,41 @@ void __init mapin_ram(void)
}
}
-void mark_initmem_nx(void)
+static int __mark_initmem_nx(void)
{
unsigned long numpages = PFN_UP((unsigned long)_einittext) -
PFN_DOWN((unsigned long)_sinittext);
+ int err;
- mmu_mark_initmem_nx();
+ err = mmu_mark_initmem_nx();
if (!v_block_mapped((unsigned long)_sinittext)) {
- set_memory_nx((unsigned long)_sinittext, numpages);
- set_memory_rw((unsigned long)_sinittext, numpages);
+ err = set_memory_nx((unsigned long)_sinittext, numpages);
+ if (err)
+ return err;
+ err = set_memory_rw((unsigned long)_sinittext, numpages);
}
+ return err;
+}
+
+void mark_initmem_nx(void)
+{
+ int err = __mark_initmem_nx();
+
+ if (err)
+ panic("%s() failed, err = %d\n", __func__, err);
}
#ifdef CONFIG_STRICT_KERNEL_RWX
-void mark_rodata_ro(void)
+static int __mark_rodata_ro(void)
{
unsigned long numpages;
if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX) && mmu_has_feature(MMU_FTR_HPTE_TABLE))
pr_warn("This platform has HASH MMU, STRICT_MODULE_RWX won't work\n");
- if (v_block_mapped((unsigned long)_stext + 1)) {
- mmu_mark_rodata_ro();
- ptdump_check_wx();
- return;
- }
+ if (v_block_mapped((unsigned long)_stext + 1))
+ return mmu_mark_rodata_ro();
/*
* mark text and rodata as read only. __end_rodata is set by
@@ -165,24 +174,14 @@ void mark_rodata_ro(void)
numpages = PFN_UP((unsigned long)__end_rodata) -
PFN_DOWN((unsigned long)_stext);
- set_memory_ro((unsigned long)_stext, numpages);
-
- // mark_initmem_nx() should have already run by now
- ptdump_check_wx();
+ return set_memory_ro((unsigned long)_stext, numpages);
}
-#endif
-#if defined(CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC) && defined(CONFIG_DEBUG_PAGEALLOC)
-void __kernel_map_pages(struct page *page, int numpages, int enable)
+void mark_rodata_ro(void)
{
- unsigned long addr = (unsigned long)page_address(page);
+ int err = __mark_rodata_ro();
- if (PageHighMem(page))
- return;
-
- if (enable)
- set_memory_p(addr, numpages);
- else
- set_memory_np(addr, numpages);
+ if (err)
+ panic("%s() failed, err = %d\n", __func__, err);
}
-#endif /* CONFIG_DEBUG_PAGEALLOC */
+#endif
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index 5ac1fd30341b..9b99113cb51a 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -100,7 +100,7 @@ EXPORT_SYMBOL(__pte_frag_size_shift);
/* 4 level page table */
struct page *p4d_page(p4d_t p4d)
{
- if (p4d_is_leaf(p4d)) {
+ if (p4d_leaf(p4d)) {
if (!IS_ENABLED(CONFIG_HAVE_ARCH_HUGE_VMAP))
VM_WARN_ON(!p4d_huge(p4d));
return pte_page(p4d_pte(p4d));
@@ -111,7 +111,7 @@ struct page *p4d_page(p4d_t p4d)
struct page *pud_page(pud_t pud)
{
- if (pud_is_leaf(pud)) {
+ if (pud_leaf(pud)) {
if (!IS_ENABLED(CONFIG_HAVE_ARCH_HUGE_VMAP))
VM_WARN_ON(!pud_huge(pud));
return pte_page(pud_pte(pud));
@@ -125,14 +125,14 @@ struct page *pud_page(pud_t pud)
*/
struct page *pmd_page(pmd_t pmd)
{
- if (pmd_is_leaf(pmd)) {
+ if (pmd_leaf(pmd)) {
/*
* vmalloc_to_page may be called on any vmap address (not only
* vmalloc), and it uses pmd_page() etc., when huge vmap is
* enabled so these checks can't be used.
*/
if (!IS_ENABLED(CONFIG_HAVE_ARCH_HUGE_VMAP))
- VM_WARN_ON(!(pmd_large(pmd) || pmd_huge(pmd)));
+ VM_WARN_ON(!(pmd_leaf(pmd) || pmd_huge(pmd)));
return pte_page(pmd_pte(pmd));
}
return virt_to_page(pmd_page_vaddr(pmd));
@@ -150,9 +150,6 @@ void mark_rodata_ro(void)
radix__mark_rodata_ro();
else
hash__mark_rodata_ro();
-
- // mark_initmem_nx() should have already run by now
- ptdump_check_wx();
}
void mark_initmem_nx(void)
diff --git a/arch/powerpc/mm/ptdump/ptdump.c b/arch/powerpc/mm/ptdump/ptdump.c
index 2313053fe679..9dc239967b77 100644
--- a/arch/powerpc/mm/ptdump/ptdump.c
+++ b/arch/powerpc/mm/ptdump/ptdump.c
@@ -184,13 +184,14 @@ static void note_prot_wx(struct pg_state *st, unsigned long addr)
{
pte_t pte = __pte(st->current_flags);
- if (!IS_ENABLED(CONFIG_DEBUG_WX) || !st->check_wx)
+ if (!st->check_wx)
return;
if (!pte_write(pte) || !pte_exec(pte))
return;
- WARN_ONCE(1, "powerpc/mm: Found insecure W+X mapping at address %p/%pS\n",
+ WARN_ONCE(IS_ENABLED(CONFIG_DEBUG_WX),
+ "powerpc/mm: Found insecure W+X mapping at address %p/%pS\n",
(void *)st->start_address, (void *)st->start_address);
st->wx_pages += (addr - st->start_address) / PAGE_SIZE;
@@ -326,8 +327,7 @@ static void __init build_pgtable_complete_mask(void)
pg_level[i].mask |= pg_level[i].flag[j].mask;
}
-#ifdef CONFIG_DEBUG_WX
-void ptdump_check_wx(void)
+bool ptdump_check_wx(void)
{
struct pg_state st = {
.seq = NULL,
@@ -343,15 +343,22 @@ void ptdump_check_wx(void)
}
};
+ if (IS_ENABLED(CONFIG_PPC_BOOK3S_64) && !mmu_has_feature(MMU_FTR_KERNEL_RO))
+ return true;
+
ptdump_walk_pgd(&st.ptdump, &init_mm, NULL);
- if (st.wx_pages)
+ if (st.wx_pages) {
pr_warn("Checked W+X mappings: FAILED, %lu W+X pages found\n",
st.wx_pages);
- else
+
+ return false;
+ } else {
pr_info("Checked W+X mappings: passed, no W+X pages found\n");
+
+ return true;
+ }
}
-#endif
static int __init ptdump_init(void)
{
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index b7ff680cde96..6b5f8a94e7d8 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -256,7 +256,7 @@ static bool regs_sipr(struct pt_regs *regs)
static inline u32 perf_flags_from_msr(struct pt_regs *regs)
{
- if (regs->msr & MSR_PR)
+ if (user_mode(regs))
return PERF_RECORD_MISC_USER;
if ((regs->msr & MSR_HV) && freeze_events_kernel != MMCR0_FCHV)
return PERF_RECORD_MISC_HYPERVISOR;
@@ -2593,6 +2593,8 @@ static int __init init_ppc64_pmu(void)
return 0;
else if (!init_power10_pmu())
return 0;
+ else if (!init_power11_pmu())
+ return 0;
else if (!init_ppc970_pmu())
return 0;
else
diff --git a/arch/powerpc/perf/hv-gpci.c b/arch/powerpc/perf/hv-gpci.c
index 27f18119fda1..241551d1282f 100644
--- a/arch/powerpc/perf/hv-gpci.c
+++ b/arch/powerpc/perf/hv-gpci.c
@@ -695,6 +695,20 @@ static unsigned long single_gpci_request(u32 req, u32 starting_index,
ret = plpar_hcall_norets(H_GET_PERF_COUNTER_INFO,
virt_to_phys(arg), HGPCI_REQ_BUFFER_SIZE);
+
+ /*
+ * ret value as 'H_PARAMETER' with detail_rc as 'GEN_BUF_TOO_SMALL',
+ * specifies that the current buffer size cannot accommodate
+ * all the information and a partial buffer returned.
+ * Since in this function we are only accessing data for a given starting index,
+ * we don't need to accommodate whole data and can get required count by
+ * accessing first entry data.
+ * Hence hcall fails only incase the ret value is other than H_SUCCESS or
+ * H_PARAMETER with detail_rc value as GEN_BUF_TOO_SMALL(0x1B).
+ */
+ if (ret == H_PARAMETER && be32_to_cpu(arg->params.detail_rc) == 0x1B)
+ ret = 0;
+
if (ret) {
pr_devel("hcall failed: 0x%lx\n", ret);
goto out;
@@ -759,6 +773,7 @@ static int h_gpci_event_init(struct perf_event *event)
{
u64 count;
u8 length;
+ unsigned long ret;
/* Not our event */
if (event->attr.type != event->pmu->type)
@@ -789,13 +804,23 @@ static int h_gpci_event_init(struct perf_event *event)
}
/* check if the request works... */
- if (single_gpci_request(event_get_request(event),
+ ret = single_gpci_request(event_get_request(event),
event_get_starting_index(event),
event_get_secondary_index(event),
event_get_counter_info_version(event),
event_get_offset(event),
length,
- &count)) {
+ &count);
+
+ /*
+ * ret value as H_AUTHORITY implies that partition is not permitted to retrieve
+ * performance information, and required to set
+ * "Enable Performance Information Collection" option.
+ */
+ if (ret == H_AUTHORITY)
+ return -EPERM;
+
+ if (ret) {
pr_devel("gpci hcall failed\n");
return -EINVAL;
}
diff --git a/arch/powerpc/perf/internal.h b/arch/powerpc/perf/internal.h
index 4c18b5504326..a70ac471a5a5 100644
--- a/arch/powerpc/perf/internal.h
+++ b/arch/powerpc/perf/internal.h
@@ -10,4 +10,5 @@ int __init init_power7_pmu(void);
int __init init_power8_pmu(void);
int __init init_power9_pmu(void);
int __init init_power10_pmu(void);
+int __init init_power11_pmu(void);
int __init init_generic_compat_pmu(void);
diff --git a/arch/powerpc/perf/power10-pmu.c b/arch/powerpc/perf/power10-pmu.c
index 9b5133e361a7..62a68b6b2d4b 100644
--- a/arch/powerpc/perf/power10-pmu.c
+++ b/arch/powerpc/perf/power10-pmu.c
@@ -634,3 +634,30 @@ int __init init_power10_pmu(void)
return 0;
}
+
+static struct power_pmu power11_pmu;
+
+int __init init_power11_pmu(void)
+{
+ unsigned int pvr;
+ int rc;
+
+ pvr = mfspr(SPRN_PVR);
+ if (PVR_VER(pvr) != PVR_POWER11)
+ return -ENODEV;
+
+ /* Set the PERF_REG_EXTENDED_MASK here */
+ PERF_REG_EXTENDED_MASK = PERF_REG_PMU_MASK_31;
+
+ power11_pmu = power10_pmu;
+ power11_pmu.name = "Power11";
+
+ rc = register_power_pmu(&power11_pmu);
+ if (rc)
+ return rc;
+
+ /* Tell userspace that EBB is supported */
+ cur_cpu_spec->cpu_user_features2 |= PPC_FEATURE2_EBB;
+
+ return 0;
+}
diff --git a/arch/powerpc/platforms/40x/ppc40x_simple.c b/arch/powerpc/platforms/40x/ppc40x_simple.c
index e454e9d2eff1..294ab2728588 100644
--- a/arch/powerpc/platforms/40x/ppc40x_simple.c
+++ b/arch/powerpc/platforms/40x/ppc40x_simple.c
@@ -59,16 +59,13 @@ static const char * const board[] __initconst = {
static int __init ppc40x_probe(void)
{
- if (of_device_compatible_match(of_root, board)) {
- pci_set_flags(PCI_REASSIGN_ALL_RSRC);
- return 1;
- }
-
- return 0;
+ 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,
diff --git a/arch/powerpc/platforms/44x/warp.c b/arch/powerpc/platforms/44x/warp.c
index bf0188dcb918..a5001d32f978 100644
--- a/arch/powerpc/platforms/44x/warp.c
+++ b/arch/powerpc/platforms/44x/warp.c
@@ -8,6 +8,7 @@
#include <linux/err.h>
#include <linux/init.h>
#include <linux/of_platform.h>
+#include <linux/platform_device.h>
#include <linux/kthread.h>
#include <linux/leds.h>
#include <linux/i2c.h>
diff --git a/arch/powerpc/platforms/512x/mpc512x_generic.c b/arch/powerpc/platforms/512x/mpc512x_generic.c
index 0d58ab257cd9..d4fa6c302ccf 100644
--- a/arch/powerpc/platforms/512x/mpc512x_generic.c
+++ b/arch/powerpc/platforms/512x/mpc512x_generic.c
@@ -32,9 +32,6 @@ static const char * const board[] __initconst = {
*/
static int __init mpc512x_generic_probe(void)
{
- if (!of_device_compatible_match(of_root, board))
- return 0;
-
mpc512x_init_early();
return 1;
@@ -42,6 +39,7 @@ static int __init mpc512x_generic_probe(void)
define_machine(mpc512x_generic) {
.name = "MPC512x generic",
+ .compatibles = board,
.probe = mpc512x_generic_probe,
.init = mpc512x_init,
.setup_arch = mpc512x_setup_arch,
diff --git a/arch/powerpc/platforms/52xx/efika.c b/arch/powerpc/platforms/52xx/efika.c
index aa82e6b437f3..37a67120f257 100644
--- a/arch/powerpc/platforms/52xx/efika.c
+++ b/arch/powerpc/platforms/52xx/efika.c
@@ -195,8 +195,10 @@ static void __init efika_setup_arch(void)
static int __init efika_probe(void)
{
- const char *model = of_get_property(of_root, "model", NULL);
+ struct device_node *root = of_find_node_by_path("/");
+ const char *model = of_get_property(root, "model", NULL);
+ of_node_put(root);
if (model == NULL)
return 0;
if (strcmp(model, "EFIKA5K2"))
diff --git a/arch/powerpc/platforms/52xx/lite5200.c b/arch/powerpc/platforms/52xx/lite5200.c
index 0fd67b3ffc3e..0a161d82a3a8 100644
--- a/arch/powerpc/platforms/52xx/lite5200.c
+++ b/arch/powerpc/platforms/52xx/lite5200.c
@@ -172,17 +172,9 @@ static const char * const board[] __initconst = {
NULL,
};
-/*
- * Called very early, MMU is off, device-tree isn't unflattened
- */
-static int __init lite5200_probe(void)
-{
- return of_device_compatible_match(of_root, board);
-}
-
define_machine(lite5200) {
.name = "lite5200",
- .probe = lite5200_probe,
+ .compatibles = board,
.setup_arch = lite5200_setup_arch,
.discover_phbs = mpc52xx_setup_pci,
.init = mpc52xx_declare_of_platform_devices,
diff --git a/arch/powerpc/platforms/52xx/mpc5200_simple.c b/arch/powerpc/platforms/52xx/mpc5200_simple.c
index f1e85e86f5e5..7e0e4c34a40b 100644
--- a/arch/powerpc/platforms/52xx/mpc5200_simple.c
+++ b/arch/powerpc/platforms/52xx/mpc5200_simple.c
@@ -59,17 +59,9 @@ static const char *board[] __initdata = {
NULL
};
-/*
- * Called very early, MMU is off, device-tree isn't unflattened
- */
-static int __init mpc5200_simple_probe(void)
-{
- return of_device_compatible_match(of_root, board);
-}
-
define_machine(mpc5200_simple_platform) {
.name = "mpc5200-simple-platform",
- .probe = mpc5200_simple_probe,
+ .compatibles = board,
.setup_arch = mpc5200_simple_setup_arch,
.discover_phbs = mpc52xx_setup_pci,
.init = mpc52xx_declare_of_platform_devices,
diff --git a/arch/powerpc/platforms/83xx/mpc830x_rdb.c b/arch/powerpc/platforms/83xx/mpc830x_rdb.c
index 534bb227480d..63b6d213726a 100644
--- a/arch/powerpc/platforms/83xx/mpc830x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc830x_rdb.c
@@ -34,19 +34,11 @@ static const char *board[] __initdata = {
NULL
};
-/*
- * Called very early, MMU is off, device-tree isn't unflattened
- */
-static int __init mpc830x_rdb_probe(void)
-{
- return of_device_compatible_match(of_root, board);
-}
-
machine_device_initcall(mpc830x_rdb, mpc83xx_declare_of_platform_devices);
define_machine(mpc830x_rdb) {
.name = "MPC830x RDB",
- .probe = mpc830x_rdb_probe,
+ .compatibles = board,
.setup_arch = mpc830x_rdb_setup_arch,
.discover_phbs = mpc83xx_setup_pci,
.init_IRQ = mpc83xx_ipic_init_IRQ,
diff --git a/arch/powerpc/platforms/83xx/mpc831x_rdb.c b/arch/powerpc/platforms/83xx/mpc831x_rdb.c
index 7b901ab3b864..5c39966762e4 100644
--- a/arch/powerpc/platforms/83xx/mpc831x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc831x_rdb.c
@@ -34,19 +34,11 @@ static const char *board[] __initdata = {
NULL
};
-/*
- * Called very early, MMU is off, device-tree isn't unflattened
- */
-static int __init mpc831x_rdb_probe(void)
-{
- return of_device_compatible_match(of_root, board);
-}
-
machine_device_initcall(mpc831x_rdb, mpc83xx_declare_of_platform_devices);
define_machine(mpc831x_rdb) {
.name = "MPC831x RDB",
- .probe = mpc831x_rdb_probe,
+ .compatibles = board,
.setup_arch = mpc831x_rdb_setup_arch,
.discover_phbs = mpc83xx_setup_pci,
.init_IRQ = mpc83xx_ipic_init_IRQ,
diff --git a/arch/powerpc/platforms/83xx/mpc837x_rdb.c b/arch/powerpc/platforms/83xx/mpc837x_rdb.c
index 39e78018dd0b..45823e147933 100644
--- a/arch/powerpc/platforms/83xx/mpc837x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc837x_rdb.c
@@ -61,17 +61,9 @@ static const char * const board[] __initconst = {
NULL
};
-/*
- * Called very early, MMU is off, device-tree isn't unflattened
- */
-static int __init mpc837x_rdb_probe(void)
-{
- return of_device_compatible_match(of_root, board);
-}
-
define_machine(mpc837x_rdb) {
.name = "MPC837x RDB/WLAN",
- .probe = mpc837x_rdb_probe,
+ .compatibles = board,
.setup_arch = mpc837x_rdb_setup_arch,
.discover_phbs = mpc83xx_setup_pci,
.init_IRQ = mpc83xx_ipic_init_IRQ,
diff --git a/arch/powerpc/platforms/83xx/suspend.c b/arch/powerpc/platforms/83xx/suspend.c
index c9664e46b03d..99bd4355f28e 100644
--- a/arch/powerpc/platforms/83xx/suspend.c
+++ b/arch/powerpc/platforms/83xx/suspend.c
@@ -206,7 +206,8 @@ static int mpc83xx_suspend_enter(suspend_state_t state)
out_be32(&pmc_regs->config1,
in_be32(&pmc_regs->config1) | PMCCR1_POWER_OFF);
- enable_kernel_fp();
+ if (IS_ENABLED(CONFIG_PPC_FPU))
+ enable_kernel_fp();
mpc83xx_enter_deep_sleep(immrbase);
diff --git a/arch/powerpc/platforms/85xx/bsc913x_qds.c b/arch/powerpc/platforms/85xx/bsc913x_qds.c
index 2eb62bff86d4..3ad8096fcf16 100644
--- a/arch/powerpc/platforms/85xx/bsc913x_qds.c
+++ b/arch/powerpc/platforms/85xx/bsc913x_qds.c
@@ -19,7 +19,7 @@
#include "mpc85xx.h"
#include "smp.h"
-void __init bsc913x_qds_pic_init(void)
+static void __init bsc913x_qds_pic_init(void)
{
struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN |
MPIC_SINGLE_DEST_CPU,
diff --git a/arch/powerpc/platforms/85xx/bsc913x_rdb.c b/arch/powerpc/platforms/85xx/bsc913x_rdb.c
index 161f006cb3bb..dcd358c28201 100644
--- a/arch/powerpc/platforms/85xx/bsc913x_rdb.c
+++ b/arch/powerpc/platforms/85xx/bsc913x_rdb.c
@@ -15,7 +15,7 @@
#include "mpc85xx.h"
-void __init bsc913x_rdb_pic_init(void)
+static void __init bsc913x_rdb_pic_init(void)
{
struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN |
MPIC_SINGLE_DEST_CPU,
diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c b/arch/powerpc/platforms/85xx/corenet_generic.c
index 645fcca77cde..c44400e95f55 100644
--- a/arch/powerpc/platforms/85xx/corenet_generic.c
+++ b/arch/powerpc/platforms/85xx/corenet_generic.c
@@ -149,7 +149,7 @@ static int __init corenet_generic_probe(void)
extern struct smp_ops_t smp_85xx_ops;
#endif
- if (of_device_compatible_match(of_root, boards))
+ if (of_machine_compatible_match(boards))
return 1;
/* Check if we're running under the Freescale hypervisor */
diff --git a/arch/powerpc/platforms/85xx/ge_imp3a.c b/arch/powerpc/platforms/85xx/ge_imp3a.c
index 9c3b44a1952e..477852f1a726 100644
--- a/arch/powerpc/platforms/85xx/ge_imp3a.c
+++ b/arch/powerpc/platforms/85xx/ge_imp3a.c
@@ -38,7 +38,7 @@
void __iomem *imp3a_regs;
-void __init ge_imp3a_pic_init(void)
+static void __init ge_imp3a_pic_init(void)
{
struct mpic *mpic;
struct device_node *np;
diff --git a/arch/powerpc/platforms/85xx/sgy_cts1000.c b/arch/powerpc/platforms/85xx/sgy_cts1000.c
index 751395cbf022..34ce21f42623 100644
--- a/arch/powerpc/platforms/85xx/sgy_cts1000.c
+++ b/arch/powerpc/platforms/85xx/sgy_cts1000.c
@@ -114,7 +114,7 @@ static int gpio_halt_probe(struct platform_device *pdev)
return ret;
}
-static int gpio_halt_remove(struct platform_device *pdev)
+static void gpio_halt_remove(struct platform_device *pdev)
{
free_irq(halt_irq, pdev);
cancel_work_sync(&gpio_halt_wq);
@@ -124,8 +124,6 @@ static int gpio_halt_remove(struct platform_device *pdev)
gpiod_put(halt_gpio);
halt_gpio = NULL;
-
- return 0;
}
static const struct of_device_id gpio_halt_match[] = {
@@ -145,7 +143,7 @@ static struct platform_driver gpio_halt_driver = {
.of_match_table = gpio_halt_match,
},
.probe = gpio_halt_probe,
- .remove = gpio_halt_remove,
+ .remove_new = gpio_halt_remove,
};
module_platform_driver(gpio_halt_driver);
diff --git a/arch/powerpc/platforms/85xx/tqm85xx.c b/arch/powerpc/platforms/85xx/tqm85xx.c
index 6be1b9809db6..f74d446c53f0 100644
--- a/arch/powerpc/platforms/85xx/tqm85xx.c
+++ b/arch/powerpc/platforms/85xx/tqm85xx.c
@@ -112,17 +112,9 @@ static const char * const board[] __initconst = {
NULL
};
-/*
- * Called very early, device-tree isn't unflattened
- */
-static int __init tqm85xx_probe(void)
-{
- return of_device_compatible_match(of_root, board);
-}
-
define_machine(tqm85xx) {
.name = "TQM85xx",
- .probe = tqm85xx_probe,
+ .compatibles = board,
.setup_arch = tqm85xx_setup_arch,
.init_IRQ = tqm85xx_pic_init,
.show_cpuinfo = tqm85xx_show_cpuinfo,
diff --git a/arch/powerpc/platforms/amigaone/setup.c b/arch/powerpc/platforms/amigaone/setup.c
index 6c6e714a7521..2c8dc0886912 100644
--- a/arch/powerpc/platforms/amigaone/setup.c
+++ b/arch/powerpc/platforms/amigaone/setup.c
@@ -25,7 +25,7 @@
extern void __flush_disable_L1(void);
-void amigaone_show_cpuinfo(struct seq_file *m)
+static void amigaone_show_cpuinfo(struct seq_file *m)
{
seq_printf(m, "vendor\t\t: Eyetech Ltd.\n");
}
@@ -65,7 +65,7 @@ static int __init amigaone_add_bridge(struct device_node *dev)
return 0;
}
-void __init amigaone_setup_arch(void)
+static void __init amigaone_setup_arch(void)
{
if (ppc_md.progress)
ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0);
@@ -83,7 +83,7 @@ static void __init amigaone_discover_phbs(void)
BUG_ON(phb != 0);
}
-void __init amigaone_init_IRQ(void)
+static void __init amigaone_init_IRQ(void)
{
struct device_node *pic, *np = NULL;
const unsigned long *prop = NULL;
@@ -123,7 +123,7 @@ static int __init request_isa_regions(void)
}
machine_device_initcall(amigaone, request_isa_regions);
-void __noreturn amigaone_restart(char *cmd)
+static void __noreturn amigaone_restart(char *cmd)
{
local_irq_disable();
diff --git a/arch/powerpc/platforms/embedded6xx/linkstation.c b/arch/powerpc/platforms/embedded6xx/linkstation.c
index 9c10aac40c7b..e265f026eee2 100644
--- a/arch/powerpc/platforms/embedded6xx/linkstation.c
+++ b/arch/powerpc/platforms/embedded6xx/linkstation.c
@@ -99,9 +99,6 @@ static void __init linkstation_init_IRQ(void)
mpic_init(mpic);
}
-extern void avr_uart_configure(void);
-extern void avr_uart_send(const char);
-
static void __noreturn linkstation_restart(char *cmd)
{
local_irq_disable();
diff --git a/arch/powerpc/platforms/embedded6xx/mpc10x.h b/arch/powerpc/platforms/embedded6xx/mpc10x.h
index 5ad12023e562..ebc258fa4858 100644
--- a/arch/powerpc/platforms/embedded6xx/mpc10x.h
+++ b/arch/powerpc/platforms/embedded6xx/mpc10x.h
@@ -156,4 +156,7 @@ int mpc10x_disable_store_gathering(struct pci_controller *hose);
/* For MPC107 boards that use the built-in openpic */
void mpc10x_set_openpic(void);
+void avr_uart_configure(void);
+void avr_uart_send(const char c);
+
#endif /* __PPC_KERNEL_MPC10X_H */
diff --git a/arch/powerpc/platforms/pasemi/gpio_mdio.c b/arch/powerpc/platforms/pasemi/gpio_mdio.c
index fd130fe7a65a..4e983af32949 100644
--- a/arch/powerpc/platforms/pasemi/gpio_mdio.c
+++ b/arch/powerpc/platforms/pasemi/gpio_mdio.c
@@ -260,7 +260,7 @@ out:
}
-static int gpio_mdio_remove(struct platform_device *dev)
+static void gpio_mdio_remove(struct platform_device *dev)
{
struct mii_bus *bus = dev_get_drvdata(&dev->dev);
@@ -271,8 +271,6 @@ static int gpio_mdio_remove(struct platform_device *dev)
kfree(bus->priv);
bus->priv = NULL;
mdiobus_free(bus);
-
- return 0;
}
static const struct of_device_id gpio_mdio_match[] =
@@ -287,7 +285,7 @@ MODULE_DEVICE_TABLE(of, gpio_mdio_match);
static struct platform_driver gpio_mdio_driver =
{
.probe = gpio_mdio_probe,
- .remove = gpio_mdio_remove,
+ .remove_new = gpio_mdio_remove,
.driver = {
.name = "gpio-mdio-bitbang",
.of_match_table = gpio_mdio_match,
diff --git a/arch/powerpc/platforms/pasemi/pci.c b/arch/powerpc/platforms/pasemi/pci.c
index f27d31414737..60f990a336c4 100644
--- a/arch/powerpc/platforms/pasemi/pci.c
+++ b/arch/powerpc/platforms/pasemi/pci.c
@@ -270,16 +270,18 @@ static int __init pas_add_bridge(struct device_node *dev)
void __init pas_pci_init(void)
{
+ struct device_node *root = of_find_node_by_path("/");
struct device_node *np;
int res;
pci_set_flags(PCI_SCAN_ALL_PCIE_DEVS);
- np = of_find_compatible_node(of_root, NULL, "pasemi,rootbus");
+ np = of_find_compatible_node(root, NULL, "pasemi,rootbus");
if (np) {
res = pas_add_bridge(np);
of_node_put(np);
}
+ of_node_put(root);
}
void __iomem *__init pasemi_pci_getcfgaddr(struct pci_dev *dev, int offset)
diff --git a/arch/powerpc/platforms/powermac/Kconfig b/arch/powerpc/platforms/powermac/Kconfig
index 8bdae0caf21e..84f101ec53a9 100644
--- a/arch/powerpc/platforms/powermac/Kconfig
+++ b/arch/powerpc/platforms/powermac/Kconfig
@@ -2,7 +2,7 @@
config PPC_PMAC
bool "Apple PowerMac based machines"
depends on PPC_BOOK3S && CPU_BIG_ENDIAN
- select ADB_CUDA if POWER_RESET && PPC32
+ select ADB_CUDA if POWER_RESET && ADB
select MPIC
select FORCE_PCI
select PPC_INDIRECT_PCI if PPC32
diff --git a/arch/powerpc/platforms/powermac/backlight.c b/arch/powerpc/platforms/powermac/backlight.c
index aeb79a8b3e10..12bc01353bd3 100644
--- a/arch/powerpc/platforms/powermac/backlight.c
+++ b/arch/powerpc/platforms/powermac/backlight.c
@@ -9,7 +9,6 @@
*/
#include <linux/kernel.h>
-#include <linux/fb.h>
#include <linux/backlight.h>
#include <linux/adb.h>
#include <linux/pmu.h>
@@ -72,31 +71,6 @@ int pmac_has_backlight_type(const char *type)
return 0;
}
-int pmac_backlight_curve_lookup(struct fb_info *info, int value)
-{
- int level = (FB_BACKLIGHT_LEVELS - 1);
-
- if (info && info->bl_dev) {
- int i, max = 0;
-
- /* Look for biggest value */
- for (i = 0; i < FB_BACKLIGHT_LEVELS; i++)
- max = max((int)info->bl_curve[i], max);
-
- /* Look for nearest value */
- for (i = 0; i < FB_BACKLIGHT_LEVELS; i++) {
- int diff = abs(info->bl_curve[i] - value);
- if (diff < max) {
- max = diff;
- level = i;
- }
- }
-
- }
-
- return level;
-}
-
static void pmac_backlight_key_worker(struct work_struct *work)
{
if (atomic_read(&kernel_backlight_disabled))
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c
index 81c9fbae88b1..2cc257f75c50 100644
--- a/arch/powerpc/platforms/powermac/feature.c
+++ b/arch/powerpc/platforms/powermac/feature.c
@@ -2333,7 +2333,6 @@ static struct pmac_mb_def pmac_mb_defs[] = {
PMAC_TYPE_POWERMAC_G5, g5_features,
0,
},
-#ifdef CONFIG_PPC64
{ "PowerMac7,3", "PowerMac G5",
PMAC_TYPE_POWERMAC_G5, g5_features,
0,
@@ -2359,7 +2358,6 @@ static struct pmac_mb_def pmac_mb_defs[] = {
0,
},
#endif /* CONFIG_PPC64 */
-#endif /* CONFIG_PPC64 */
};
/*
diff --git a/arch/powerpc/platforms/powernv/opal-core.c b/arch/powerpc/platforms/powernv/opal-core.c
index bb7657115f1d..c9a9b759cc92 100644
--- a/arch/powerpc/platforms/powernv/opal-core.c
+++ b/arch/powerpc/platforms/powernv/opal-core.c
@@ -16,7 +16,7 @@
#include <linux/kobject.h>
#include <linux/sysfs.h>
#include <linux/slab.h>
-#include <linux/crash_core.h>
+#include <linux/vmcore_info.h>
#include <linux/of.h>
#include <asm/page.h>
diff --git a/arch/powerpc/platforms/powernv/opal-prd.c b/arch/powerpc/platforms/powernv/opal-prd.c
index b66b06efcef1..24f04f20d3e8 100644
--- a/arch/powerpc/platforms/powernv/opal-prd.c
+++ b/arch/powerpc/platforms/powernv/opal-prd.c
@@ -425,12 +425,11 @@ static int opal_prd_probe(struct platform_device *pdev)
return 0;
}
-static int opal_prd_remove(struct platform_device *pdev)
+static void opal_prd_remove(struct platform_device *pdev)
{
misc_deregister(&opal_prd_dev);
opal_message_notifier_unregister(OPAL_MSG_PRD, &opal_prd_event_nb);
opal_message_notifier_unregister(OPAL_MSG_PRD2, &opal_prd_event_nb2);
- return 0;
}
static const struct of_device_id opal_prd_match[] = {
@@ -444,7 +443,7 @@ static struct platform_driver opal_prd_driver = {
.of_match_table = opal_prd_match,
},
.probe = opal_prd_probe,
- .remove = opal_prd_remove,
+ .remove_new = opal_prd_remove,
};
module_platform_driver(opal_prd_driver);
diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c
index 9e1a25398f98..8f14f0581a21 100644
--- a/arch/powerpc/platforms/powernv/smp.c
+++ b/arch/powerpc/platforms/powernv/smp.c
@@ -434,7 +434,7 @@ void __init pnv_smp_init(void)
smp_ops = &pnv_smp_ops;
#ifdef CONFIG_HOTPLUG_CPU
-#ifdef CONFIG_KEXEC_CORE
+#ifdef CONFIG_CRASH_DUMP
crash_wake_offline = 1;
#endif
#endif
diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig
index e9c1087dd42e..706194e5f0b4 100644
--- a/arch/powerpc/platforms/ps3/Kconfig
+++ b/arch/powerpc/platforms/ps3/Kconfig
@@ -67,6 +67,7 @@ config PS3_VUART
config PS3_PS3AV
depends on PPC_PS3
tristate "PS3 AV settings driver" if PS3_ADVANCED
+ select VIDEO
select PS3_VUART
default y
help
diff --git a/arch/powerpc/platforms/ps3/hvcall.S b/arch/powerpc/platforms/ps3/hvcall.S
index 509e30ad01bb..e8ab3d6b03bd 100644
--- a/arch/powerpc/platforms/ps3/hvcall.S
+++ b/arch/powerpc/platforms/ps3/hvcall.S
@@ -9,6 +9,7 @@
#include <asm/processor.h>
#include <asm/ppc_asm.h>
+#include <asm/ptrace.h>
#define lv1call .long 0x44000022; extsw r3, r3
@@ -16,12 +17,14 @@
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
\
+ stdu r1, -STACK_FRAME_MIN_SIZE(r1); \
li r11, API_NUMBER; \
lv1call; \
+ addi r1, r1, STACK_FRAME_MIN_SIZE; \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
@@ -38,18 +41,19 @@ _GLOBAL(_##API_NAME) \
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
\
- stdu r3, -8(r1); \
+ std r3, -8(r1); \
+ stdu r1, -STACK_FRAME_MIN_SIZE-8(r1); \
\
li r11, API_NUMBER; \
lv1call; \
\
- addi r1, r1, 8; \
+ addi r1, r1, STACK_FRAME_MIN_SIZE+8; \
ld r11, -8(r1); \
std r4, 0(r11); \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
@@ -57,21 +61,22 @@ _GLOBAL(_##API_NAME) \
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
\
std r3, -8(r1); \
- stdu r4, -16(r1); \
+ std r4, -16(r1); \
+ stdu r1, -STACK_FRAME_MIN_SIZE-16(r1); \
\
li r11, API_NUMBER; \
lv1call; \
\
- addi r1, r1, 16; \
+ addi r1, r1, STACK_FRAME_MIN_SIZE+16; \
ld r11, -8(r1); \
std r4, 0(r11); \
ld r11, -16(r1); \
std r5, 0(r11); \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
@@ -79,16 +84,17 @@ _GLOBAL(_##API_NAME) \
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
\
std r3, -8(r1); \
std r4, -16(r1); \
- stdu r5, -24(r1); \
+ std r5, -24(r1); \
+ stdu r1, -STACK_FRAME_MIN_SIZE-24(r1); \
\
li r11, API_NUMBER; \
lv1call; \
\
- addi r1, r1, 24; \
+ addi r1, r1, STACK_FRAME_MIN_SIZE+24; \
ld r11, -8(r1); \
std r4, 0(r11); \
ld r11, -16(r1); \
@@ -96,7 +102,7 @@ _GLOBAL(_##API_NAME) \
ld r11, -24(r1); \
std r6, 0(r11); \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
@@ -104,7 +110,7 @@ _GLOBAL(_##API_NAME) \
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
\
std r3, -8(r1); \
std r4, -16(r1); \
@@ -112,12 +118,13 @@ _GLOBAL(_##API_NAME) \
std r6, -32(r1); \
std r7, -40(r1); \
std r8, -48(r1); \
- stdu r9, -56(r1); \
+ std r9, -56(r1); \
+ stdu r1, -STACK_FRAME_MIN_SIZE-56(r1); \
\
li r11, API_NUMBER; \
lv1call; \
\
- addi r1, r1, 56; \
+ addi r1, r1, STACK_FRAME_MIN_SIZE+56; \
ld r11, -8(r1); \
std r4, 0(r11); \
ld r11, -16(r1); \
@@ -133,7 +140,7 @@ _GLOBAL(_##API_NAME) \
ld r11, -56(r1); \
std r10, 0(r11); \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
@@ -141,18 +148,19 @@ _GLOBAL(_##API_NAME) \
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
\
- stdu r4, -8(r1); \
+ std r4, -8(r1); \
+ stdu r1, -STACK_FRAME_MIN_SIZE-8(r1); \
\
li r11, API_NUMBER; \
lv1call; \
\
- addi r1, r1, 8; \
+ addi r1, r1, STACK_FRAME_MIN_SIZE+8; \
ld r11, -8(r1); \
std r4, 0(r11); \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
@@ -160,21 +168,22 @@ _GLOBAL(_##API_NAME) \
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
\
std r4, -8(r1); \
- stdu r5, -16(r1); \
+ std r5, -16(r1); \
+ stdu r1, -STACK_FRAME_MIN_SIZE-16(r1); \
\
li r11, API_NUMBER; \
lv1call; \
\
- addi r1, r1, 16; \
+ addi r1, r1, STACK_FRAME_MIN_SIZE+16; \
ld r11, -8(r1); \
std r4, 0(r11); \
ld r11, -16(r1); \
std r5, 0(r11); \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
@@ -182,16 +191,17 @@ _GLOBAL(_##API_NAME) \
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
\
std r4, -8(r1); \
std r5, -16(r1); \
- stdu r6, -24(r1); \
+ std r6, -24(r1); \
+ stdu r1, -STACK_FRAME_MIN_SIZE-24(r1); \
\
li r11, API_NUMBER; \
lv1call; \
\
- addi r1, r1, 24; \
+ addi r1, r1, STACK_FRAME_MIN_SIZE+24; \
ld r11, -8(r1); \
std r4, 0(r11); \
ld r11, -16(r1); \
@@ -199,7 +209,7 @@ _GLOBAL(_##API_NAME) \
ld r11, -24(r1); \
std r6, 0(r11); \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
@@ -207,17 +217,18 @@ _GLOBAL(_##API_NAME) \
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
\
std r4, -8(r1); \
std r5, -16(r1); \
std r6, -24(r1); \
- stdu r7, -32(r1); \
+ std r7, -32(r1); \
+ stdu r1, -STACK_FRAME_MIN_SIZE-32(r1); \
\
li r11, API_NUMBER; \
lv1call; \
\
- addi r1, r1, 32; \
+ addi r1, r1, STACK_FRAME_MIN_SIZE+32; \
ld r11, -8(r1); \
std r4, 0(r11); \
ld r11, -16(r1); \
@@ -227,7 +238,7 @@ _GLOBAL(_##API_NAME) \
ld r11, -32(r1); \
std r7, 0(r11); \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
@@ -235,18 +246,19 @@ _GLOBAL(_##API_NAME) \
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
\
std r4, -8(r1); \
std r5, -16(r1); \
std r6, -24(r1); \
std r7, -32(r1); \
- stdu r8, -40(r1); \
+ std r8, -40(r1); \
+ stdu r1, -STACK_FRAME_MIN_SIZE-40(r1); \
\
li r11, API_NUMBER; \
lv1call; \
\
- addi r1, r1, 40; \
+ addi r1, r1, STACK_FRAME_MIN_SIZE+40; \
ld r11, -8(r1); \
std r4, 0(r11); \
ld r11, -16(r1); \
@@ -258,7 +270,7 @@ _GLOBAL(_##API_NAME) \
ld r11, -40(r1); \
std r8, 0(r11); \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
@@ -266,19 +278,20 @@ _GLOBAL(_##API_NAME) \
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
\
std r4, -8(r1); \
std r5, -16(r1); \
std r6, -24(r1); \
std r7, -32(r1); \
std r8, -40(r1); \
- stdu r9, -48(r1); \
+ std r9, -48(r1); \
+ stdu r1, -STACK_FRAME_MIN_SIZE-48(r1); \
\
li r11, API_NUMBER; \
lv1call; \
\
- addi r1, r1, 48; \
+ addi r1, r1, STACK_FRAME_MIN_SIZE+48; \
ld r11, -8(r1); \
std r4, 0(r11); \
ld r11, -16(r1); \
@@ -292,7 +305,7 @@ _GLOBAL(_##API_NAME) \
ld r11, -48(r1); \
std r9, 0(r11); \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
@@ -300,7 +313,7 @@ _GLOBAL(_##API_NAME) \
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
\
std r4, -8(r1); \
std r5, -16(r1); \
@@ -308,12 +321,13 @@ _GLOBAL(_##API_NAME) \
std r7, -32(r1); \
std r8, -40(r1); \
std r9, -48(r1); \
- stdu r10, -56(r1); \
+ std r10, -56(r1); \
+ stdu r1, -STACK_FRAME_MIN_SIZE-56(r1); \
\
li r11, API_NUMBER; \
lv1call; \
\
- addi r1, r1, 56; \
+ addi r1, r1, STACK_FRAME_MIN_SIZE+56; \
ld r11, -8(r1); \
std r4, 0(r11); \
ld r11, -16(r1); \
@@ -329,7 +343,7 @@ _GLOBAL(_##API_NAME) \
ld r11, -56(r1); \
std r10, 0(r11); \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
@@ -337,18 +351,19 @@ _GLOBAL(_##API_NAME) \
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
\
- stdu r5, -8(r1); \
+ std r5, -8(r1); \
+ stdu r1, -STACK_FRAME_MIN_SIZE-8(r1); \
\
li r11, API_NUMBER; \
lv1call; \
\
- addi r1, r1, 8; \
+ addi r1, r1, STACK_FRAME_MIN_SIZE+8; \
ld r11, -8(r1); \
std r4, 0(r11); \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
@@ -356,21 +371,22 @@ _GLOBAL(_##API_NAME) \
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
\
std r5, -8(r1); \
- stdu r6, -16(r1); \
+ std r6, -16(r1); \
+ stdu r1, -STACK_FRAME_MIN_SIZE-16(r1); \
\
li r11, API_NUMBER; \
lv1call; \
\
- addi r1, r1, 16; \
+ addi r1, r1, STACK_FRAME_MIN_SIZE+16; \
ld r11, -8(r1); \
std r4, 0(r11); \
ld r11, -16(r1); \
std r5, 0(r11); \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
@@ -378,16 +394,17 @@ _GLOBAL(_##API_NAME) \
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
\
std r5, -8(r1); \
std r6, -16(r1); \
- stdu r7, -24(r1); \
+ std r7, -24(r1); \
+ stdu r1, -STACK_FRAME_MIN_SIZE-24(r1); \
\
li r11, API_NUMBER; \
lv1call; \
\
- addi r1, r1, 24; \
+ addi r1, r1, STACK_FRAME_MIN_SIZE+24; \
ld r11, -8(r1); \
std r4, 0(r11); \
ld r11, -16(r1); \
@@ -395,7 +412,7 @@ _GLOBAL(_##API_NAME) \
ld r11, -24(r1); \
std r6, 0(r11); \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
@@ -403,17 +420,18 @@ _GLOBAL(_##API_NAME) \
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
\
std r5, -8(r1); \
std r6, -16(r1); \
std r7, -24(r1); \
- stdu r8, -32(r1); \
+ std r8, -32(r1); \
+ stdu r1, -STACK_FRAME_MIN_SIZE-32(r1); \
\
li r11, API_NUMBER; \
lv1call; \
\
- addi r1, r1, 32; \
+ addi r1, r1, STACK_FRAME_MIN_SIZE+32;\
ld r11, -8(r1); \
std r4, 0(r11); \
ld r11, -16(r1); \
@@ -423,7 +441,7 @@ _GLOBAL(_##API_NAME) \
ld r11, -32(r1); \
std r7, 0(r11); \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
@@ -431,18 +449,19 @@ _GLOBAL(_##API_NAME) \
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
\
std r5, -8(r1); \
std r6, -16(r1); \
std r7, -24(r1); \
std r8, -32(r1); \
- stdu r9, -40(r1); \
+ std r9, -40(r1); \
+ stdu r1, -STACK_FRAME_MIN_SIZE-40(r1); \
\
li r11, API_NUMBER; \
lv1call; \
\
- addi r1, r1, 40; \
+ addi r1, r1, STACK_FRAME_MIN_SIZE+40; \
ld r11, -8(r1); \
std r4, 0(r11); \
ld r11, -16(r1); \
@@ -454,7 +473,7 @@ _GLOBAL(_##API_NAME) \
ld r11, -40(r1); \
std r8, 0(r11); \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
@@ -462,18 +481,19 @@ _GLOBAL(_##API_NAME) \
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
\
- stdu r6, -8(r1); \
+ std r6, -8(r1); \
+ stdu r1, -STACK_FRAME_MIN_SIZE-8(r1); \
\
li r11, API_NUMBER; \
lv1call; \
\
- addi r1, r1, 8; \
+ addi r1, r1, STACK_FRAME_MIN_SIZE+8; \
ld r11, -8(r1); \
std r4, 0(r11); \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
@@ -481,21 +501,22 @@ _GLOBAL(_##API_NAME) \
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
\
std r6, -8(r1); \
- stdu r7, -16(r1); \
+ std r7, -16(r1); \
+ stdu r1, -STACK_FRAME_MIN_SIZE-16(r1); \
\
li r11, API_NUMBER; \
lv1call; \
\
- addi r1, r1, 16; \
+ addi r1, r1, STACK_FRAME_MIN_SIZE+16; \
ld r11, -8(r1); \
std r4, 0(r11); \
ld r11, -16(r1); \
std r5, 0(r11); \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
@@ -503,16 +524,17 @@ _GLOBAL(_##API_NAME) \
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
\
std r6, -8(r1); \
std r7, -16(r1); \
- stdu r8, -24(r1); \
+ std r8, -24(r1); \
+ stdu r1, -STACK_FRAME_MIN_SIZE-24(r1); \
\
li r11, API_NUMBER; \
lv1call; \
\
- addi r1, r1, 24; \
+ addi r1, r1, STACK_FRAME_MIN_SIZE+24; \
ld r11, -8(r1); \
std r4, 0(r11); \
ld r11, -16(r1); \
@@ -520,7 +542,7 @@ _GLOBAL(_##API_NAME) \
ld r11, -24(r1); \
std r6, 0(r11); \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
@@ -528,18 +550,19 @@ _GLOBAL(_##API_NAME) \
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
\
- stdu r7, -8(r1); \
+ std r7, -8(r1); \
+ stdu r1, -STACK_FRAME_MIN_SIZE-8(r1); \
\
li r11, API_NUMBER; \
lv1call; \
\
- addi r1, r1, 8; \
+ addi r1, r1, STACK_FRAME_MIN_SIZE+8; \
ld r11, -8(r1); \
std r4, 0(r11); \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
@@ -547,21 +570,22 @@ _GLOBAL(_##API_NAME) \
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
\
std r7, -8(r1); \
- stdu r8, -16(r1); \
+ std r8, -16(r1); \
+ stdu r1, -STACK_FRAME_MIN_SIZE-16(r1); \
\
li r11, API_NUMBER; \
lv1call; \
\
- addi r1, r1, 16; \
+ addi r1, r1, STACK_FRAME_MIN_SIZE+16; \
ld r11, -8(r1); \
std r4, 0(r11); \
ld r11, -16(r1); \
std r5, 0(r11); \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
@@ -569,16 +593,17 @@ _GLOBAL(_##API_NAME) \
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
\
std r7, -8(r1); \
std r8, -16(r1); \
- stdu r9, -24(r1); \
+ std r9, -24(r1); \
+ stdu r1, -STACK_FRAME_MIN_SIZE-24(r1); \
\
li r11, API_NUMBER; \
lv1call; \
\
- addi r1, r1, 24; \
+ addi r1, r1, STACK_FRAME_MIN_SIZE+24; \
ld r11, -8(r1); \
std r4, 0(r11); \
ld r11, -16(r1); \
@@ -586,7 +611,7 @@ _GLOBAL(_##API_NAME) \
ld r11, -24(r1); \
std r6, 0(r11); \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
@@ -594,18 +619,19 @@ _GLOBAL(_##API_NAME) \
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
\
- stdu r8, -8(r1); \
+ std r8, -8(r1); \
+ stdu r1, -STACK_FRAME_MIN_SIZE-8(r1); \
\
li r11, API_NUMBER; \
lv1call; \
\
- addi r1, r1, 8; \
+ addi r1, r1, STACK_FRAME_MIN_SIZE+8; \
ld r11, -8(r1); \
std r4, 0(r11); \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
@@ -613,21 +639,22 @@ _GLOBAL(_##API_NAME) \
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
\
std r8, -8(r1); \
- stdu r9, -16(r1); \
+ std r9, -16(r1); \
+ stdu r1, -STACK_FRAME_MIN_SIZE-16(r1); \
\
li r11, API_NUMBER; \
lv1call; \
\
- addi r1, r1, 16; \
+ addi r1, r1, STACK_FRAME_MIN_SIZE+16; \
ld r11, -8(r1); \
std r4, 0(r11); \
ld r11, -16(r1); \
std r5, 0(r11); \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
@@ -635,16 +662,17 @@ _GLOBAL(_##API_NAME) \
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
\
std r8, -8(r1); \
std r9, -16(r1); \
- stdu r10, -24(r1); \
+ std r10, -24(r1); \
+ stdu r1, -STACK_FRAME_MIN_SIZE-24(r1); \
\
li r11, API_NUMBER; \
lv1call; \
\
- addi r1, r1, 24; \
+ addi r1, r1, STACK_FRAME_MIN_SIZE+24; \
ld r11, -8(r1); \
std r4, 0(r11); \
ld r11, -16(r1); \
@@ -652,7 +680,7 @@ _GLOBAL(_##API_NAME) \
ld r11, -24(r1); \
std r6, 0(r11); \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
@@ -660,18 +688,19 @@ _GLOBAL(_##API_NAME) \
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
\
- stdu r9, -8(r1); \
+ std r9, -8(r1); \
+ stdu r1, -STACK_FRAME_MIN_SIZE-8(r1); \
\
li r11, API_NUMBER; \
lv1call; \
\
- addi r1, r1, 8; \
+ addi r1, r1, STACK_FRAME_MIN_SIZE+8; \
ld r11, -8(r1); \
std r4, 0(r11); \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
@@ -679,21 +708,22 @@ _GLOBAL(_##API_NAME) \
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
\
std r9, -8(r1); \
- stdu r10, -16(r1); \
+ std r10, -16(r1); \
+ stdu r1, -STACK_FRAME_MIN_SIZE-16(r1); \
\
li r11, API_NUMBER; \
lv1call; \
\
- addi r1, r1, 16; \
+ addi r1, r1, STACK_FRAME_MIN_SIZE+16; \
ld r11, -8(r1); \
std r4, 0(r11); \
ld r11, -16(r1); \
std r5, 0(r11); \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
@@ -701,23 +731,24 @@ _GLOBAL(_##API_NAME) \
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
\
std r9, -8(r1); \
- stdu r10, -16(r1); \
+ std r10, -16(r1); \
+ stdu r1, -STACK_FRAME_MIN_SIZE-16(r1); \
\
li r11, API_NUMBER; \
lv1call; \
\
- addi r1, r1, 16; \
+ addi r1, r1, STACK_FRAME_MIN_SIZE+16; \
ld r11, -8(r1); \
std r4, 0(r11); \
ld r11, -16(r1); \
std r5, 0(r11); \
- ld r11, 48+8*8(r1); \
+ ld r11, STK_PARAM_AREA+8*8(r1); \
std r6, 0(r11); \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
@@ -725,18 +756,19 @@ _GLOBAL(_##API_NAME) \
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
\
- stdu r10, -8(r1); \
+ std r10, -8(r1); \
+ stdu r1, -STACK_FRAME_MIN_SIZE-8(r1); \
\
li r11, API_NUMBER; \
lv1call; \
\
- addi r1, r1, 8; \
+ addi r1, r1, STACK_FRAME_MIN_SIZE+8; \
ld r11, -8(r1); \
std r4, 0(r11); \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
@@ -744,27 +776,29 @@ _GLOBAL(_##API_NAME) \
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
\
- std r10, 48+8*7(r1); \
+ std r10, STK_PARAM_AREA+8*7(r1); \
+ stdu r1, -STACK_FRAME_MIN_SIZE(r1); \
\
li r11, API_NUMBER; \
lv1call; \
\
- ld r11, 48+8*7(r1); \
+ addi r1, r1, STACK_FRAME_MIN_SIZE; \
+ ld r11, STK_PARAM_AREA+8*7(r1); \
std r4, 0(r11); \
- ld r11, 48+8*8(r1); \
+ ld r11, STK_PARAM_AREA+8*8(r1); \
std r5, 0(r11); \
- ld r11, 48+8*9(r1); \
+ ld r11, STK_PARAM_AREA+8*9(r1); \
std r6, 0(r11); \
- ld r11, 48+8*10(r1); \
+ ld r11, STK_PARAM_AREA+8*10(r1); \
std r7, 0(r11); \
- ld r11, 48+8*11(r1); \
+ ld r11, STK_PARAM_AREA+8*11(r1); \
std r8, 0(r11); \
- ld r11, 48+8*12(r1); \
+ ld r11, STK_PARAM_AREA+8*12(r1); \
std r9, 0(r11); \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
@@ -772,15 +806,17 @@ _GLOBAL(_##API_NAME) \
_GLOBAL(_##API_NAME) \
\
mflr r0; \
- std r0, 16(r1); \
+ std r0, LRSAVE(r1); \
+ stdu r1, -STACK_FRAME_MIN_SIZE(r1); \
\
li r11, API_NUMBER; \
lv1call; \
\
- ld r11, 48+8*8(r1); \
+ addi r1, r1, STACK_FRAME_MIN_SIZE; \
+ ld r11, STK_PARAM_AREA+8*8(r1); \
std r4, 0(r11); \
\
- ld r0, 16(r1); \
+ ld r0, LRSAVE(r1); \
mtlr r0; \
blr
diff --git a/arch/powerpc/platforms/pseries/ibmebus.c b/arch/powerpc/platforms/pseries/ibmebus.c
index 998e3aff2457..b401282727a4 100644
--- a/arch/powerpc/platforms/pseries/ibmebus.c
+++ b/arch/powerpc/platforms/pseries/ibmebus.c
@@ -55,7 +55,7 @@ static struct device ibmebus_bus_device = { /* fake "parent" device */
.init_name = "ibmebus",
};
-struct bus_type ibmebus_bus_type;
+const struct bus_type ibmebus_bus_type;
/* These devices will automatically be added to the bus during init */
static const struct of_device_id ibmebus_matches[] __initconst = {
@@ -432,7 +432,7 @@ static int ibmebus_bus_modalias(const struct device *dev, struct kobj_uevent_env
return of_device_uevent_modalias(dev, env);
}
-struct bus_type ibmebus_bus_type = {
+const struct bus_type ibmebus_bus_type = {
.name = "ibmebus",
.uevent = ibmebus_bus_modalias,
.bus_groups = ibmbus_bus_groups,
diff --git a/arch/powerpc/platforms/pseries/lparcfg.c b/arch/powerpc/platforms/pseries/lparcfg.c
index 1c151d77e74b..f73c4d1c26af 100644
--- a/arch/powerpc/platforms/pseries/lparcfg.c
+++ b/arch/powerpc/platforms/pseries/lparcfg.c
@@ -346,9 +346,13 @@ static int read_rtas_lpar_name(struct seq_file *m)
*/
static int read_dt_lpar_name(struct seq_file *m)
{
+ struct device_node *root = of_find_node_by_path("/");
const char *name;
+ int ret;
- if (of_property_read_string(of_root, "ibm,partition-name", &name))
+ ret = of_property_read_string(root, "ibm,partition-name", &name);
+ of_node_put(root);
+ if (ret)
return -ENOENT;
seq_printf(m, "partition_name=%s\n", name);
diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c
index 423ee1d5bd94..6dfb55b52d36 100644
--- a/arch/powerpc/platforms/pseries/msi.c
+++ b/arch/powerpc/platforms/pseries/msi.c
@@ -26,6 +26,7 @@ static int query_token, change_token;
#define RTAS_CHANGE_MSI_FN 3
#define RTAS_CHANGE_MSIX_FN 4
#define RTAS_CHANGE_32MSI_FN 5
+#define RTAS_CHANGE_32MSIX_FN 6
/* RTAS Helpers */
@@ -41,7 +42,7 @@ static int rtas_change_msi(struct pci_dn *pdn, u32 func, u32 num_irqs)
seq_num = 1;
do {
if (func == RTAS_CHANGE_MSI_FN || func == RTAS_CHANGE_MSIX_FN ||
- func == RTAS_CHANGE_32MSI_FN)
+ func == RTAS_CHANGE_32MSI_FN || func == RTAS_CHANGE_32MSIX_FN)
rc = rtas_call(change_token, 6, 4, rtas_ret, addr,
BUID_HI(buid), BUID_LO(buid),
func, num_irqs, seq_num);
@@ -406,8 +407,12 @@ again:
if (use_32bit_msi_hack && rc > 0)
rtas_hack_32bit_msi_gen2(pdev);
- } else
- rc = rtas_change_msi(pdn, RTAS_CHANGE_MSIX_FN, nvec);
+ } else {
+ if (pdev->no_64bit_msi)
+ rc = rtas_change_msi(pdn, RTAS_CHANGE_32MSIX_FN, nvec);
+ else
+ rc = rtas_change_msi(pdn, RTAS_CHANGE_MSIX_FN, nvec);
+ }
if (rc != nvec) {
if (nvec != nvec_in) {
diff --git a/arch/powerpc/platforms/pseries/papr_platform_attributes.c b/arch/powerpc/platforms/pseries/papr_platform_attributes.c
index 526c621b098b..eea2041b270b 100644
--- a/arch/powerpc/platforms/pseries/papr_platform_attributes.c
+++ b/arch/powerpc/platforms/pseries/papr_platform_attributes.c
@@ -101,10 +101,12 @@ retry:
esi_buf_size = ESI_HDR_SIZE + (CURR_MAX_ESI_ATTRS * max_esi_attrs);
temp_buf = krealloc(buf, esi_buf_size, GFP_KERNEL);
- if (temp_buf)
+ if (temp_buf) {
buf = temp_buf;
- else
- return -ENOMEM;
+ } else {
+ ret = -ENOMEM;
+ goto out_buf;
+ }
goto retry;
}
diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c
index 1a53e048ceb7..c233f9db039b 100644
--- a/arch/powerpc/platforms/pseries/papr_scm.c
+++ b/arch/powerpc/platforms/pseries/papr_scm.c
@@ -1521,7 +1521,7 @@ err: kfree(p);
return rc;
}
-static int papr_scm_remove(struct platform_device *pdev)
+static void papr_scm_remove(struct platform_device *pdev)
{
struct papr_scm_priv *p = platform_get_drvdata(pdev);
@@ -1538,8 +1538,6 @@ static int papr_scm_remove(struct platform_device *pdev)
pdev->archdata.priv = NULL;
kfree(p->bus_desc.provider_name);
kfree(p);
-
- return 0;
}
static const struct of_device_id papr_scm_match[] = {
@@ -1550,7 +1548,7 @@ static const struct of_device_id papr_scm_match[] = {
static struct platform_driver papr_scm_driver = {
.probe = papr_scm_probe,
- .remove = papr_scm_remove,
+ .remove_new = papr_scm_remove,
.driver = {
.name = "papr_scm",
.of_match_table = papr_scm_match,
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index ecea85c74c43..284a6fa04b0c 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -1029,9 +1029,11 @@ static void __init pseries_add_hw_description(void)
return;
}
- if (of_property_read_bool(of_root, "ibm,powervm-partition") ||
- of_property_read_bool(of_root, "ibm,fw-net-version"))
+ dn = of_find_node_by_path("/");
+ if (of_property_read_bool(dn, "ibm,powervm-partition") ||
+ of_property_read_bool(dn, "ibm,fw-net-version"))
seq_buf_printf(&ppc_hw_desc, "hv:phyp ");
+ of_node_put(dn);
}
/*
@@ -1091,7 +1093,11 @@ static void pseries_power_off(void)
static int __init pSeries_probe(void)
{
- if (!of_node_is_type(of_root, "chrp"))
+ struct device_node *root = of_find_node_by_path("/");
+ bool ret = of_node_is_type(root, "chrp");
+
+ of_node_put(root);
+ if (!ret)
return 0;
/* Cell blades firmware claims to be chrp while it's not. Until this
diff --git a/arch/powerpc/platforms/pseries/vio.c b/arch/powerpc/platforms/pseries/vio.c
index 2dc9cbc4bcd8..90ff85c879bf 100644
--- a/arch/powerpc/platforms/pseries/vio.c
+++ b/arch/powerpc/platforms/pseries/vio.c
@@ -991,18 +991,6 @@ static DEVICE_ATTR_RO(cmo_allocated);
static DEVICE_ATTR_RW(cmo_desired);
static DEVICE_ATTR_RW(cmo_allocs_failed);
-static struct attribute *vio_cmo_dev_attrs[] = {
- &dev_attr_name.attr,
- &dev_attr_devspec.attr,
- &dev_attr_modalias.attr,
- &dev_attr_cmo_entitled.attr,
- &dev_attr_cmo_allocated.attr,
- &dev_attr_cmo_desired.attr,
- &dev_attr_cmo_allocs_failed.attr,
- NULL,
-};
-ATTRIBUTE_GROUPS(vio_cmo_dev);
-
/* sysfs bus functions and data structures for CMO */
#define viobus_cmo_rd_attr(name) \
@@ -1062,11 +1050,7 @@ static struct attribute *vio_bus_attrs[] = {
};
ATTRIBUTE_GROUPS(vio_bus);
-static void __init vio_cmo_sysfs_init(void)
-{
- vio_bus_type.dev_groups = vio_cmo_dev_groups;
- vio_bus_type.bus_groups = vio_bus_groups;
-}
+static void __init vio_cmo_sysfs_init(void) { }
#else /* CONFIG_PPC_SMLPAR */
int vio_cmo_entitlement_update(size_t new_entitlement) { return 0; }
void vio_cmo_set_dev_desired(struct vio_dev *viodev, size_t desired) {}
@@ -1584,14 +1568,6 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR_RO(modalias);
-static struct attribute *vio_dev_attrs[] = {
- &dev_attr_name.attr,
- &dev_attr_devspec.attr,
- &dev_attr_modalias.attr,
- NULL,
-};
-ATTRIBUTE_GROUPS(vio_dev);
-
void vio_unregister_device(struct vio_dev *viodev)
{
device_unregister(&viodev->dev);
@@ -1626,7 +1602,39 @@ static int vio_hotplug(const struct device *dev, struct kobj_uevent_env *env)
return 0;
}
-struct bus_type vio_bus_type = {
+#ifdef CONFIG_PPC_SMLPAR
+static struct attribute *vio_cmo_dev_attrs[] = {
+ &dev_attr_name.attr,
+ &dev_attr_devspec.attr,
+ &dev_attr_modalias.attr,
+ &dev_attr_cmo_entitled.attr,
+ &dev_attr_cmo_allocated.attr,
+ &dev_attr_cmo_desired.attr,
+ &dev_attr_cmo_allocs_failed.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(vio_cmo_dev);
+
+const struct bus_type vio_bus_type = {
+ .name = "vio",
+ .dev_groups = vio_cmo_dev_groups,
+ .bus_groups = vio_bus_groups,
+ .uevent = vio_hotplug,
+ .match = vio_bus_match,
+ .probe = vio_bus_probe,
+ .remove = vio_bus_remove,
+ .shutdown = vio_bus_shutdown,
+};
+#else /* CONFIG_PPC_SMLPAR */
+static struct attribute *vio_dev_attrs[] = {
+ &dev_attr_name.attr,
+ &dev_attr_devspec.attr,
+ &dev_attr_modalias.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(vio_dev);
+
+const struct bus_type vio_bus_type = {
.name = "vio",
.dev_groups = vio_dev_groups,
.uevent = vio_hotplug,
@@ -1635,6 +1643,7 @@ struct bus_type vio_bus_type = {
.remove = vio_bus_remove,
.shutdown = vio_bus_shutdown,
};
+#endif /* CONFIG_PPC_SMLPAR */
/**
* vio_get_attribute: - get attribute for virtual device
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index 558ec68d768e..8e6c84df4ca1 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -320,7 +320,7 @@ static irqreturn_t fsl_msi_cascade(int irq, void *data)
return ret;
}
-static int fsl_of_msi_remove(struct platform_device *ofdev)
+static void fsl_of_msi_remove(struct platform_device *ofdev)
{
struct fsl_msi *msi = platform_get_drvdata(ofdev);
int virq, i;
@@ -343,8 +343,6 @@ static int fsl_of_msi_remove(struct platform_device *ofdev)
if ((msi->feature & FSL_PIC_IP_MASK) != FSL_PIC_IP_VMPIC)
iounmap(msi->msi_regs);
kfree(msi);
-
- return 0;
}
static struct lock_class_key fsl_msi_irq_class;
@@ -603,7 +601,7 @@ static struct platform_driver fsl_of_msi_driver = {
.of_match_table = fsl_of_msi_ids,
},
.probe = fsl_of_msi_probe,
- .remove = fsl_of_msi_remove,
+ .remove_new = fsl_of_msi_remove,
};
static __init int fsl_of_msi_init(void)
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index dabbdd356664..d94cf36b0f65 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -49,7 +49,7 @@
#define DBG(fmt...)
#endif
-struct bus_type mpic_subsys = {
+const struct bus_type mpic_subsys = {
.name = "mpic",
.dev_name = "mpic",
};
diff --git a/arch/powerpc/sysdev/pmi.c b/arch/powerpc/sysdev/pmi.c
index fcf8d1516210..737f97fd67d7 100644
--- a/arch/powerpc/sysdev/pmi.c
+++ b/arch/powerpc/sysdev/pmi.c
@@ -173,7 +173,7 @@ out:
return rc;
}
-static int pmi_of_remove(struct platform_device *dev)
+static void pmi_of_remove(struct platform_device *dev)
{
struct pmi_handler *handler, *tmp;
@@ -189,13 +189,11 @@ static int pmi_of_remove(struct platform_device *dev)
kfree(data);
data = NULL;
-
- return 0;
}
static struct platform_driver pmi_of_platform_driver = {
.probe = pmi_of_probe,
- .remove = pmi_of_remove,
+ .remove_new = pmi_of_remove,
.driver = {
.name = "pmi",
.of_match_table = pmi_match,
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index b3b94cd37713..d79d6633f333 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -643,10 +643,8 @@ static int xmon_core(struct pt_regs *regs, volatile int fromipi)
touch_nmi_watchdog();
} else {
cmd = 1;
-#ifdef CONFIG_SMP
if (xmon_batch)
cmd = batch_cmds(regs);
-#endif
if (!locked_down && cmd)
cmd = cmds(regs);
if (locked_down || cmd != 0) {
@@ -1820,8 +1818,8 @@ static void print_bug_trap(struct pt_regs *regs)
const struct bug_entry *bug;
unsigned long addr;
- if (regs->msr & MSR_PR)
- return; /* not in kernel */
+ if (user_mode(regs))
+ return;
addr = regs->nip; /* address of trap instruction */
if (!is_kernel_addr(addr))
return;
@@ -3342,7 +3340,7 @@ static void show_pte(unsigned long addr)
return;
}
- if (p4d_is_leaf(*p4dp)) {
+ if (p4d_leaf(*p4dp)) {
format_pte(p4dp, p4d_val(*p4dp));
return;
}
@@ -3356,7 +3354,7 @@ static void show_pte(unsigned long addr)
return;
}
- if (pud_is_leaf(*pudp)) {
+ if (pud_leaf(*pudp)) {
format_pte(pudp, pud_val(*pudp));
return;
}
@@ -3370,7 +3368,7 @@ static void show_pte(unsigned long addr)
return;
}
- if (pmd_is_leaf(*pmdp)) {
+ if (pmd_leaf(*pmdp)) {
format_pte(pmdp, pmd_val(*pmdp));
return;
}
diff --git a/arch/riscv/Kbuild b/arch/riscv/Kbuild
index d25ad1c19f88..2c585f7a0b6e 100644
--- a/arch/riscv/Kbuild
+++ b/arch/riscv/Kbuild
@@ -2,6 +2,7 @@
obj-y += kernel/ mm/ net/
obj-$(CONFIG_BUILTIN_DTB) += boot/dts/
+obj-$(CONFIG_CRYPTO) += crypto/
obj-y += errata/
obj-$(CONFIG_KVM) += kvm/
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index e3142ce531a0..be09c8836d56 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -27,17 +27,21 @@ config RISCV
select ARCH_HAS_GCOV_PROFILE_ALL
select ARCH_HAS_GIGANTIC_PAGE
select ARCH_HAS_KCOV
+ 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_SPECIAL
select ARCH_HAS_SET_DIRECT_MAP if MMU
select ARCH_HAS_SET_MEMORY if MMU
select ARCH_HAS_STRICT_KERNEL_RWX if MMU && !XIP_KERNEL
select ARCH_HAS_STRICT_MODULE_RWX if MMU && !XIP_KERNEL
+ select ARCH_HAS_SYNC_CORE_BEFORE_USERMODE
select ARCH_HAS_SYSCALL_WRAPPER
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
- select ARCH_HAS_UBSAN_SANITIZE_ALL
+ select ARCH_HAS_UBSAN
select ARCH_HAS_VDSO_DATA
select ARCH_KEEP_MEMBLOCK if ACPI
select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX
@@ -47,6 +51,9 @@ config RISCV
select ARCH_SUPPORTS_CFI_CLANG
select ARCH_SUPPORTS_DEBUG_PAGEALLOC if MMU
select ARCH_SUPPORTS_HUGETLBFS if MMU
+ # LLD >= 14: https://github.com/llvm/llvm-project/issues/50505
+ select ARCH_SUPPORTS_LTO_CLANG if LLD_VERSION >= 140000
+ select ARCH_SUPPORTS_LTO_CLANG_THIN if LLD_VERSION >= 140000
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
@@ -106,6 +113,7 @@ config RISCV
select HAVE_ARCH_KGDB_QXFER_PKT
select HAVE_ARCH_MMAP_RND_BITS if MMU
select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT
+ select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET
select HAVE_ARCH_SECCOMP_FILTER
select HAVE_ARCH_THREAD_STRUCT_WHITELIST
select HAVE_ARCH_TRACEHOOK
@@ -124,6 +132,7 @@ config RISCV
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_FUNCTION_ARG_ACCESS_API
select HAVE_FUNCTION_ERROR_INJECTION
select HAVE_GCC_PLUGINS
@@ -136,6 +145,7 @@ config RISCV
select HAVE_LD_DEAD_CODE_DATA_ELIMINATION if !LD_IS_LLD
select HAVE_MOVE_PMD
select HAVE_MOVE_PUD
+ select HAVE_PAGE_SIZE_4KB
select HAVE_PCI
select HAVE_PERF_EVENTS
select HAVE_PERF_REGS
@@ -154,6 +164,7 @@ config RISCV
select IRQ_FORCED_THREADING
select KASAN_VMALLOC if KASAN
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
@@ -174,8 +185,6 @@ config RISCV
config CLANG_SUPPORTS_DYNAMIC_FTRACE
def_bool CC_IS_CLANG
- # https://github.com/llvm/llvm-project/commit/6ab8927931851bb42b2c93a00801dc499d7d9b1e
- depends on CLANG_VERSION >= 130000
# https://github.com/ClangBuiltLinux/linux/issues/1817
depends on AS_IS_GNU || (AS_IS_LLVM && (LD_IS_LLD || LD_VERSION >= 23600))
@@ -312,7 +321,7 @@ config AS_HAS_INSN
def_bool $(as-instr,.insn r 51$(comma) 0$(comma) 0$(comma) t0$(comma) t0$(comma) zero)
config AS_HAS_OPTION_ARCH
- # https://reviews.llvm.org/D123515
+ # https://github.com/llvm/llvm-project/commit/9e8ed3403c191ab9c4903e8eeb8f732ff8a43cb4
def_bool y
depends on $(as-instr, .option arch$(comma) +m)
@@ -577,6 +586,13 @@ config TOOLCHAIN_HAS_ZBB
depends on LLD_VERSION >= 150000 || LD_VERSION >= 23900
depends on AS_HAS_OPTION_ARCH
+# This symbol indicates that the toolchain supports all v1.0 vector crypto
+# extensions, including Zvk*, Zvbb, and Zvbc. LLVM added all of these at once.
+# binutils added all except Zvkb, then added Zvkb. So we just check for Zvkb.
+config TOOLCHAIN_HAS_VECTOR_CRYPTO
+ def_bool $(as-instr, .option arch$(comma) +v$(comma) +zvkb)
+ depends on AS_HAS_OPTION_ARCH
+
config RISCV_ISA_ZBB
bool "Zbb extension support for bit manipulation instructions"
depends on TOOLCHAIN_HAS_ZBB
@@ -687,27 +703,61 @@ config THREAD_SIZE_ORDER
affects irq stack size, which is equal to thread stack size.
config RISCV_MISALIGNED
- bool "Support misaligned load/store traps for kernel and userspace"
+ bool
select SYSCTL_ARCH_UNALIGN_ALLOW
- default y
help
- Say Y here if you want the kernel to embed support for misaligned
- load/store for both kernel and userspace. When disable, misaligned
- accesses will generate SIGBUS in userspace and panic in kernel.
+ Embed support for emulating misaligned loads and stores.
+
+choice
+ prompt "Unaligned Accesses Support"
+ default RISCV_PROBE_UNALIGNED_ACCESS
+ help
+ This determines the level of support for unaligned accesses. This
+ information is used by the kernel to perform optimizations. It is also
+ exposed to user space via the hwprobe syscall. The hardware will be
+ probed at boot by default.
+
+config RISCV_PROBE_UNALIGNED_ACCESS
+ bool "Probe for hardware unaligned access support"
+ select RISCV_MISALIGNED
+ help
+ During boot, the kernel will run a series of tests to determine the
+ speed of unaligned accesses. This probing will dynamically determine
+ the speed of unaligned accesses on the underlying system. If unaligned
+ memory accesses trap into the kernel as they are not supported by the
+ system, the kernel will emulate the unaligned accesses to preserve the
+ UABI.
+
+config RISCV_EMULATED_UNALIGNED_ACCESS
+ bool "Emulate unaligned access where system support is missing"
+ select RISCV_MISALIGNED
+ help
+ If unaligned memory accesses trap into the kernel as they are not
+ supported by the system, the kernel will emulate the unaligned
+ accesses to preserve the UABI. When the underlying system does support
+ unaligned accesses, the unaligned accesses are assumed to be slow.
+
+config RISCV_SLOW_UNALIGNED_ACCESS
+ bool "Assume the system supports slow unaligned memory accesses"
+ depends on NONPORTABLE
+ help
+ Assume that the system supports slow unaligned memory accesses. The
+ kernel and userspace programs may not be able to run at all on systems
+ that do not support unaligned memory accesses.
config RISCV_EFFICIENT_UNALIGNED_ACCESS
- bool "Assume the CPU supports fast unaligned memory accesses"
+ bool "Assume the system supports fast unaligned memory accesses"
depends on NONPORTABLE
select DCACHE_WORD_ACCESS if MMU
select HAVE_EFFICIENT_UNALIGNED_ACCESS
help
- Say Y here if you want the kernel to assume that the CPU supports
- efficient unaligned memory accesses. When enabled, this option
- improves the performance of the kernel on such CPUs. However, the
- kernel will run much more slowly, or will not be able to run at all,
- on CPUs that do not support efficient unaligned memory accesses.
+ Assume that the system supports fast unaligned memory accesses. When
+ enabled, this option improves the performance of the kernel on such
+ systems. However, the kernel and userspace programs will run much more
+ slowly, or will not be able to run at all, on systems that do not
+ support efficient unaligned memory accesses.
- If unsure what to do here, say N.
+endchoice
endmenu # "Platform type"
@@ -766,7 +816,7 @@ config ARCH_SUPPORTS_CRASH_DUMP
def_bool y
config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
- def_bool CRASH_CORE
+ def_bool CRASH_RESERVE
config COMPAT
bool "Kernel support for 32-bit U-mode"
@@ -982,7 +1032,19 @@ config RISCV_ISA_FALLBACK
config BUILTIN_DTB
bool "Built-in device tree"
depends on OF && NONPORTABLE
- default y if XIP_KERNEL
+ help
+ Build a device tree into the Linux image.
+ This option should be selected if no bootloader is being used.
+ If unsure, say N.
+
+
+config BUILTIN_DTB_SOURCE
+ string "Built-in device tree source"
+ depends on BUILTIN_DTB
+ help
+ DTS file path (without suffix, relative to arch/riscv/boot/dts)
+ for the DTS file that will be used to produce the DTB linked into the
+ kernel.
endmenu # "Boot options"
@@ -1000,11 +1062,8 @@ menu "Power management options"
source "kernel/power/Kconfig"
-# Hibernation is only possible on systems where the SBI implementation has
-# marked its reserved memory as not accessible from, or does not run
-# from the same memory as, Linux
config ARCH_HIBERNATION_POSSIBLE
- def_bool NONPORTABLE
+ def_bool y
config ARCH_HIBERNATION_HEADER
def_bool HIBERNATION
diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
index e08e91c49abe..623de5f8a208 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -84,36 +84,4 @@ config SOC_CANAAN
help
This enables support for Canaan Kendryte K210 SoC platform hardware.
-if ARCH_CANAAN
-
-config ARCH_CANAAN_K210_DTB_BUILTIN
- def_bool SOC_CANAAN_K210_DTB_BUILTIN
-
-config SOC_CANAAN_K210_DTB_BUILTIN
- bool "Builtin device tree for the Canaan Kendryte K210"
- depends on ARCH_CANAAN
- default y
- select OF
- select BUILTIN_DTB
- help
- Build a device tree for the Kendryte K210 into the Linux image.
- This option should be selected if no bootloader is being used.
- If unsure, say Y.
-
-config ARCH_CANAAN_K210_DTB_SOURCE
- string
- default SOC_CANAAN_K210_DTB_SOURCE
-
-config SOC_CANAAN_K210_DTB_SOURCE
- string "Source file for the Canaan Kendryte K210 builtin DTB"
- depends on ARCH_CANAAN
- depends on ARCH_CANAAN_K210_DTB_BUILTIN
- default "k210_generic"
- help
- Base name (without suffix, relative to arch/riscv/boot/dts/canaan)
- for the DTS file that will be used to produce the DTB linked into the
- kernel.
-
-endif # ARCH_CANAAN
-
endmenu # "SoC selection"
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index 0b7d109258e7..5b3115a19852 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -50,6 +50,11 @@ ifndef CONFIG_AS_IS_LLVM
KBUILD_CFLAGS += -Wa,-mno-relax
KBUILD_AFLAGS += -Wa,-mno-relax
endif
+# LLVM has an issue with target-features and LTO: https://github.com/llvm/llvm-project/issues/59350
+# Ensure it is aware of linker relaxation with LTO, otherwise relocations may
+# be incorrect: https://github.com/llvm/llvm-project/issues/65090
+else ifeq ($(CONFIG_LTO_CLANG),y)
+ KBUILD_LDFLAGS += -mllvm -mattr=+c -mllvm -mattr=+relax
endif
ifeq ($(CONFIG_SHADOW_CALL_STACK),y)
@@ -146,7 +151,7 @@ endif
endif
vdso-install-y += arch/riscv/kernel/vdso/vdso.so.dbg
-vdso-install-$(CONFIG_COMPAT) += arch/riscv/kernel/compat_vdso/compat_vdso.so.dbg:../compat_vdso/compat_vdso.so
+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)
diff --git a/arch/riscv/boot/dts/Makefile b/arch/riscv/boot/dts/Makefile
index 72030fd727af..fdae05bbf556 100644
--- a/arch/riscv/boot/dts/Makefile
+++ b/arch/riscv/boot/dts/Makefile
@@ -8,4 +8,4 @@ subdir-y += sophgo
subdir-y += starfive
subdir-y += thead
-obj-$(CONFIG_BUILTIN_DTB) := $(addsuffix /, $(subdir-y))
+obj-$(CONFIG_BUILTIN_DTB) := $(addsuffix .dtb.o, $(CONFIG_BUILTIN_DTB_SOURCE))
diff --git a/arch/riscv/boot/dts/canaan/Makefile b/arch/riscv/boot/dts/canaan/Makefile
index 520623264c87..987d1f0c41f0 100644
--- a/arch/riscv/boot/dts/canaan/Makefile
+++ b/arch/riscv/boot/dts/canaan/Makefile
@@ -5,5 +5,3 @@ dtb-$(CONFIG_ARCH_CANAAN) += sipeed_maix_bit.dtb
dtb-$(CONFIG_ARCH_CANAAN) += sipeed_maix_dock.dtb
dtb-$(CONFIG_ARCH_CANAAN) += sipeed_maix_go.dtb
dtb-$(CONFIG_ARCH_CANAAN) += sipeed_maixduino.dtb
-
-obj-$(CONFIG_ARCH_CANAAN_K210_DTB_BUILTIN) += $(addsuffix .dtb.o, $(CONFIG_ARCH_CANAAN_K210_DTB_SOURCE))
diff --git a/arch/riscv/boot/dts/microchip/Makefile b/arch/riscv/boot/dts/microchip/Makefile
index 45adc4926e79..e177815bf1a2 100644
--- a/arch/riscv/boot/dts/microchip/Makefile
+++ b/arch/riscv/boot/dts/microchip/Makefile
@@ -4,4 +4,3 @@ dtb-$(CONFIG_ARCH_MICROCHIP_POLARFIRE) += mpfs-m100pfsevp.dtb
dtb-$(CONFIG_ARCH_MICROCHIP_POLARFIRE) += mpfs-polarberry.dtb
dtb-$(CONFIG_ARCH_MICROCHIP_POLARFIRE) += mpfs-sev-kit.dtb
dtb-$(CONFIG_ARCH_MICROCHIP_POLARFIRE) += mpfs-tysom-m.dtb
-obj-$(CONFIG_BUILTIN_DTB) += $(addsuffix .o, $(dtb-y))
diff --git a/arch/riscv/boot/dts/microchip/mpfs.dtsi b/arch/riscv/boot/dts/microchip/mpfs.dtsi
index 59fd2d4ea523..9883ca3554c5 100644
--- a/arch/riscv/boot/dts/microchip/mpfs.dtsi
+++ b/arch/riscv/boot/dts/microchip/mpfs.dtsi
@@ -243,7 +243,7 @@
};
pdma: dma-controller@3000000 {
- compatible = "sifive,fu540-c000-pdma", "sifive,pdma0";
+ compatible = "microchip,mpfs-pdma", "sifive,pdma0";
reg = <0x0 0x3000000 0x0 0x8000>;
interrupt-parent = <&plic>;
interrupts = <5 6>, <7 8>, <9 10>, <11 12>;
@@ -422,7 +422,7 @@
can0: can@2010c000 {
compatible = "microchip,mpfs-can";
reg = <0x0 0x2010c000 0x0 0x1000>;
- clocks = <&clkcfg CLK_CAN0>;
+ clocks = <&clkcfg CLK_CAN0>, <&clkcfg CLK_MSSPLL3>;
interrupt-parent = <&plic>;
interrupts = <56>;
status = "disabled";
@@ -431,7 +431,7 @@
can1: can@2010d000 {
compatible = "microchip,mpfs-can";
reg = <0x0 0x2010d000 0x0 0x1000>;
- clocks = <&clkcfg CLK_CAN1>;
+ clocks = <&clkcfg CLK_CAN1>, <&clkcfg CLK_MSSPLL3>;
interrupt-parent = <&plic>;
interrupts = <57>;
status = "disabled";
diff --git a/arch/riscv/boot/dts/renesas/r9a07g043f.dtsi b/arch/riscv/boot/dts/renesas/r9a07g043f.dtsi
index a92cfcfc021b..f35324b9173c 100644
--- a/arch/riscv/boot/dts/renesas/r9a07g043f.dtsi
+++ b/arch/riscv/boot/dts/renesas/r9a07g043f.dtsi
@@ -27,7 +27,7 @@
riscv,isa-base = "rv64i";
riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
"zicntr", "zicsr", "zifencei",
- "zihpm";
+ "zihpm", "xandespmu";
mmu-type = "riscv,sv39";
i-cache-size = <0x8000>;
i-cache-line-size = <0x40>;
@@ -39,13 +39,17 @@
cpu0_intc: interrupt-controller {
#interrupt-cells = <1>;
- compatible = "riscv,cpu-intc";
+ compatible = "andestech,cpu-intc", "riscv,cpu-intc";
interrupt-controller;
};
};
};
};
+&pinctrl {
+ gpio-ranges = <&pinctrl 0 0 232>;
+};
+
&soc {
dma-noncoherent;
interrupt-parent = <&plic>;
diff --git a/arch/riscv/boot/dts/sifive/Makefile b/arch/riscv/boot/dts/sifive/Makefile
index 6a5fbd4ed96a..495bf760a909 100644
--- a/arch/riscv/boot/dts/sifive/Makefile
+++ b/arch/riscv/boot/dts/sifive/Makefile
@@ -1,4 +1,3 @@
# SPDX-License-Identifier: GPL-2.0
dtb-$(CONFIG_ARCH_SIFIVE) += hifive-unleashed-a00.dtb \
hifive-unmatched-a00.dtb
-obj-$(CONFIG_BUILTIN_DTB) += $(addsuffix .o, $(dtb-y))
diff --git a/arch/riscv/boot/dts/sophgo/sg2042.dtsi b/arch/riscv/boot/dts/sophgo/sg2042.dtsi
index ead1cc35d88b..81fda312f988 100644
--- a/arch/riscv/boot/dts/sophgo/sg2042.dtsi
+++ b/arch/riscv/boot/dts/sophgo/sg2042.dtsi
@@ -6,6 +6,8 @@
/dts-v1/;
#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/reset/sophgo,sg2042-reset.h>
+
#include "sg2042-cpus.dtsi"
/ {
@@ -327,6 +329,12 @@
riscv,ndev = <224>;
};
+ rstgen: reset-controller@7030013000 {
+ compatible = "sophgo,sg2042-reset";
+ reg = <0x00000070 0x30013000 0x00000000 0x0000000c>;
+ #reset-cells = <1>;
+ };
+
uart0: serial@7040000000 {
compatible = "snps,dw-apb-uart";
reg = <0x00000070 0x40000000 0x00000000 0x00001000>;
@@ -335,6 +343,7 @@
clock-frequency = <500000000>;
reg-shift = <2>;
reg-io-width = <4>;
+ resets = <&rstgen RST_UART0>;
status = "disabled";
};
};
diff --git a/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts b/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts
index 7cda3a89020a..168f5d9895a9 100644
--- a/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts
+++ b/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts
@@ -11,3 +11,14 @@
model = "BeagleV Starlight Beta";
compatible = "beagle,beaglev-starlight-jh7100-r0", "starfive,jh7100";
};
+
+&gmac {
+ phy-handle = <&phy>;
+};
+
+&mdio {
+ phy: ethernet-phy@7 {
+ reg = <7>;
+ reset-gpios = <&gpio 63 GPIO_ACTIVE_LOW>;
+ };
+};
diff --git a/arch/riscv/boot/dts/starfive/jh7100-common.dtsi b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
index 42fb61c36068..ae1a6aeb0aea 100644
--- a/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
@@ -72,7 +72,91 @@
};
};
+&gmac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gmac_pins>;
+ phy-mode = "rgmii-id";
+ status = "okay";
+
+ mdio: mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,dwmac-mdio";
+ };
+};
+
&gpio {
+ gmac_pins: gmac-0 {
+ gtxclk-pins {
+ pins = <PAD_FUNC_SHARE(115)>;
+ bias-pull-up;
+ drive-strength = <35>;
+ input-enable;
+ input-schmitt-enable;
+ slew-rate = <0>;
+ };
+ miitxclk-pins {
+ pins = <PAD_FUNC_SHARE(116)>;
+ bias-pull-up;
+ drive-strength = <14>;
+ input-enable;
+ input-schmitt-disable;
+ slew-rate = <0>;
+ };
+ tx-pins {
+ pins = <PAD_FUNC_SHARE(117)>,
+ <PAD_FUNC_SHARE(119)>,
+ <PAD_FUNC_SHARE(120)>,
+ <PAD_FUNC_SHARE(121)>,
+ <PAD_FUNC_SHARE(122)>,
+ <PAD_FUNC_SHARE(123)>,
+ <PAD_FUNC_SHARE(124)>,
+ <PAD_FUNC_SHARE(125)>,
+ <PAD_FUNC_SHARE(126)>;
+ bias-pull-up;
+ drive-strength = <35>;
+ input-disable;
+ input-schmitt-disable;
+ slew-rate = <0>;
+ };
+ rxclk-pins {
+ pins = <PAD_FUNC_SHARE(127)>;
+ bias-pull-up;
+ drive-strength = <14>;
+ input-enable;
+ input-schmitt-disable;
+ slew-rate = <6>;
+ };
+ rxer-pins {
+ pins = <PAD_FUNC_SHARE(129)>;
+ bias-pull-up;
+ drive-strength = <14>;
+ input-enable;
+ input-schmitt-disable;
+ slew-rate = <0>;
+ };
+ rx-pins {
+ pins = <PAD_FUNC_SHARE(128)>,
+ <PAD_FUNC_SHARE(130)>,
+ <PAD_FUNC_SHARE(131)>,
+ <PAD_FUNC_SHARE(132)>,
+ <PAD_FUNC_SHARE(133)>,
+ <PAD_FUNC_SHARE(134)>,
+ <PAD_FUNC_SHARE(135)>,
+ <PAD_FUNC_SHARE(136)>,
+ <PAD_FUNC_SHARE(137)>,
+ <PAD_FUNC_SHARE(138)>,
+ <PAD_FUNC_SHARE(139)>,
+ <PAD_FUNC_SHARE(140)>,
+ <PAD_FUNC_SHARE(141)>;
+ bias-pull-up;
+ drive-strength = <14>;
+ input-enable;
+ input-schmitt-enable;
+ slew-rate = <0>;
+ };
+ };
+
i2c0_pins: i2c0-0 {
i2c-pins {
pinmux = <GPIOMUX(62, GPO_LOW,
@@ -115,6 +199,24 @@
};
};
+ pwm_pins: pwm-0 {
+ pwm-pins {
+ pinmux = <GPIOMUX(7,
+ GPO_PWM_PAD_OUT_BIT0,
+ GPO_PWM_PAD_OE_N_BIT0,
+ GPI_NONE)>,
+ <GPIOMUX(5,
+ GPO_PWM_PAD_OUT_BIT1,
+ GPO_PWM_PAD_OE_N_BIT1,
+ GPI_NONE)>;
+ bias-disable;
+ drive-strength = <35>;
+ input-disable;
+ input-schmitt-disable;
+ slew-rate = <0>;
+ };
+ };
+
sdio0_pins: sdio0-0 {
clk-pins {
pinmux = <GPIOMUX(54, GPO_SDIO0_PAD_CCLK_OUT,
@@ -257,6 +359,12 @@
clock-frequency = <27000000>;
};
+&pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm_pins>;
+ status = "okay";
+};
+
&sdio0 {
broken-cd;
bus-width = <4>;
diff --git a/arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts b/arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts
index e82af72f1aaf..692c696e1ab4 100644
--- a/arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts
+++ b/arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts
@@ -6,7 +6,6 @@
/dts-v1/;
#include "jh7100-common.dtsi"
-#include <dt-bindings/gpio/gpio.h>
/ {
model = "StarFive VisionFive V1";
@@ -18,3 +17,24 @@
priority = <224>;
};
};
+
+&gmac {
+ phy-handle = <&phy>;
+};
+
+/*
+ * The board uses a Motorcomm YT8521 PHY supporting RGMII-ID, but requires
+ * manual adjustment of the RX internal delay to work properly. The default
+ * RX delay provided by the driver (1.95ns) is too high, but applying a 50%
+ * reduction seems to mitigate the issue.
+ *
+ * It is worth noting the adjustment is not necessary on BeagleV Starlight SBC,
+ * which uses a Microchip PHY. Hence, most likely the Motorcomm PHY is the one
+ * responsible for the misbehaviour, not the GMAC.
+ */
+&mdio {
+ phy: ethernet-phy@0 {
+ reg = <0>;
+ rx-internal-delay-ps = <900>;
+ };
+};
diff --git a/arch/riscv/boot/dts/starfive/jh7100.dtsi b/arch/riscv/boot/dts/starfive/jh7100.dtsi
index 8bcf36d07f3f..9a2e9583af88 100644
--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
@@ -116,6 +116,7 @@
osc_sys: osc-sys {
compatible = "fixed-clock";
#clock-cells = <0>;
+ clock-output-names = "osc_sys";
/* This value must be overridden by the board */
clock-frequency = <0>;
};
@@ -123,6 +124,7 @@
osc_aud: osc-aud {
compatible = "fixed-clock";
#clock-cells = <0>;
+ clock-output-names = "osc_aud";
/* This value must be overridden by the board */
clock-frequency = <0>;
};
@@ -130,6 +132,7 @@
gmac_rmii_ref: gmac-rmii-ref {
compatible = "fixed-clock";
#clock-cells = <0>;
+ clock-output-names = "gmac_rmii_ref";
/* Should be overridden by the board when needed */
clock-frequency = <0>;
};
@@ -137,6 +140,7 @@
gmac_gr_mii_rxclk: gmac-gr-mii-rxclk {
compatible = "fixed-clock";
#clock-cells = <0>;
+ clock-output-names = "gmac_gr_mii_rxclk";
/* Should be overridden by the board when needed */
clock-frequency = <0>;
};
@@ -204,6 +208,37 @@
status = "disabled";
};
+ gmac: ethernet@10020000 {
+ compatible = "starfive,jh7100-dwmac", "snps,dwmac";
+ reg = <0x0 0x10020000 0x0 0x10000>;
+ clocks = <&clkgen JH7100_CLK_GMAC_ROOT_DIV>,
+ <&clkgen JH7100_CLK_GMAC_AHB>,
+ <&clkgen JH7100_CLK_GMAC_PTP_REF>,
+ <&clkgen JH7100_CLK_GMAC_TX_INV>,
+ <&clkgen JH7100_CLK_GMAC_GTX>;
+ clock-names = "stmmaceth", "pclk", "ptp_ref", "tx", "gtx";
+ resets = <&rstgen JH7100_RSTN_GMAC_AHB>;
+ reset-names = "ahb";
+ interrupts = <6>, <7>;
+ interrupt-names = "macirq", "eth_wake_irq";
+ max-frame-size = <9000>;
+ snps,multicast-filter-bins = <32>;
+ snps,perfect-filter-entries = <128>;
+ starfive,syscon = <&sysmain 0x70 0>;
+ rx-fifo-depth = <32768>;
+ tx-fifo-depth = <16384>;
+ snps,axi-config = <&stmmac_axi_setup>;
+ snps,fixed-burst;
+ snps,force_thresh_dma_mode;
+ status = "disabled";
+
+ stmmac_axi_setup: stmmac-axi-config {
+ snps,wr_osr_lmt = <16>;
+ snps,rd_osr_lmt = <16>;
+ snps,blen = <256 128 64 32 0 0 0>;
+ };
+ };
+
clkgen: clock-controller@11800000 {
compatible = "starfive,jh7100-clkgen";
reg = <0x0 0x11800000 0x0 0x10000>;
@@ -218,6 +253,11 @@
#reset-cells = <1>;
};
+ sysmain: syscon@11850000 {
+ compatible = "starfive,jh7100-sysmain", "syscon";
+ reg = <0x0 0x11850000 0x0 0x10000>;
+ };
+
i2c0: i2c@118b0000 {
compatible = "snps,designware-i2c";
reg = <0x0 0x118b0000 0x0 0x10000>;
@@ -320,6 +360,15 @@
<&rstgen JH7100_RSTN_WDT>;
};
+ pwm: pwm@12490000 {
+ compatible = "starfive,jh7100-pwm", "opencores,pwm-v1";
+ reg = <0x0 0x12490000 0x0 0x10000>;
+ clocks = <&clkgen JH7100_CLK_PWM_APB>;
+ resets = <&rstgen JH7100_RSTN_PWM_APB>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
sfctemp: temperature-sensor@124a0000 {
compatible = "starfive,jh7100-temp";
reg = <0x0 0x124a0000 0x0 0x10000>;
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 b89e9791efa7..45b58b6f3df8 100644
--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
@@ -125,6 +125,55 @@
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";
@@ -323,6 +372,12 @@
};
};
+&pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm_pins>;
+ status = "okay";
+};
+
&spi0 {
pinctrl-names = "default";
pinctrl-0 = <&spi0_pins>;
@@ -513,6 +568,22 @@
};
};
+ 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,
diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
index 74ed3b9264d8..4a5708f7fcf7 100644
--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
@@ -829,6 +829,15 @@
status = "disabled";
};
+ pwm: pwm@120d0000 {
+ compatible = "starfive,jh7110-pwm", "opencores,pwm-v1";
+ reg = <0x0 0x120d0000 0x0 0x10000>;
+ clocks = <&syscrg JH7110_SYSCLK_PWM_APB>;
+ resets = <&syscrg JH7110_SYSRST_PWM_APB>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
sfctemp: temperature-sensor@120e0000 {
compatible = "starfive,jh7110-temp";
reg = <0x0 0x120e0000 0x0 0x10000>;
@@ -1104,6 +1113,32 @@
#power-domain-cells = <1>;
};
+ csi2rx: csi@19800000 {
+ compatible = "starfive,jh7110-csi2rx", "cdns,csi2rx";
+ reg = <0x0 0x19800000 0x0 0x10000>;
+ clocks = <&ispcrg JH7110_ISPCLK_VIN_SYS>,
+ <&ispcrg JH7110_ISPCLK_VIN_APB>,
+ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF0>,
+ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF1>,
+ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF2>,
+ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF3>;
+ clock-names = "sys_clk", "p_clk",
+ "pixel_if0_clk", "pixel_if1_clk",
+ "pixel_if2_clk", "pixel_if3_clk";
+ resets = <&ispcrg JH7110_ISPRST_VIN_SYS>,
+ <&ispcrg JH7110_ISPRST_VIN_APB>,
+ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF0>,
+ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF1>,
+ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF2>,
+ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF3>;
+ reset-names = "sys", "reg_bank",
+ "pixel_if0", "pixel_if1",
+ "pixel_if2", "pixel_if3";
+ phys = <&csi_phy>;
+ phy-names = "dphy";
+ status = "disabled";
+ };
+
ispcrg: clock-controller@19810000 {
compatible = "starfive,jh7110-ispcrg";
reg = <0x0 0x19810000 0x0 0x10000>;
@@ -1121,6 +1156,47 @@
power-domains = <&pwrc JH7110_PD_ISP>;
};
+ csi_phy: phy@19820000 {
+ compatible = "starfive,jh7110-dphy-rx";
+ reg = <0x0 0x19820000 0x0 0x10000>;
+ clocks = <&ispcrg JH7110_ISPCLK_M31DPHY_CFG_IN>,
+ <&ispcrg JH7110_ISPCLK_M31DPHY_REF_IN>,
+ <&ispcrg JH7110_ISPCLK_M31DPHY_TX_ESC_LAN0>;
+ clock-names = "cfg", "ref", "tx";
+ resets = <&ispcrg JH7110_ISPRST_M31DPHY_HW>,
+ <&ispcrg JH7110_ISPRST_M31DPHY_B09_AON>;
+ power-domains = <&aon_syscon JH7110_AON_PD_DPHY_RX>;
+ #phy-cells = <0>;
+ };
+
+ camss: isp@19840000 {
+ compatible = "starfive,jh7110-camss";
+ reg = <0x0 0x19840000 0x0 0x10000>,
+ <0x0 0x19870000 0x0 0x30000>;
+ reg-names = "syscon", "isp";
+ clocks = <&ispcrg JH7110_ISPCLK_DOM4_APB_FUNC>,
+ <&ispcrg JH7110_ISPCLK_ISPV2_TOP_WRAPPER_C>,
+ <&ispcrg JH7110_ISPCLK_DVP_INV>,
+ <&ispcrg JH7110_ISPCLK_VIN_P_AXI_WR>,
+ <&ispcrg JH7110_ISPCLK_MIPI_RX0_PXL>,
+ <&syscrg JH7110_SYSCLK_ISP_TOP_CORE>,
+ <&syscrg JH7110_SYSCLK_ISP_TOP_AXI>;
+ clock-names = "apb_func", "wrapper_clk_c", "dvp_inv",
+ "axiwr", "mipi_rx0_pxl", "ispcore_2x",
+ "isp_axi";
+ resets = <&ispcrg JH7110_ISPRST_ISPV2_TOP_WRAPPER_P>,
+ <&ispcrg JH7110_ISPRST_ISPV2_TOP_WRAPPER_C>,
+ <&ispcrg JH7110_ISPRST_VIN_P_AXI_RD>,
+ <&ispcrg JH7110_ISPRST_VIN_P_AXI_WR>,
+ <&syscrg JH7110_SYSRST_ISP_TOP>,
+ <&syscrg JH7110_SYSRST_ISP_TOP_AXI>;
+ reset-names = "wrapper_p", "wrapper_c", "axird",
+ "axiwr", "isp_top_n", "isp_top_axi";
+ power-domains = <&pwrc JH7110_PD_ISP>;
+ interrupts = <92>, <87>, <90>, <88>;
+ status = "disabled";
+ };
+
voutcrg: clock-controller@295c0000 {
compatible = "starfive,jh7110-voutcrg";
reg = <0x0 0x295c0000 0x0 0x10000>;
diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig
index eaf34e871e30..fc0ec2ee13bc 100644
--- a/arch/riscv/configs/defconfig
+++ b/arch/riscv/configs/defconfig
@@ -44,6 +44,7 @@ CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
CONFIG_CPUFREQ_DT=y
+CONFIG_ACPI_CPPC_CPUFREQ=m
CONFIG_VIRTUALIZATION=y
CONFIG_KVM=m
CONFIG_ACPI=y
@@ -215,6 +216,7 @@ CONFIG_MMC=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_CADENCE=y
+CONFIG_MMC_SDHCI_OF_DWCMSHC=y
CONFIG_MMC_SPI=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_STARFIVE=y
@@ -224,6 +226,7 @@ CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_SUN6I=y
CONFIG_DMADEVICES=y
CONFIG_DMA_SUN6I=m
+CONFIG_DW_AXI_DMAC=y
CONFIG_RZ_DMAC=y
CONFIG_VIRTIO_PCI=y
CONFIG_VIRTIO_BALLOON=y
diff --git a/arch/riscv/configs/nommu_k210_defconfig b/arch/riscv/configs/nommu_k210_defconfig
index 146c46d0525b..7e75200543f4 100644
--- a/arch/riscv/configs/nommu_k210_defconfig
+++ b/arch/riscv/configs/nommu_k210_defconfig
@@ -33,6 +33,8 @@ CONFIG_SMP=y
CONFIG_NR_CPUS=2
CONFIG_CMDLINE="earlycon console=ttySIF0"
CONFIG_CMDLINE_FORCE=y
+CONFIG_BUILTIN_DTB=y
+CONFIG_BUILTIN_DTB_SOURCE="canaan/k210_generic"
# CONFIG_SECCOMP is not set
# CONFIG_STACKPROTECTOR is not set
# CONFIG_GCC_PLUGINS is not set
diff --git a/arch/riscv/configs/nommu_k210_sdcard_defconfig b/arch/riscv/configs/nommu_k210_sdcard_defconfig
index 95d8d1808f19..0ba353e9ca71 100644
--- a/arch/riscv/configs/nommu_k210_sdcard_defconfig
+++ b/arch/riscv/configs/nommu_k210_sdcard_defconfig
@@ -25,6 +25,8 @@ CONFIG_SMP=y
CONFIG_NR_CPUS=2
CONFIG_CMDLINE="earlycon console=ttySIF0 root=/dev/mmcblk0p1 rootwait ro"
CONFIG_CMDLINE_FORCE=y
+CONFIG_BUILTIN_DTB=y
+CONFIG_BUILTIN_DTB_SOURCE="canaan/k210_generic"
# CONFIG_SECCOMP is not set
# CONFIG_STACKPROTECTOR is not set
# CONFIG_GCC_PLUGINS is not set
diff --git a/arch/riscv/crypto/Kconfig b/arch/riscv/crypto/Kconfig
new file mode 100644
index 000000000000..ad58dad9a580
--- /dev/null
+++ b/arch/riscv/crypto/Kconfig
@@ -0,0 +1,93 @@
+# SPDX-License-Identifier: GPL-2.0
+
+menu "Accelerated Cryptographic Algorithms for CPU (riscv)"
+
+config CRYPTO_AES_RISCV64
+ tristate "Ciphers: AES, modes: ECB, CBC, CTS, CTR, XTS"
+ depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
+ select CRYPTO_ALGAPI
+ select CRYPTO_LIB_AES
+ select CRYPTO_SKCIPHER
+ help
+ Block cipher: AES cipher algorithms
+ Length-preserving ciphers: AES with ECB, CBC, CTS, CTR, XTS
+
+ Architecture: riscv64 using:
+ - Zvkned vector crypto extension
+ - Zvbb vector extension (XTS)
+ - Zvkb vector crypto extension (CTR)
+ - Zvkg vector crypto extension (XTS)
+
+config CRYPTO_CHACHA_RISCV64
+ tristate "Ciphers: ChaCha"
+ depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
+ select CRYPTO_SKCIPHER
+ select CRYPTO_LIB_CHACHA_GENERIC
+ help
+ Length-preserving ciphers: ChaCha20 stream cipher algorithm
+
+ Architecture: riscv64 using:
+ - Zvkb vector crypto extension
+
+config CRYPTO_GHASH_RISCV64
+ tristate "Hash functions: GHASH"
+ depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
+ select CRYPTO_GCM
+ help
+ GCM GHASH function (NIST SP 800-38D)
+
+ Architecture: riscv64 using:
+ - Zvkg vector crypto extension
+
+config CRYPTO_SHA256_RISCV64
+ tristate "Hash functions: SHA-224 and SHA-256"
+ depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
+ select CRYPTO_SHA256
+ help
+ SHA-224 and SHA-256 secure hash algorithm (FIPS 180)
+
+ Architecture: riscv64 using:
+ - Zvknha or Zvknhb vector crypto extensions
+ - Zvkb vector crypto extension
+
+config CRYPTO_SHA512_RISCV64
+ tristate "Hash functions: SHA-384 and SHA-512"
+ depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
+ select CRYPTO_SHA512
+ help
+ SHA-384 and SHA-512 secure hash algorithm (FIPS 180)
+
+ Architecture: riscv64 using:
+ - Zvknhb vector crypto extension
+ - Zvkb vector crypto extension
+
+config CRYPTO_SM3_RISCV64
+ tristate "Hash functions: SM3 (ShangMi 3)"
+ depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
+ select CRYPTO_HASH
+ select CRYPTO_SM3
+ help
+ SM3 (ShangMi 3) secure hash function (OSCCA GM/T 0004-2012)
+
+ Architecture: riscv64 using:
+ - Zvksh vector crypto extension
+ - Zvkb vector crypto extension
+
+config CRYPTO_SM4_RISCV64
+ tristate "Ciphers: SM4 (ShangMi 4)"
+ depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
+ select CRYPTO_ALGAPI
+ select CRYPTO_SM4
+ help
+ SM4 block cipher algorithm (OSCCA GB/T 32907-2016,
+ ISO/IEC 18033-3:2010/Amd 1:2021)
+
+ SM4 (GBT.32907-2016) is a cryptographic standard issued by the
+ Organization of State Commercial Administration of China (OSCCA)
+ as an authorized cryptographic algorithm for use within China.
+
+ Architecture: riscv64 using:
+ - Zvksed vector crypto extension
+ - Zvkb vector crypto extension
+
+endmenu
diff --git a/arch/riscv/crypto/Makefile b/arch/riscv/crypto/Makefile
new file mode 100644
index 000000000000..247c7bc7288c
--- /dev/null
+++ b/arch/riscv/crypto/Makefile
@@ -0,0 +1,23 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+obj-$(CONFIG_CRYPTO_AES_RISCV64) += aes-riscv64.o
+aes-riscv64-y := aes-riscv64-glue.o aes-riscv64-zvkned.o \
+ aes-riscv64-zvkned-zvbb-zvkg.o aes-riscv64-zvkned-zvkb.o
+
+obj-$(CONFIG_CRYPTO_CHACHA_RISCV64) += chacha-riscv64.o
+chacha-riscv64-y := chacha-riscv64-glue.o chacha-riscv64-zvkb.o
+
+obj-$(CONFIG_CRYPTO_GHASH_RISCV64) += ghash-riscv64.o
+ghash-riscv64-y := ghash-riscv64-glue.o ghash-riscv64-zvkg.o
+
+obj-$(CONFIG_CRYPTO_SHA256_RISCV64) += sha256-riscv64.o
+sha256-riscv64-y := sha256-riscv64-glue.o sha256-riscv64-zvknha_or_zvknhb-zvkb.o
+
+obj-$(CONFIG_CRYPTO_SHA512_RISCV64) += sha512-riscv64.o
+sha512-riscv64-y := sha512-riscv64-glue.o sha512-riscv64-zvknhb-zvkb.o
+
+obj-$(CONFIG_CRYPTO_SM3_RISCV64) += sm3-riscv64.o
+sm3-riscv64-y := sm3-riscv64-glue.o sm3-riscv64-zvksh-zvkb.o
+
+obj-$(CONFIG_CRYPTO_SM4_RISCV64) += sm4-riscv64.o
+sm4-riscv64-y := sm4-riscv64-glue.o sm4-riscv64-zvksed-zvkb.o
diff --git a/arch/riscv/crypto/aes-macros.S b/arch/riscv/crypto/aes-macros.S
new file mode 100644
index 000000000000..d1a258d04bc7
--- /dev/null
+++ b/arch/riscv/crypto/aes-macros.S
@@ -0,0 +1,156 @@
+/* SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause */
+//
+// This file is dual-licensed, meaning that you can use it under your
+// choice of either of the following two licenses:
+//
+// Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
+//
+// Licensed under the Apache License 2.0 (the "License"). You can obtain
+// a copy in the file LICENSE in the source distribution or at
+// https://www.openssl.org/source/license.html
+//
+// or
+//
+// Copyright (c) 2023, Christoph Müllner <christoph.muellner@vrull.eu>
+// Copyright (c) 2023, Phoebe Chen <phoebe.chen@sifive.com>
+// Copyright (c) 2023, Jerry Shih <jerry.shih@sifive.com>
+// Copyright 2024 Google LLC
+// All rights reserved.
+//
+// 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
+// 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.
+
+// This file contains macros that are shared by the other aes-*.S files. The
+// generated code of these macros depends on the following RISC-V extensions:
+// - RV64I
+// - RISC-V Vector ('V') with VLEN >= 128
+// - RISC-V Vector AES block cipher extension ('Zvkned')
+
+// Loads the AES round keys from \keyp into vector registers and jumps to code
+// specific to the length of the key. Specifically:
+// - If AES-128, loads round keys into v1-v11 and jumps to \label128.
+// - If AES-192, loads round keys into v1-v13 and jumps to \label192.
+// - If AES-256, loads round keys into v1-v15 and continues onwards.
+//
+// Also sets vl=4 and vtype=e32,m1,ta,ma. Clobbers t0 and t1.
+.macro aes_begin keyp, label128, label192
+ lwu t0, 480(\keyp) // t0 = key length in bytes
+ li t1, 24 // t1 = key length for AES-192
+ vsetivli zero, 4, e32, m1, ta, ma
+ vle32.v v1, (\keyp)
+ addi \keyp, \keyp, 16
+ vle32.v v2, (\keyp)
+ addi \keyp, \keyp, 16
+ vle32.v v3, (\keyp)
+ addi \keyp, \keyp, 16
+ vle32.v v4, (\keyp)
+ addi \keyp, \keyp, 16
+ vle32.v v5, (\keyp)
+ addi \keyp, \keyp, 16
+ vle32.v v6, (\keyp)
+ addi \keyp, \keyp, 16
+ vle32.v v7, (\keyp)
+ addi \keyp, \keyp, 16
+ vle32.v v8, (\keyp)
+ addi \keyp, \keyp, 16
+ vle32.v v9, (\keyp)
+ addi \keyp, \keyp, 16
+ vle32.v v10, (\keyp)
+ addi \keyp, \keyp, 16
+ vle32.v v11, (\keyp)
+ blt t0, t1, \label128 // If AES-128, goto label128.
+ addi \keyp, \keyp, 16
+ vle32.v v12, (\keyp)
+ addi \keyp, \keyp, 16
+ vle32.v v13, (\keyp)
+ beq t0, t1, \label192 // If AES-192, goto label192.
+ // Else, it's AES-256.
+ addi \keyp, \keyp, 16
+ vle32.v v14, (\keyp)
+ addi \keyp, \keyp, 16
+ vle32.v v15, (\keyp)
+.endm
+
+// Encrypts \data using zvkned instructions, using the round keys loaded into
+// v1-v11 (for AES-128), v1-v13 (for AES-192), or v1-v15 (for AES-256). \keylen
+// is the AES key length in bits. vl and vtype must already be set
+// appropriately. Note that if vl > 4, multiple blocks are encrypted.
+.macro aes_encrypt data, keylen
+ vaesz.vs \data, v1
+ vaesem.vs \data, v2
+ vaesem.vs \data, v3
+ vaesem.vs \data, v4
+ vaesem.vs \data, v5
+ vaesem.vs \data, v6
+ vaesem.vs \data, v7
+ vaesem.vs \data, v8
+ vaesem.vs \data, v9
+ vaesem.vs \data, v10
+.if \keylen == 128
+ vaesef.vs \data, v11
+.elseif \keylen == 192
+ vaesem.vs \data, v11
+ vaesem.vs \data, v12
+ vaesef.vs \data, v13
+.else
+ vaesem.vs \data, v11
+ vaesem.vs \data, v12
+ vaesem.vs \data, v13
+ vaesem.vs \data, v14
+ vaesef.vs \data, v15
+.endif
+.endm
+
+// Same as aes_encrypt, but decrypts instead of encrypts.
+.macro aes_decrypt data, keylen
+.if \keylen == 128
+ vaesz.vs \data, v11
+.elseif \keylen == 192
+ vaesz.vs \data, v13
+ vaesdm.vs \data, v12
+ vaesdm.vs \data, v11
+.else
+ vaesz.vs \data, v15
+ vaesdm.vs \data, v14
+ vaesdm.vs \data, v13
+ vaesdm.vs \data, v12
+ vaesdm.vs \data, v11
+.endif
+ vaesdm.vs \data, v10
+ vaesdm.vs \data, v9
+ vaesdm.vs \data, v8
+ vaesdm.vs \data, v7
+ vaesdm.vs \data, v6
+ vaesdm.vs \data, v5
+ vaesdm.vs \data, v4
+ vaesdm.vs \data, v3
+ vaesdm.vs \data, v2
+ vaesdf.vs \data, v1
+.endm
+
+// Expands to aes_encrypt or aes_decrypt according to \enc, which is 1 or 0.
+.macro aes_crypt data, enc, keylen
+.if \enc
+ aes_encrypt \data, \keylen
+.else
+ aes_decrypt \data, \keylen
+.endif
+.endm
diff --git a/arch/riscv/crypto/aes-riscv64-glue.c b/arch/riscv/crypto/aes-riscv64-glue.c
new file mode 100644
index 000000000000..f814ee048555
--- /dev/null
+++ b/arch/riscv/crypto/aes-riscv64-glue.c
@@ -0,0 +1,637 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * AES using the RISC-V vector crypto extensions. Includes the bare block
+ * cipher and the ECB, CBC, CBC-CTS, CTR, and XTS modes.
+ *
+ * Copyright (C) 2023 VRULL GmbH
+ * Author: Heiko Stuebner <heiko.stuebner@vrull.eu>
+ *
+ * Copyright (C) 2023 SiFive, Inc.
+ * Author: Jerry Shih <jerry.shih@sifive.com>
+ *
+ * Copyright 2024 Google LLC
+ */
+
+#include <asm/simd.h>
+#include <asm/vector.h>
+#include <crypto/aes.h>
+#include <crypto/internal/cipher.h>
+#include <crypto/internal/simd.h>
+#include <crypto/internal/skcipher.h>
+#include <crypto/scatterwalk.h>
+#include <crypto/xts.h>
+#include <linux/linkage.h>
+#include <linux/module.h>
+
+asmlinkage void aes_encrypt_zvkned(const struct crypto_aes_ctx *key,
+ const u8 in[AES_BLOCK_SIZE],
+ u8 out[AES_BLOCK_SIZE]);
+asmlinkage void aes_decrypt_zvkned(const struct crypto_aes_ctx *key,
+ const u8 in[AES_BLOCK_SIZE],
+ u8 out[AES_BLOCK_SIZE]);
+
+asmlinkage void aes_ecb_encrypt_zvkned(const struct crypto_aes_ctx *key,
+ const u8 *in, u8 *out, size_t len);
+asmlinkage void aes_ecb_decrypt_zvkned(const struct crypto_aes_ctx *key,
+ const u8 *in, u8 *out, size_t len);
+
+asmlinkage void aes_cbc_encrypt_zvkned(const struct crypto_aes_ctx *key,
+ const u8 *in, u8 *out, size_t len,
+ u8 iv[AES_BLOCK_SIZE]);
+asmlinkage void aes_cbc_decrypt_zvkned(const struct crypto_aes_ctx *key,
+ const u8 *in, u8 *out, size_t len,
+ u8 iv[AES_BLOCK_SIZE]);
+
+asmlinkage void aes_cbc_cts_crypt_zvkned(const struct crypto_aes_ctx *key,
+ const u8 *in, u8 *out, size_t len,
+ const u8 iv[AES_BLOCK_SIZE], bool enc);
+
+asmlinkage void aes_ctr32_crypt_zvkned_zvkb(const struct crypto_aes_ctx *key,
+ const u8 *in, u8 *out, size_t len,
+ u8 iv[AES_BLOCK_SIZE]);
+
+asmlinkage void aes_xts_encrypt_zvkned_zvbb_zvkg(
+ const struct crypto_aes_ctx *key,
+ const u8 *in, u8 *out, size_t len,
+ u8 tweak[AES_BLOCK_SIZE]);
+
+asmlinkage void aes_xts_decrypt_zvkned_zvbb_zvkg(
+ const struct crypto_aes_ctx *key,
+ const u8 *in, u8 *out, size_t len,
+ u8 tweak[AES_BLOCK_SIZE]);
+
+static int riscv64_aes_setkey(struct crypto_aes_ctx *ctx,
+ const u8 *key, unsigned int keylen)
+{
+ /*
+ * For now we just use the generic key expansion, for these reasons:
+ *
+ * - zvkned's key expansion instructions don't support AES-192.
+ * So, non-zvkned fallback code would be needed anyway.
+ *
+ * - Users of AES in Linux usually don't change keys frequently.
+ * So, key expansion isn't performance-critical.
+ *
+ * - For single-block AES exposed as a "cipher" algorithm, it's
+ * necessary to use struct crypto_aes_ctx and initialize its 'key_dec'
+ * field with the round keys for the Equivalent Inverse Cipher. This
+ * is because with "cipher", decryption can be requested from a
+ * context where the vector unit isn't usable, necessitating a
+ * fallback to aes_decrypt(). But, zvkned can only generate and use
+ * the normal round keys. Of course, it's preferable to not have
+ * special code just for "cipher", as e.g. XTS also uses a
+ * single-block AES encryption. It's simplest to just use
+ * struct crypto_aes_ctx and aes_expandkey() everywhere.
+ */
+ return aes_expandkey(ctx, key, keylen);
+}
+
+static int riscv64_aes_setkey_cipher(struct crypto_tfm *tfm,
+ const u8 *key, unsigned int keylen)
+{
+ struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ return riscv64_aes_setkey(ctx, key, keylen);
+}
+
+static int riscv64_aes_setkey_skcipher(struct crypto_skcipher *tfm,
+ const u8 *key, unsigned int keylen)
+{
+ struct crypto_aes_ctx *ctx = crypto_skcipher_ctx(tfm);
+
+ return riscv64_aes_setkey(ctx, key, keylen);
+}
+
+/* Bare AES, without a mode of operation */
+
+static void riscv64_aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+{
+ const struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ if (crypto_simd_usable()) {
+ kernel_vector_begin();
+ aes_encrypt_zvkned(ctx, src, dst);
+ kernel_vector_end();
+ } else {
+ aes_encrypt(ctx, dst, src);
+ }
+}
+
+static void riscv64_aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+{
+ const struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ if (crypto_simd_usable()) {
+ kernel_vector_begin();
+ aes_decrypt_zvkned(ctx, src, dst);
+ kernel_vector_end();
+ } else {
+ aes_decrypt(ctx, dst, src);
+ }
+}
+
+/* AES-ECB */
+
+static inline int riscv64_aes_ecb_crypt(struct skcipher_request *req, bool enc)
+{
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ const struct crypto_aes_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct skcipher_walk walk;
+ unsigned int nbytes;
+ int err;
+
+ err = skcipher_walk_virt(&walk, req, false);
+ while ((nbytes = walk.nbytes) != 0) {
+ kernel_vector_begin();
+ if (enc)
+ aes_ecb_encrypt_zvkned(ctx, walk.src.virt.addr,
+ walk.dst.virt.addr,
+ nbytes & ~(AES_BLOCK_SIZE - 1));
+ else
+ aes_ecb_decrypt_zvkned(ctx, walk.src.virt.addr,
+ walk.dst.virt.addr,
+ nbytes & ~(AES_BLOCK_SIZE - 1));
+ kernel_vector_end();
+ err = skcipher_walk_done(&walk, nbytes & (AES_BLOCK_SIZE - 1));
+ }
+
+ return err;
+}
+
+static int riscv64_aes_ecb_encrypt(struct skcipher_request *req)
+{
+ return riscv64_aes_ecb_crypt(req, true);
+}
+
+static int riscv64_aes_ecb_decrypt(struct skcipher_request *req)
+{
+ return riscv64_aes_ecb_crypt(req, false);
+}
+
+/* AES-CBC */
+
+static int riscv64_aes_cbc_crypt(struct skcipher_request *req, bool enc)
+{
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ const struct crypto_aes_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct skcipher_walk walk;
+ unsigned int nbytes;
+ int err;
+
+ err = skcipher_walk_virt(&walk, req, false);
+ while ((nbytes = walk.nbytes) != 0) {
+ kernel_vector_begin();
+ if (enc)
+ aes_cbc_encrypt_zvkned(ctx, walk.src.virt.addr,
+ walk.dst.virt.addr,
+ nbytes & ~(AES_BLOCK_SIZE - 1),
+ walk.iv);
+ else
+ aes_cbc_decrypt_zvkned(ctx, walk.src.virt.addr,
+ walk.dst.virt.addr,
+ nbytes & ~(AES_BLOCK_SIZE - 1),
+ walk.iv);
+ kernel_vector_end();
+ err = skcipher_walk_done(&walk, nbytes & (AES_BLOCK_SIZE - 1));
+ }
+
+ return err;
+}
+
+static int riscv64_aes_cbc_encrypt(struct skcipher_request *req)
+{
+ return riscv64_aes_cbc_crypt(req, true);
+}
+
+static int riscv64_aes_cbc_decrypt(struct skcipher_request *req)
+{
+ return riscv64_aes_cbc_crypt(req, false);
+}
+
+/* AES-CBC-CTS */
+
+static int riscv64_aes_cbc_cts_crypt(struct skcipher_request *req, bool enc)
+{
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ const struct crypto_aes_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct scatterlist sg_src[2], sg_dst[2];
+ struct skcipher_request subreq;
+ struct scatterlist *src, *dst;
+ struct skcipher_walk walk;
+ unsigned int cbc_len;
+ int err;
+
+ if (req->cryptlen < AES_BLOCK_SIZE)
+ return -EINVAL;
+
+ err = skcipher_walk_virt(&walk, req, false);
+ if (err)
+ return err;
+ /*
+ * If the full message is available in one step, decrypt it in one call
+ * to the CBC-CTS assembly function. This reduces overhead, especially
+ * on short messages. Otherwise, fall back to doing CBC up to the last
+ * two blocks, then invoke CTS just for the ciphertext stealing.
+ */
+ if (unlikely(walk.nbytes != req->cryptlen)) {
+ cbc_len = round_down(req->cryptlen - AES_BLOCK_SIZE - 1,
+ AES_BLOCK_SIZE);
+ skcipher_walk_abort(&walk);
+ 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,
+ cbc_len, req->iv);
+ err = riscv64_aes_cbc_crypt(&subreq, enc);
+ if (err)
+ return err;
+ dst = src = scatterwalk_ffwd(sg_src, req->src, cbc_len);
+ if (req->dst != req->src)
+ dst = scatterwalk_ffwd(sg_dst, req->dst, cbc_len);
+ skcipher_request_set_crypt(&subreq, src, dst,
+ req->cryptlen - cbc_len, req->iv);
+ err = skcipher_walk_virt(&walk, &subreq, false);
+ if (err)
+ return err;
+ }
+ kernel_vector_begin();
+ aes_cbc_cts_crypt_zvkned(ctx, walk.src.virt.addr, walk.dst.virt.addr,
+ walk.nbytes, req->iv, enc);
+ kernel_vector_end();
+ return skcipher_walk_done(&walk, 0);
+}
+
+static int riscv64_aes_cbc_cts_encrypt(struct skcipher_request *req)
+{
+ return riscv64_aes_cbc_cts_crypt(req, true);
+}
+
+static int riscv64_aes_cbc_cts_decrypt(struct skcipher_request *req)
+{
+ return riscv64_aes_cbc_cts_crypt(req, false);
+}
+
+/* AES-CTR */
+
+static int riscv64_aes_ctr_crypt(struct skcipher_request *req)
+{
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ const struct crypto_aes_ctx *ctx = crypto_skcipher_ctx(tfm);
+ unsigned int nbytes, p1_nbytes;
+ struct skcipher_walk walk;
+ u32 ctr32, nblocks;
+ int err;
+
+ /* Get the low 32-bit word of the 128-bit big endian counter. */
+ ctr32 = get_unaligned_be32(req->iv + 12);
+
+ err = skcipher_walk_virt(&walk, req, false);
+ while ((nbytes = walk.nbytes) != 0) {
+ if (nbytes < walk.total) {
+ /* Not the end yet, so keep the length block-aligned. */
+ nbytes = round_down(nbytes, AES_BLOCK_SIZE);
+ nblocks = nbytes / AES_BLOCK_SIZE;
+ } else {
+ /* It's the end, so include any final partial block. */
+ nblocks = DIV_ROUND_UP(nbytes, AES_BLOCK_SIZE);
+ }
+ ctr32 += nblocks;
+
+ kernel_vector_begin();
+ if (ctr32 >= nblocks) {
+ /* The low 32-bit word of the counter won't overflow. */
+ aes_ctr32_crypt_zvkned_zvkb(ctx, walk.src.virt.addr,
+ walk.dst.virt.addr, nbytes,
+ req->iv);
+ } else {
+ /*
+ * The low 32-bit word of the counter will overflow.
+ * The assembly doesn't handle this case, so split the
+ * operation into two at the point where the overflow
+ * will occur. After the first part, add the carry bit.
+ */
+ p1_nbytes = min_t(unsigned int, nbytes,
+ (nblocks - ctr32) * AES_BLOCK_SIZE);
+ aes_ctr32_crypt_zvkned_zvkb(ctx, walk.src.virt.addr,
+ walk.dst.virt.addr,
+ p1_nbytes, req->iv);
+ crypto_inc(req->iv, 12);
+
+ if (ctr32) {
+ aes_ctr32_crypt_zvkned_zvkb(
+ ctx,
+ walk.src.virt.addr + p1_nbytes,
+ walk.dst.virt.addr + p1_nbytes,
+ nbytes - p1_nbytes, req->iv);
+ }
+ }
+ kernel_vector_end();
+
+ err = skcipher_walk_done(&walk, walk.nbytes - nbytes);
+ }
+
+ return err;
+}
+
+/* AES-XTS */
+
+struct riscv64_aes_xts_ctx {
+ struct crypto_aes_ctx ctx1;
+ struct crypto_aes_ctx ctx2;
+};
+
+static int riscv64_aes_xts_setkey(struct crypto_skcipher *tfm, const u8 *key,
+ unsigned int keylen)
+{
+ struct riscv64_aes_xts_ctx *ctx = crypto_skcipher_ctx(tfm);
+
+ return xts_verify_key(tfm, key, keylen) ?:
+ riscv64_aes_setkey(&ctx->ctx1, key, keylen / 2) ?:
+ riscv64_aes_setkey(&ctx->ctx2, key + keylen / 2, keylen / 2);
+}
+
+static int riscv64_aes_xts_crypt(struct skcipher_request *req, bool enc)
+{
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ const struct riscv64_aes_xts_ctx *ctx = crypto_skcipher_ctx(tfm);
+ int tail = req->cryptlen % AES_BLOCK_SIZE;
+ struct scatterlist sg_src[2], sg_dst[2];
+ struct skcipher_request subreq;
+ struct scatterlist *src, *dst;
+ struct skcipher_walk walk;
+ int err;
+
+ if (req->cryptlen < AES_BLOCK_SIZE)
+ return -EINVAL;
+
+ /* Encrypt the IV with the tweak key to get the first tweak. */
+ kernel_vector_begin();
+ aes_encrypt_zvkned(&ctx->ctx2, req->iv, req->iv);
+ kernel_vector_end();
+
+ err = skcipher_walk_virt(&walk, req, false);
+
+ /*
+ * If the message length isn't divisible by the AES block size and the
+ * full message isn't available in one step of the scatterlist walk,
+ * 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 (unlikely(tail > 0 && walk.nbytes < walk.total)) {
+ skcipher_walk_abort(&walk);
+
+ 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,
+ req->cryptlen - tail - AES_BLOCK_SIZE,
+ req->iv);
+ req = &subreq;
+ err = skcipher_walk_virt(&walk, req, false);
+ } else {
+ tail = 0;
+ }
+
+ while (walk.nbytes) {
+ unsigned int nbytes = walk.nbytes;
+
+ if (nbytes < walk.total)
+ nbytes = round_down(nbytes, AES_BLOCK_SIZE);
+
+ kernel_vector_begin();
+ if (enc)
+ aes_xts_encrypt_zvkned_zvbb_zvkg(
+ &ctx->ctx1, walk.src.virt.addr,
+ walk.dst.virt.addr, nbytes, req->iv);
+ else
+ aes_xts_decrypt_zvkned_zvbb_zvkg(
+ &ctx->ctx1, walk.src.virt.addr,
+ walk.dst.virt.addr, nbytes, req->iv);
+ kernel_vector_end();
+ err = skcipher_walk_done(&walk, walk.nbytes - nbytes);
+ }
+
+ if (err || likely(!tail))
+ return err;
+
+ /* Do ciphertext stealing with the last full block and partial block. */
+
+ dst = src = scatterwalk_ffwd(sg_src, req->src, req->cryptlen);
+ if (req->dst != req->src)
+ dst = scatterwalk_ffwd(sg_dst, req->dst, req->cryptlen);
+
+ skcipher_request_set_crypt(req, src, dst, AES_BLOCK_SIZE + tail,
+ req->iv);
+
+ err = skcipher_walk_virt(&walk, req, false);
+ if (err)
+ return err;
+
+ kernel_vector_begin();
+ if (enc)
+ aes_xts_encrypt_zvkned_zvbb_zvkg(
+ &ctx->ctx1, walk.src.virt.addr,
+ walk.dst.virt.addr, walk.nbytes, req->iv);
+ else
+ aes_xts_decrypt_zvkned_zvbb_zvkg(
+ &ctx->ctx1, walk.src.virt.addr,
+ walk.dst.virt.addr, walk.nbytes, req->iv);
+ kernel_vector_end();
+
+ return skcipher_walk_done(&walk, 0);
+}
+
+static int riscv64_aes_xts_encrypt(struct skcipher_request *req)
+{
+ return riscv64_aes_xts_crypt(req, true);
+}
+
+static int riscv64_aes_xts_decrypt(struct skcipher_request *req)
+{
+ return riscv64_aes_xts_crypt(req, false);
+}
+
+/* Algorithm definitions */
+
+static struct crypto_alg riscv64_zvkned_aes_cipher_alg = {
+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct crypto_aes_ctx),
+ .cra_priority = 300,
+ .cra_name = "aes",
+ .cra_driver_name = "aes-riscv64-zvkned",
+ .cra_cipher = {
+ .cia_min_keysize = AES_MIN_KEY_SIZE,
+ .cia_max_keysize = AES_MAX_KEY_SIZE,
+ .cia_setkey = riscv64_aes_setkey_cipher,
+ .cia_encrypt = riscv64_aes_encrypt,
+ .cia_decrypt = riscv64_aes_decrypt,
+ },
+ .cra_module = THIS_MODULE,
+};
+
+static struct skcipher_alg riscv64_zvkned_aes_skcipher_algs[] = {
+ {
+ .setkey = riscv64_aes_setkey_skcipher,
+ .encrypt = riscv64_aes_ecb_encrypt,
+ .decrypt = riscv64_aes_ecb_decrypt,
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .walksize = 8 * AES_BLOCK_SIZE, /* matches LMUL=8 */
+ .base = {
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct crypto_aes_ctx),
+ .cra_priority = 300,
+ .cra_name = "ecb(aes)",
+ .cra_driver_name = "ecb-aes-riscv64-zvkned",
+ .cra_module = THIS_MODULE,
+ },
+ }, {
+ .setkey = riscv64_aes_setkey_skcipher,
+ .encrypt = riscv64_aes_cbc_encrypt,
+ .decrypt = riscv64_aes_cbc_decrypt,
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .base = {
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct crypto_aes_ctx),
+ .cra_priority = 300,
+ .cra_name = "cbc(aes)",
+ .cra_driver_name = "cbc-aes-riscv64-zvkned",
+ .cra_module = THIS_MODULE,
+ },
+ }, {
+ .setkey = riscv64_aes_setkey_skcipher,
+ .encrypt = riscv64_aes_cbc_cts_encrypt,
+ .decrypt = riscv64_aes_cbc_cts_decrypt,
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .walksize = 4 * AES_BLOCK_SIZE, /* matches LMUL=4 */
+ .base = {
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct crypto_aes_ctx),
+ .cra_priority = 300,
+ .cra_name = "cts(cbc(aes))",
+ .cra_driver_name = "cts-cbc-aes-riscv64-zvkned",
+ .cra_module = THIS_MODULE,
+ },
+ }
+};
+
+static struct skcipher_alg riscv64_zvkned_zvkb_aes_skcipher_alg = {
+ .setkey = riscv64_aes_setkey_skcipher,
+ .encrypt = riscv64_aes_ctr_crypt,
+ .decrypt = riscv64_aes_ctr_crypt,
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .chunksize = AES_BLOCK_SIZE,
+ .walksize = 4 * AES_BLOCK_SIZE, /* matches LMUL=4 */
+ .base = {
+ .cra_blocksize = 1,
+ .cra_ctxsize = sizeof(struct crypto_aes_ctx),
+ .cra_priority = 300,
+ .cra_name = "ctr(aes)",
+ .cra_driver_name = "ctr-aes-riscv64-zvkned-zvkb",
+ .cra_module = THIS_MODULE,
+ },
+};
+
+static struct skcipher_alg riscv64_zvkned_zvbb_zvkg_aes_skcipher_alg = {
+ .setkey = riscv64_aes_xts_setkey,
+ .encrypt = riscv64_aes_xts_encrypt,
+ .decrypt = riscv64_aes_xts_decrypt,
+ .min_keysize = 2 * AES_MIN_KEY_SIZE,
+ .max_keysize = 2 * AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .chunksize = AES_BLOCK_SIZE,
+ .walksize = 4 * AES_BLOCK_SIZE, /* matches LMUL=4 */
+ .base = {
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct riscv64_aes_xts_ctx),
+ .cra_priority = 300,
+ .cra_name = "xts(aes)",
+ .cra_driver_name = "xts-aes-riscv64-zvkned-zvbb-zvkg",
+ .cra_module = THIS_MODULE,
+ },
+};
+
+static inline bool riscv64_aes_xts_supported(void)
+{
+ return riscv_isa_extension_available(NULL, ZVBB) &&
+ riscv_isa_extension_available(NULL, ZVKG) &&
+ riscv_vector_vlen() < 2048 /* Implementation limitation */;
+}
+
+static int __init riscv64_aes_mod_init(void)
+{
+ int err = -ENODEV;
+
+ if (riscv_isa_extension_available(NULL, ZVKNED) &&
+ riscv_vector_vlen() >= 128) {
+ err = crypto_register_alg(&riscv64_zvkned_aes_cipher_alg);
+ if (err)
+ return err;
+
+ err = crypto_register_skciphers(
+ riscv64_zvkned_aes_skcipher_algs,
+ ARRAY_SIZE(riscv64_zvkned_aes_skcipher_algs));
+ if (err)
+ goto unregister_zvkned_cipher_alg;
+
+ if (riscv_isa_extension_available(NULL, ZVKB)) {
+ err = crypto_register_skcipher(
+ &riscv64_zvkned_zvkb_aes_skcipher_alg);
+ if (err)
+ goto unregister_zvkned_skcipher_algs;
+ }
+
+ if (riscv64_aes_xts_supported()) {
+ err = crypto_register_skcipher(
+ &riscv64_zvkned_zvbb_zvkg_aes_skcipher_alg);
+ if (err)
+ goto unregister_zvkned_zvkb_skcipher_alg;
+ }
+ }
+
+ return err;
+
+unregister_zvkned_zvkb_skcipher_alg:
+ if (riscv_isa_extension_available(NULL, ZVKB))
+ crypto_unregister_skcipher(&riscv64_zvkned_zvkb_aes_skcipher_alg);
+unregister_zvkned_skcipher_algs:
+ crypto_unregister_skciphers(riscv64_zvkned_aes_skcipher_algs,
+ ARRAY_SIZE(riscv64_zvkned_aes_skcipher_algs));
+unregister_zvkned_cipher_alg:
+ crypto_unregister_alg(&riscv64_zvkned_aes_cipher_alg);
+ return err;
+}
+
+static void __exit riscv64_aes_mod_exit(void)
+{
+ if (riscv64_aes_xts_supported())
+ crypto_unregister_skcipher(&riscv64_zvkned_zvbb_zvkg_aes_skcipher_alg);
+ if (riscv_isa_extension_available(NULL, ZVKB))
+ crypto_unregister_skcipher(&riscv64_zvkned_zvkb_aes_skcipher_alg);
+ crypto_unregister_skciphers(riscv64_zvkned_aes_skcipher_algs,
+ ARRAY_SIZE(riscv64_zvkned_aes_skcipher_algs));
+ crypto_unregister_alg(&riscv64_zvkned_aes_cipher_alg);
+}
+
+module_init(riscv64_aes_mod_init);
+module_exit(riscv64_aes_mod_exit);
+
+MODULE_DESCRIPTION("AES-ECB/CBC/CTS/CTR/XTS (RISC-V accelerated)");
+MODULE_AUTHOR("Jerry Shih <jerry.shih@sifive.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_CRYPTO("aes");
+MODULE_ALIAS_CRYPTO("ecb(aes)");
+MODULE_ALIAS_CRYPTO("cbc(aes)");
+MODULE_ALIAS_CRYPTO("cts(cbc(aes))");
+MODULE_ALIAS_CRYPTO("ctr(aes)");
+MODULE_ALIAS_CRYPTO("xts(aes)");
diff --git a/arch/riscv/crypto/aes-riscv64-zvkned-zvbb-zvkg.S b/arch/riscv/crypto/aes-riscv64-zvkned-zvbb-zvkg.S
new file mode 100644
index 000000000000..146fc9cfb268
--- /dev/null
+++ b/arch/riscv/crypto/aes-riscv64-zvkned-zvbb-zvkg.S
@@ -0,0 +1,312 @@
+/* SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause */
+//
+// This file is dual-licensed, meaning that you can use it under your
+// choice of either of the following two licenses:
+//
+// Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
+//
+// Licensed under the Apache License 2.0 (the "License"). You can obtain
+// a copy in the file LICENSE in the source distribution or at
+// https://www.openssl.org/source/license.html
+//
+// or
+//
+// Copyright (c) 2023, Jerry Shih <jerry.shih@sifive.com>
+// Copyright 2024 Google LLC
+// All rights reserved.
+//
+// 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
+// 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.
+
+// The generated code of this file depends on the following RISC-V extensions:
+// - RV64I
+// - RISC-V Vector ('V') with VLEN >= 128 && VLEN < 2048
+// - RISC-V Vector AES block cipher extension ('Zvkned')
+// - RISC-V Vector Bit-manipulation extension ('Zvbb')
+// - RISC-V Vector GCM/GMAC extension ('Zvkg')
+
+#include <linux/linkage.h>
+
+.text
+.option arch, +zvkned, +zvbb, +zvkg
+
+#include "aes-macros.S"
+
+#define KEYP a0
+#define INP a1
+#define OUTP a2
+#define LEN a3
+#define TWEAKP a4
+
+#define LEN32 a5
+#define TAIL_LEN a6
+#define VL a7
+#define VLMAX t4
+
+// v1-v15 contain the AES round keys, but they are used for temporaries before
+// the AES round keys have been loaded.
+#define TWEAKS v16 // LMUL=4 (most of the time)
+#define TWEAKS_BREV v20 // LMUL=4 (most of the time)
+#define MULTS_BREV v24 // LMUL=4 (most of the time)
+#define TMP0 v28
+#define TMP1 v29
+#define TMP2 v30
+#define TMP3 v31
+
+// xts_init initializes the following values:
+//
+// TWEAKS: N 128-bit tweaks T*(x^i) for i in 0..(N - 1)
+// TWEAKS_BREV: same as TWEAKS, but bit-reversed
+// MULTS_BREV: N 128-bit values x^N, bit-reversed. Only if N > 1.
+//
+// N is the maximum number of blocks that will be processed per loop iteration,
+// computed using vsetvli.
+//
+// The field convention used by XTS is the same as that of GHASH, but with the
+// bits reversed within each byte. The zvkg extension provides the vgmul
+// instruction which does multiplication in this field. Therefore, for tweak
+// computation we use vgmul to do multiplications in parallel, instead of
+// serially multiplying by x using shifting+xoring. Note that for this to work,
+// the inputs and outputs to vgmul must be bit-reversed (we do it with vbrev8).
+.macro xts_init
+
+ // Load the first tweak T.
+ vsetivli zero, 4, e32, m1, ta, ma
+ vle32.v TWEAKS, (TWEAKP)
+
+ // If there's only one block (or no blocks at all), then skip the tweak
+ // sequence computation because (at most) T itself is needed.
+ li t0, 16
+ ble LEN, t0, .Linit_single_block\@
+
+ // Save a copy of T bit-reversed in v12.
+ vbrev8.v v12, TWEAKS
+
+ //
+ // Generate x^i for i in 0..(N - 1), i.e. 128-bit values 1 << i assuming
+ // that N <= 128. Though, this code actually requires N < 64 (or
+ // equivalently VLEN < 2048) due to the use of 64-bit intermediate
+ // values here and in the x^N computation later.
+ //
+ vsetvli VL, LEN32, e32, m4, ta, ma
+ srli t0, VL, 2 // t0 = N (num blocks)
+ // Generate two sequences, each with N 32-bit values:
+ // v0=[1, 1, 1, ...] and v1=[0, 1, 2, ...].
+ vsetvli zero, t0, e32, m1, ta, ma
+ vmv.v.i v0, 1
+ vid.v v1
+ // Use vzext to zero-extend the sequences to 64 bits. Reinterpret them
+ // as two sequences, each with 2*N 32-bit values:
+ // v2=[1, 0, 1, 0, 1, 0, ...] and v4=[0, 0, 1, 0, 2, 0, ...].
+ vsetvli zero, t0, e64, m2, ta, ma
+ vzext.vf2 v2, v0
+ vzext.vf2 v4, v1
+ slli t1, t0, 1 // t1 = 2*N
+ vsetvli zero, t1, e32, m2, ta, ma
+ // Use vwsll to compute [1<<0, 0<<0, 1<<1, 0<<0, 1<<2, 0<<0, ...],
+ // widening to 64 bits per element. When reinterpreted as N 128-bit
+ // values, this is the needed sequence of 128-bit values 1 << i (x^i).
+ vwsll.vv v8, v2, v4
+
+ // Copy the bit-reversed T to all N elements of TWEAKS_BREV, then
+ // multiply by x^i. This gives the sequence T*(x^i), bit-reversed.
+ vsetvli zero, LEN32, e32, m4, ta, ma
+ vmv.v.i TWEAKS_BREV, 0
+ vaesz.vs TWEAKS_BREV, v12
+ vbrev8.v v8, v8
+ vgmul.vv TWEAKS_BREV, v8
+
+ // Save a copy of the sequence T*(x^i) with the bit reversal undone.
+ vbrev8.v TWEAKS, TWEAKS_BREV
+
+ // Generate N copies of x^N, i.e. 128-bit values 1 << N, bit-reversed.
+ li t1, 1
+ sll t1, t1, t0 // t1 = 1 << N
+ vsetivli zero, 2, e64, m1, ta, ma
+ vmv.v.i v0, 0
+ vsetivli zero, 1, e64, m1, tu, ma
+ vmv.v.x v0, t1
+ vbrev8.v v0, v0
+ vsetvli zero, LEN32, e32, m4, ta, ma
+ vmv.v.i MULTS_BREV, 0
+ vaesz.vs MULTS_BREV, v0
+
+ j .Linit_done\@
+
+.Linit_single_block\@:
+ vbrev8.v TWEAKS_BREV, TWEAKS
+.Linit_done\@:
+.endm
+
+// Set the first 128 bits of MULTS_BREV to 0x40, i.e. 'x' bit-reversed. This is
+// the multiplier required to advance the tweak by one.
+.macro load_x
+ li t0, 0x40
+ vsetivli zero, 4, e32, m1, ta, ma
+ vmv.v.i MULTS_BREV, 0
+ vsetivli zero, 1, e8, m1, tu, ma
+ vmv.v.x MULTS_BREV, t0
+.endm
+
+.macro __aes_xts_crypt enc, keylen
+ // With 16 < len <= 31, there's no main loop, just ciphertext stealing.
+ beqz LEN32, .Lcts_without_main_loop\@
+
+ vsetvli VLMAX, zero, e32, m4, ta, ma
+1:
+ vsetvli VL, LEN32, e32, m4, ta, ma
+2:
+ // Encrypt or decrypt VL/4 blocks.
+ vle32.v TMP0, (INP)
+ vxor.vv TMP0, TMP0, TWEAKS
+ aes_crypt TMP0, \enc, \keylen
+ vxor.vv TMP0, TMP0, TWEAKS
+ vse32.v TMP0, (OUTP)
+
+ // Update the pointers and the remaining length.
+ slli t0, VL, 2
+ add INP, INP, t0
+ add OUTP, OUTP, t0
+ sub LEN32, LEN32, VL
+
+ // Check whether more blocks remain.
+ beqz LEN32, .Lmain_loop_done\@
+
+ // Compute the next sequence of tweaks by multiplying the previous
+ // sequence by x^N. Store the result in both bit-reversed order and
+ // regular order (i.e. with the bit reversal undone).
+ vgmul.vv TWEAKS_BREV, MULTS_BREV
+ vbrev8.v TWEAKS, TWEAKS_BREV
+
+ // Since we compute the tweak multipliers x^N in advance, we require
+ // that each iteration process the same length except possibly the last.
+ // This conflicts slightly with the behavior allowed by RISC-V Vector
+ // Extension, where CPUs can select a lower length for both of the last
+ // two iterations. E.g., vl might take the sequence of values
+ // [16, 16, 16, 12, 12], whereas we need [16, 16, 16, 16, 8] so that we
+ // can use x^4 again instead of computing x^3. Therefore, we explicitly
+ // keep the vl at VLMAX if there is at least VLMAX remaining.
+ bge LEN32, VLMAX, 2b
+ j 1b
+
+.Lmain_loop_done\@:
+ load_x
+
+ // Compute the next tweak.
+ addi t0, VL, -4
+ vsetivli zero, 4, e32, m4, ta, ma
+ vslidedown.vx TWEAKS_BREV, TWEAKS_BREV, t0 // Extract last tweak
+ vsetivli zero, 4, e32, m1, ta, ma
+ vgmul.vv TWEAKS_BREV, MULTS_BREV // Advance to next tweak
+
+ bnez TAIL_LEN, .Lcts\@
+
+ // Update *TWEAKP to contain the next tweak.
+ vbrev8.v TWEAKS, TWEAKS_BREV
+ vse32.v TWEAKS, (TWEAKP)
+ ret
+
+.Lcts_without_main_loop\@:
+ load_x
+.Lcts\@:
+ // TWEAKS_BREV now contains the next tweak. Compute the one after that.
+ vsetivli zero, 4, e32, m1, ta, ma
+ vmv.v.v TMP0, TWEAKS_BREV
+ vgmul.vv TMP0, MULTS_BREV
+ // Undo the bit reversal of the next two tweaks and store them in TMP1
+ // and TMP2, such that TMP1 is the first needed and TMP2 the second.
+.if \enc
+ vbrev8.v TMP1, TWEAKS_BREV
+ vbrev8.v TMP2, TMP0
+.else
+ vbrev8.v TMP1, TMP0
+ vbrev8.v TMP2, TWEAKS_BREV
+.endif
+
+ // Encrypt/decrypt the last full block.
+ vle32.v TMP0, (INP)
+ vxor.vv TMP0, TMP0, TMP1
+ aes_crypt TMP0, \enc, \keylen
+ vxor.vv TMP0, TMP0, TMP1
+
+ // Swap the first TAIL_LEN bytes of the above result with the tail.
+ // Note that to support in-place encryption/decryption, the load from
+ // the input tail must happen before the store to the output tail.
+ addi t0, INP, 16
+ addi t1, OUTP, 16
+ vmv.v.v TMP3, TMP0
+ vsetvli zero, TAIL_LEN, e8, m1, tu, ma
+ vle8.v TMP0, (t0)
+ vse8.v TMP3, (t1)
+
+ // Encrypt/decrypt again and store the last full block.
+ vsetivli zero, 4, e32, m1, ta, ma
+ vxor.vv TMP0, TMP0, TMP2
+ aes_crypt TMP0, \enc, \keylen
+ vxor.vv TMP0, TMP0, TMP2
+ vse32.v TMP0, (OUTP)
+
+ ret
+.endm
+
+.macro aes_xts_crypt enc
+
+ // Check whether the length is a multiple of the AES block size.
+ andi TAIL_LEN, LEN, 15
+ beqz TAIL_LEN, 1f
+
+ // The length isn't a multiple of the AES block size, so ciphertext
+ // stealing will be required. Ciphertext stealing involves special
+ // handling of the partial block and the last full block, so subtract
+ // the length of both from the length to be processed in the main loop.
+ sub LEN, LEN, TAIL_LEN
+ addi LEN, LEN, -16
+1:
+ srli LEN32, LEN, 2
+ // LEN and LEN32 now contain the total length of the blocks that will be
+ // processed in the main loop, in bytes and 32-bit words respectively.
+
+ xts_init
+ aes_begin KEYP, 128f, 192f
+ __aes_xts_crypt \enc, 256
+128:
+ __aes_xts_crypt \enc, 128
+192:
+ __aes_xts_crypt \enc, 192
+.endm
+
+// void aes_xts_encrypt_zvkned_zvbb_zvkg(const struct crypto_aes_ctx *key,
+// const u8 *in, u8 *out, size_t len,
+// u8 tweak[16]);
+//
+// |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.
+SYM_FUNC_START(aes_xts_encrypt_zvkned_zvbb_zvkg)
+ aes_xts_crypt 1
+SYM_FUNC_END(aes_xts_encrypt_zvkned_zvbb_zvkg)
+
+// Same prototype and calling convention as the encryption function
+SYM_FUNC_START(aes_xts_decrypt_zvkned_zvbb_zvkg)
+ aes_xts_crypt 0
+SYM_FUNC_END(aes_xts_decrypt_zvkned_zvbb_zvkg)
diff --git a/arch/riscv/crypto/aes-riscv64-zvkned-zvkb.S b/arch/riscv/crypto/aes-riscv64-zvkned-zvkb.S
new file mode 100644
index 000000000000..9962d4500587
--- /dev/null
+++ b/arch/riscv/crypto/aes-riscv64-zvkned-zvkb.S
@@ -0,0 +1,146 @@
+/* SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause */
+//
+// This file is dual-licensed, meaning that you can use it under your
+// choice of either of the following two licenses:
+//
+// Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
+//
+// Licensed under the Apache License 2.0 (the "License"). You can obtain
+// a copy in the file LICENSE in the source distribution or at
+// https://www.openssl.org/source/license.html
+//
+// or
+//
+// Copyright (c) 2023, Jerry Shih <jerry.shih@sifive.com>
+// Copyright 2024 Google LLC
+// All rights reserved.
+//
+// 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
+// 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.
+
+// The generated code of this file depends on the following RISC-V extensions:
+// - RV64I
+// - RISC-V Vector ('V') with VLEN >= 128
+// - RISC-V Vector AES block cipher extension ('Zvkned')
+// - RISC-V Vector Cryptography Bit-manipulation extension ('Zvkb')
+
+#include <linux/linkage.h>
+
+.text
+.option arch, +zvkned, +zvkb
+
+#include "aes-macros.S"
+
+#define KEYP a0
+#define INP a1
+#define OUTP a2
+#define LEN a3
+#define IVP a4
+
+#define LEN32 a5
+#define VL_E32 a6
+#define VL_BLOCKS a7
+
+.macro aes_ctr32_crypt keylen
+ // LEN32 = number of blocks, rounded up, in 32-bit words.
+ addi t0, LEN, 15
+ srli t0, t0, 4
+ slli LEN32, t0, 2
+
+ // Create a mask that selects the last 32-bit word of each 128-bit
+ // block. This is the word that contains the (big-endian) counter.
+ li t0, 0x88
+ vsetvli t1, zero, e8, m1, ta, ma
+ vmv.v.x v0, t0
+
+ // Load the IV into v31. The last 32-bit word contains the counter.
+ vsetivli zero, 4, e32, m1, ta, ma
+ vle32.v v31, (IVP)
+
+ // Convert the big-endian counter into little-endian.
+ vsetivli zero, 4, e32, m1, ta, mu
+ vrev8.v v31, v31, v0.t
+
+ // Splat the IV to v16 (with LMUL=4). The number of copies is the
+ // maximum number of blocks that will be processed per iteration.
+ vsetvli zero, LEN32, e32, m4, ta, ma
+ vmv.v.i v16, 0
+ vaesz.vs v16, v31
+
+ // v20 = [x, x, x, 0, x, x, x, 1, ...]
+ viota.m v20, v0, v0.t
+ // v16 = [IV0, IV1, IV2, counter+0, IV0, IV1, IV2, counter+1, ...]
+ vsetvli VL_E32, LEN32, e32, m4, ta, mu
+ vadd.vv v16, v16, v20, v0.t
+
+ j 2f
+1:
+ // Set the number of blocks to process in this iteration. vl=VL_E32 is
+ // the length in 32-bit words, i.e. 4 times the number of blocks.
+ vsetvli VL_E32, LEN32, e32, m4, ta, mu
+
+ // Increment the counters by the number of blocks processed in the
+ // previous iteration.
+ vadd.vx v16, v16, VL_BLOCKS, v0.t
+2:
+ // Prepare the AES inputs into v24.
+ vmv.v.v v24, v16
+ vrev8.v v24, v24, v0.t // Convert counters back to big-endian.
+
+ // Encrypt the AES inputs to create the next portion of the keystream.
+ aes_encrypt v24, \keylen
+
+ // XOR the data with the keystream.
+ vsetvli t0, LEN, e8, m4, ta, ma
+ vle8.v v20, (INP)
+ vxor.vv v20, v20, v24
+ vse8.v v20, (OUTP)
+
+ // Advance the pointers and update the remaining length.
+ add INP, INP, t0
+ add OUTP, OUTP, t0
+ sub LEN, LEN, t0
+ sub LEN32, LEN32, VL_E32
+ srli VL_BLOCKS, VL_E32, 2
+
+ // Repeat if more data remains.
+ bnez LEN, 1b
+
+ // Update *IVP to contain the next counter.
+ vsetivli zero, 4, e32, m1, ta, mu
+ vadd.vx v16, v16, VL_BLOCKS, v0.t
+ vrev8.v v16, v16, v0.t // Convert counters back to big-endian.
+ vse32.v v16, (IVP)
+
+ ret
+.endm
+
+// void aes_ctr32_crypt_zvkned_zvkb(const struct crypto_aes_ctx *key,
+// const u8 *in, u8 *out, size_t len,
+// u8 iv[16]);
+SYM_FUNC_START(aes_ctr32_crypt_zvkned_zvkb)
+ aes_begin KEYP, 128f, 192f
+ aes_ctr32_crypt 256
+128:
+ aes_ctr32_crypt 128
+192:
+ aes_ctr32_crypt 192
+SYM_FUNC_END(aes_ctr32_crypt_zvkned_zvkb)
diff --git a/arch/riscv/crypto/aes-riscv64-zvkned.S b/arch/riscv/crypto/aes-riscv64-zvkned.S
new file mode 100644
index 000000000000..23d063f94ce6
--- /dev/null
+++ b/arch/riscv/crypto/aes-riscv64-zvkned.S
@@ -0,0 +1,339 @@
+/* SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause */
+//
+// This file is dual-licensed, meaning that you can use it under your
+// choice of either of the following two licenses:
+//
+// Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
+//
+// Licensed under the Apache License 2.0 (the "License"). You can obtain
+// a copy in the file LICENSE in the source distribution or at
+// https://www.openssl.org/source/license.html
+//
+// or
+//
+// Copyright (c) 2023, Christoph Müllner <christoph.muellner@vrull.eu>
+// Copyright (c) 2023, Phoebe Chen <phoebe.chen@sifive.com>
+// Copyright (c) 2023, Jerry Shih <jerry.shih@sifive.com>
+// Copyright 2024 Google LLC
+// All rights reserved.
+//
+// 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
+// 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.
+
+// The generated code of this file depends on the following RISC-V extensions:
+// - RV64I
+// - RISC-V Vector ('V') with VLEN >= 128
+// - RISC-V Vector AES block cipher extension ('Zvkned')
+
+#include <linux/linkage.h>
+
+.text
+.option arch, +zvkned
+
+#include "aes-macros.S"
+
+#define KEYP a0
+#define INP a1
+#define OUTP a2
+#define LEN a3
+#define IVP a4
+
+.macro __aes_crypt_zvkned enc, keylen
+ vle32.v v16, (INP)
+ aes_crypt v16, \enc, \keylen
+ vse32.v v16, (OUTP)
+ ret
+.endm
+
+.macro aes_crypt_zvkned enc
+ aes_begin KEYP, 128f, 192f
+ __aes_crypt_zvkned \enc, 256
+128:
+ __aes_crypt_zvkned \enc, 128
+192:
+ __aes_crypt_zvkned \enc, 192
+.endm
+
+// void aes_encrypt_zvkned(const struct crypto_aes_ctx *key,
+// const u8 in[16], u8 out[16]);
+SYM_FUNC_START(aes_encrypt_zvkned)
+ aes_crypt_zvkned 1
+SYM_FUNC_END(aes_encrypt_zvkned)
+
+// Same prototype and calling convention as the encryption function
+SYM_FUNC_START(aes_decrypt_zvkned)
+ aes_crypt_zvkned 0
+SYM_FUNC_END(aes_decrypt_zvkned)
+
+.macro __aes_ecb_crypt enc, keylen
+ srli t0, LEN, 2
+ // t0 is the remaining length in 32-bit words. It's a multiple of 4.
+1:
+ vsetvli t1, t0, e32, m8, ta, ma
+ sub t0, t0, t1 // Subtract number of words processed
+ slli t1, t1, 2 // Words to bytes
+ vle32.v v16, (INP)
+ aes_crypt v16, \enc, \keylen
+ vse32.v v16, (OUTP)
+ add INP, INP, t1
+ add OUTP, OUTP, t1
+ bnez t0, 1b
+
+ ret
+.endm
+
+.macro aes_ecb_crypt enc
+ aes_begin KEYP, 128f, 192f
+ __aes_ecb_crypt \enc, 256
+128:
+ __aes_ecb_crypt \enc, 128
+192:
+ __aes_ecb_crypt \enc, 192
+.endm
+
+// void aes_ecb_encrypt_zvkned(const struct crypto_aes_ctx *key,
+// const u8 *in, u8 *out, size_t len);
+//
+// |len| must be nonzero and a multiple of 16 (AES_BLOCK_SIZE).
+SYM_FUNC_START(aes_ecb_encrypt_zvkned)
+ aes_ecb_crypt 1
+SYM_FUNC_END(aes_ecb_encrypt_zvkned)
+
+// Same prototype and calling convention as the encryption function
+SYM_FUNC_START(aes_ecb_decrypt_zvkned)
+ aes_ecb_crypt 0
+SYM_FUNC_END(aes_ecb_decrypt_zvkned)
+
+.macro aes_cbc_encrypt keylen
+ vle32.v v16, (IVP) // Load IV
+1:
+ vle32.v v17, (INP) // Load plaintext block
+ vxor.vv v16, v16, v17 // XOR with IV or prev ciphertext block
+ aes_encrypt v16, \keylen // Encrypt
+ vse32.v v16, (OUTP) // Store ciphertext block
+ addi INP, INP, 16
+ addi OUTP, OUTP, 16
+ addi LEN, LEN, -16
+ bnez LEN, 1b
+
+ vse32.v v16, (IVP) // Store next IV
+ ret
+.endm
+
+.macro aes_cbc_decrypt keylen
+ srli LEN, LEN, 2 // Convert LEN from bytes to words
+ vle32.v v16, (IVP) // Load IV
+1:
+ vsetvli t0, LEN, e32, m4, ta, ma
+ vle32.v v20, (INP) // Load ciphertext blocks
+ vslideup.vi v16, v20, 4 // Setup prev ciphertext blocks
+ addi t1, t0, -4
+ vslidedown.vx v24, v20, t1 // Save last ciphertext block
+ aes_decrypt v20, \keylen // Decrypt the blocks
+ vxor.vv v20, v20, v16 // XOR with prev ciphertext blocks
+ vse32.v v20, (OUTP) // Store plaintext blocks
+ vmv.v.v v16, v24 // Next "IV" is last ciphertext block
+ slli t1, t0, 2 // Words to bytes
+ add INP, INP, t1
+ add OUTP, OUTP, t1
+ sub LEN, LEN, t0
+ bnez LEN, 1b
+
+ vsetivli zero, 4, e32, m1, ta, ma
+ vse32.v v16, (IVP) // Store next IV
+ ret
+.endm
+
+// void aes_cbc_encrypt_zvkned(const struct crypto_aes_ctx *key,
+// const u8 *in, u8 *out, size_t len, u8 iv[16]);
+//
+// |len| must be nonzero and a multiple of 16 (AES_BLOCK_SIZE).
+SYM_FUNC_START(aes_cbc_encrypt_zvkned)
+ aes_begin KEYP, 128f, 192f
+ aes_cbc_encrypt 256
+128:
+ aes_cbc_encrypt 128
+192:
+ aes_cbc_encrypt 192
+SYM_FUNC_END(aes_cbc_encrypt_zvkned)
+
+// Same prototype and calling convention as the encryption function
+SYM_FUNC_START(aes_cbc_decrypt_zvkned)
+ aes_begin KEYP, 128f, 192f
+ aes_cbc_decrypt 256
+128:
+ aes_cbc_decrypt 128
+192:
+ aes_cbc_decrypt 192
+SYM_FUNC_END(aes_cbc_decrypt_zvkned)
+
+.macro aes_cbc_cts_encrypt keylen
+
+ // CBC-encrypt all blocks except the last. But don't store the
+ // second-to-last block to the output buffer yet, since it will be
+ // handled specially in the ciphertext stealing step. Exception: if the
+ // message is single-block, still encrypt the last (and only) block.
+ li t0, 16
+ j 2f
+1:
+ vse32.v v16, (OUTP) // Store ciphertext block
+ addi OUTP, OUTP, 16
+2:
+ vle32.v v17, (INP) // Load plaintext block
+ vxor.vv v16, v16, v17 // XOR with IV or prev ciphertext block
+ aes_encrypt v16, \keylen // Encrypt
+ addi INP, INP, 16
+ addi LEN, LEN, -16
+ bgt LEN, t0, 1b // Repeat if more than one block remains
+
+ // Special case: if the message is a single block, just do CBC.
+ beqz LEN, .Lcts_encrypt_done\@
+
+ // Encrypt the last two blocks using ciphertext stealing as follows:
+ // C[n-1] = Encrypt(Encrypt(P[n-1] ^ C[n-2]) ^ P[n])
+ // C[n] = Encrypt(P[n-1] ^ C[n-2])[0..LEN]
+ //
+ // C[i] denotes the i'th ciphertext block, and likewise P[i] the i'th
+ // plaintext block. Block n, the last block, may be partial; its length
+ // is 1 <= LEN <= 16. If there are only 2 blocks, C[n-2] means the IV.
+ //
+ // v16 already contains Encrypt(P[n-1] ^ C[n-2]).
+ // INP points to P[n]. OUTP points to where C[n-1] should go.
+ // To support in-place encryption, load P[n] before storing C[n].
+ addi t0, OUTP, 16 // Get pointer to where C[n] should go
+ vsetvli zero, LEN, e8, m1, tu, ma
+ vle8.v v17, (INP) // Load P[n]
+ vse8.v v16, (t0) // Store C[n]
+ vxor.vv v16, v16, v17 // v16 = Encrypt(P[n-1] ^ C[n-2]) ^ P[n]
+ vsetivli zero, 4, e32, m1, ta, ma
+ aes_encrypt v16, \keylen
+.Lcts_encrypt_done\@:
+ vse32.v v16, (OUTP) // Store C[n-1] (or C[n] in single-block case)
+ ret
+.endm
+
+#define LEN32 t4 // Length of remaining full blocks in 32-bit words
+#define LEN_MOD16 t5 // Length of message in bytes mod 16
+
+.macro aes_cbc_cts_decrypt keylen
+ andi LEN32, LEN, ~15
+ srli LEN32, LEN32, 2
+ andi LEN_MOD16, LEN, 15
+
+ // Save C[n-2] in v28 so that it's available later during the ciphertext
+ // stealing step. If there are fewer than three blocks, C[n-2] means
+ // the IV, otherwise it means the third-to-last ciphertext block.
+ vmv.v.v v28, v16 // IV
+ add t0, LEN, -33
+ bltz t0, .Lcts_decrypt_loop\@
+ andi t0, t0, ~15
+ add t0, t0, INP
+ vle32.v v28, (t0)
+
+ // CBC-decrypt all full blocks. For the last full block, or the last 2
+ // full blocks if the message is block-aligned, this doesn't write the
+ // correct output blocks (unless the message is only a single block),
+ // because it XORs the wrong values with the raw AES plaintexts. But we
+ // fix this after this loop without redoing the AES decryptions. This
+ // approach allows more of the AES decryptions to be parallelized.
+.Lcts_decrypt_loop\@:
+ vsetvli t0, LEN32, e32, m4, ta, ma
+ addi t1, t0, -4
+ vle32.v v20, (INP) // Load next set of ciphertext blocks
+ vmv.v.v v24, v16 // Get IV or last ciphertext block of prev set
+ vslideup.vi v24, v20, 4 // Setup prev ciphertext blocks
+ vslidedown.vx v16, v20, t1 // Save last ciphertext block of this set
+ aes_decrypt v20, \keylen // Decrypt this set of blocks
+ vxor.vv v24, v24, v20 // XOR prev ciphertext blocks with decrypted blocks
+ vse32.v v24, (OUTP) // Store this set of plaintext blocks
+ sub LEN32, LEN32, t0
+ slli t0, t0, 2 // Words to bytes
+ add INP, INP, t0
+ add OUTP, OUTP, t0
+ bnez LEN32, .Lcts_decrypt_loop\@
+
+ vsetivli zero, 4, e32, m4, ta, ma
+ vslidedown.vx v20, v20, t1 // Extract raw plaintext of last full block
+ addi t0, OUTP, -16 // Get pointer to last full plaintext block
+ bnez LEN_MOD16, .Lcts_decrypt_non_block_aligned\@
+
+ // Special case: if the message is a single block, just do CBC.
+ li t1, 16
+ beq LEN, t1, .Lcts_decrypt_done\@
+
+ // Block-aligned message. Just fix up the last 2 blocks. We need:
+ //
+ // P[n-1] = Decrypt(C[n]) ^ C[n-2]
+ // P[n] = Decrypt(C[n-1]) ^ C[n]
+ //
+ // We have C[n] in v16, Decrypt(C[n]) in v20, and C[n-2] in v28.
+ // Together with Decrypt(C[n-1]) ^ C[n-2] from the output buffer, this
+ // is everything needed to fix the output without re-decrypting blocks.
+ addi t1, OUTP, -32 // Get pointer to where P[n-1] should go
+ vxor.vv v20, v20, v28 // Decrypt(C[n]) ^ C[n-2] == P[n-1]
+ vle32.v v24, (t1) // Decrypt(C[n-1]) ^ C[n-2]
+ vse32.v v20, (t1) // Store P[n-1]
+ vxor.vv v20, v24, v16 // Decrypt(C[n-1]) ^ C[n-2] ^ C[n] == P[n] ^ C[n-2]
+ j .Lcts_decrypt_finish\@
+
+.Lcts_decrypt_non_block_aligned\@:
+ // Decrypt the last two blocks using ciphertext stealing as follows:
+ //
+ // P[n-1] = Decrypt(C[n] || Decrypt(C[n-1])[LEN_MOD16..16]) ^ C[n-2]
+ // P[n] = (Decrypt(C[n-1]) ^ C[n])[0..LEN_MOD16]
+ //
+ // We already have Decrypt(C[n-1]) in v20 and C[n-2] in v28.
+ vmv.v.v v16, v20 // v16 = Decrypt(C[n-1])
+ vsetvli zero, LEN_MOD16, e8, m1, tu, ma
+ vle8.v v20, (INP) // v20 = C[n] || Decrypt(C[n-1])[LEN_MOD16..16]
+ vxor.vv v16, v16, v20 // v16 = Decrypt(C[n-1]) ^ C[n]
+ vse8.v v16, (OUTP) // Store P[n]
+ vsetivli zero, 4, e32, m1, ta, ma
+ aes_decrypt v20, \keylen // v20 = Decrypt(C[n] || Decrypt(C[n-1])[LEN_MOD16..16])
+.Lcts_decrypt_finish\@:
+ vxor.vv v20, v20, v28 // XOR with C[n-2]
+ vse32.v v20, (t0) // Store last full plaintext block
+.Lcts_decrypt_done\@:
+ ret
+.endm
+
+.macro aes_cbc_cts_crypt keylen
+ vle32.v v16, (IVP) // Load IV
+ beqz a5, .Lcts_decrypt\@
+ aes_cbc_cts_encrypt \keylen
+.Lcts_decrypt\@:
+ aes_cbc_cts_decrypt \keylen
+.endm
+
+// void aes_cbc_cts_crypt_zvkned(const struct crypto_aes_ctx *key,
+// const u8 *in, u8 *out, size_t len,
+// const u8 iv[16], bool enc);
+//
+// Encrypts or decrypts a message with the CS3 variant of AES-CBC-CTS.
+// This is the variant that unconditionally swaps the last two blocks.
+SYM_FUNC_START(aes_cbc_cts_crypt_zvkned)
+ aes_begin KEYP, 128f, 192f
+ aes_cbc_cts_crypt 256
+128:
+ aes_cbc_cts_crypt 128
+192:
+ aes_cbc_cts_crypt 192
+SYM_FUNC_END(aes_cbc_cts_crypt_zvkned)
diff --git a/arch/riscv/crypto/chacha-riscv64-glue.c b/arch/riscv/crypto/chacha-riscv64-glue.c
new file mode 100644
index 000000000000..10b46f36375a
--- /dev/null
+++ b/arch/riscv/crypto/chacha-riscv64-glue.c
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * ChaCha20 using the RISC-V vector crypto extensions
+ *
+ * Copyright (C) 2023 SiFive, Inc.
+ * Author: Jerry Shih <jerry.shih@sifive.com>
+ */
+
+#include <asm/simd.h>
+#include <asm/vector.h>
+#include <crypto/internal/chacha.h>
+#include <crypto/internal/skcipher.h>
+#include <linux/linkage.h>
+#include <linux/module.h>
+
+asmlinkage void chacha20_zvkb(const u32 key[8], const u8 *in, u8 *out,
+ size_t len, const u32 iv[4]);
+
+static int riscv64_chacha20_crypt(struct skcipher_request *req)
+{
+ u32 iv[CHACHA_IV_SIZE / sizeof(u32)];
+ u8 block_buffer[CHACHA_BLOCK_SIZE];
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ const struct chacha_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct skcipher_walk walk;
+ unsigned int nbytes;
+ unsigned int tail_bytes;
+ int err;
+
+ iv[0] = get_unaligned_le32(req->iv);
+ iv[1] = get_unaligned_le32(req->iv + 4);
+ iv[2] = get_unaligned_le32(req->iv + 8);
+ iv[3] = get_unaligned_le32(req->iv + 12);
+
+ err = skcipher_walk_virt(&walk, req, false);
+ while (walk.nbytes) {
+ nbytes = walk.nbytes & ~(CHACHA_BLOCK_SIZE - 1);
+ tail_bytes = walk.nbytes & (CHACHA_BLOCK_SIZE - 1);
+ kernel_vector_begin();
+ if (nbytes) {
+ chacha20_zvkb(ctx->key, walk.src.virt.addr,
+ walk.dst.virt.addr, nbytes, iv);
+ iv[0] += nbytes / CHACHA_BLOCK_SIZE;
+ }
+ if (walk.nbytes == walk.total && tail_bytes > 0) {
+ memcpy(block_buffer, walk.src.virt.addr + nbytes,
+ tail_bytes);
+ chacha20_zvkb(ctx->key, block_buffer, block_buffer,
+ CHACHA_BLOCK_SIZE, iv);
+ memcpy(walk.dst.virt.addr + nbytes, block_buffer,
+ tail_bytes);
+ tail_bytes = 0;
+ }
+ kernel_vector_end();
+
+ err = skcipher_walk_done(&walk, tail_bytes);
+ }
+
+ return err;
+}
+
+static struct skcipher_alg riscv64_chacha_alg = {
+ .setkey = chacha20_setkey,
+ .encrypt = riscv64_chacha20_crypt,
+ .decrypt = riscv64_chacha20_crypt,
+ .min_keysize = CHACHA_KEY_SIZE,
+ .max_keysize = CHACHA_KEY_SIZE,
+ .ivsize = CHACHA_IV_SIZE,
+ .chunksize = CHACHA_BLOCK_SIZE,
+ .walksize = 4 * CHACHA_BLOCK_SIZE,
+ .base = {
+ .cra_blocksize = 1,
+ .cra_ctxsize = sizeof(struct chacha_ctx),
+ .cra_priority = 300,
+ .cra_name = "chacha20",
+ .cra_driver_name = "chacha20-riscv64-zvkb",
+ .cra_module = THIS_MODULE,
+ },
+};
+
+static int __init riscv64_chacha_mod_init(void)
+{
+ if (riscv_isa_extension_available(NULL, ZVKB) &&
+ riscv_vector_vlen() >= 128)
+ return crypto_register_skcipher(&riscv64_chacha_alg);
+
+ return -ENODEV;
+}
+
+static void __exit riscv64_chacha_mod_exit(void)
+{
+ crypto_unregister_skcipher(&riscv64_chacha_alg);
+}
+
+module_init(riscv64_chacha_mod_init);
+module_exit(riscv64_chacha_mod_exit);
+
+MODULE_DESCRIPTION("ChaCha20 (RISC-V accelerated)");
+MODULE_AUTHOR("Jerry Shih <jerry.shih@sifive.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_CRYPTO("chacha20");
diff --git a/arch/riscv/crypto/chacha-riscv64-zvkb.S b/arch/riscv/crypto/chacha-riscv64-zvkb.S
new file mode 100644
index 000000000000..bf057737ac69
--- /dev/null
+++ b/arch/riscv/crypto/chacha-riscv64-zvkb.S
@@ -0,0 +1,294 @@
+/* SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause */
+//
+// This file is dual-licensed, meaning that you can use it under your
+// choice of either of the following two licenses:
+//
+// Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
+//
+// Licensed under the Apache License 2.0 (the "License"). You can obtain
+// a copy in the file LICENSE in the source distribution or at
+// https://www.openssl.org/source/license.html
+//
+// or
+//
+// Copyright (c) 2023, Jerry Shih <jerry.shih@sifive.com>
+// Copyright 2024 Google LLC
+// All rights reserved.
+//
+// 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
+// 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.
+
+// The generated code of this file depends on the following RISC-V extensions:
+// - RV64I
+// - RISC-V Vector ('V') with VLEN >= 128
+// - RISC-V Vector Cryptography Bit-manipulation extension ('Zvkb')
+
+#include <linux/linkage.h>
+
+.text
+.option arch, +zvkb
+
+#define KEYP a0
+#define INP a1
+#define OUTP a2
+#define LEN a3
+#define IVP a4
+
+#define CONSTS0 a5
+#define CONSTS1 a6
+#define CONSTS2 a7
+#define CONSTS3 t0
+#define TMP t1
+#define VL t2
+#define STRIDE t3
+#define NROUNDS t4
+#define KEY0 s0
+#define KEY1 s1
+#define KEY2 s2
+#define KEY3 s3
+#define KEY4 s4
+#define KEY5 s5
+#define KEY6 s6
+#define KEY7 s7
+#define COUNTER s8
+#define NONCE0 s9
+#define NONCE1 s10
+#define NONCE2 s11
+
+.macro chacha_round a0, b0, c0, d0, a1, b1, c1, d1, \
+ a2, b2, c2, d2, a3, b3, c3, d3
+ // a += b; d ^= a; d = rol(d, 16);
+ vadd.vv \a0, \a0, \b0
+ vadd.vv \a1, \a1, \b1
+ vadd.vv \a2, \a2, \b2
+ vadd.vv \a3, \a3, \b3
+ vxor.vv \d0, \d0, \a0
+ vxor.vv \d1, \d1, \a1
+ vxor.vv \d2, \d2, \a2
+ vxor.vv \d3, \d3, \a3
+ vror.vi \d0, \d0, 32 - 16
+ vror.vi \d1, \d1, 32 - 16
+ vror.vi \d2, \d2, 32 - 16
+ vror.vi \d3, \d3, 32 - 16
+
+ // c += d; b ^= c; b = rol(b, 12);
+ vadd.vv \c0, \c0, \d0
+ vadd.vv \c1, \c1, \d1
+ vadd.vv \c2, \c2, \d2
+ vadd.vv \c3, \c3, \d3
+ vxor.vv \b0, \b0, \c0
+ vxor.vv \b1, \b1, \c1
+ vxor.vv \b2, \b2, \c2
+ vxor.vv \b3, \b3, \c3
+ vror.vi \b0, \b0, 32 - 12
+ vror.vi \b1, \b1, 32 - 12
+ vror.vi \b2, \b2, 32 - 12
+ vror.vi \b3, \b3, 32 - 12
+
+ // a += b; d ^= a; d = rol(d, 8);
+ vadd.vv \a0, \a0, \b0
+ vadd.vv \a1, \a1, \b1
+ vadd.vv \a2, \a2, \b2
+ vadd.vv \a3, \a3, \b3
+ vxor.vv \d0, \d0, \a0
+ vxor.vv \d1, \d1, \a1
+ vxor.vv \d2, \d2, \a2
+ vxor.vv \d3, \d3, \a3
+ vror.vi \d0, \d0, 32 - 8
+ vror.vi \d1, \d1, 32 - 8
+ vror.vi \d2, \d2, 32 - 8
+ vror.vi \d3, \d3, 32 - 8
+
+ // c += d; b ^= c; b = rol(b, 7);
+ vadd.vv \c0, \c0, \d0
+ vadd.vv \c1, \c1, \d1
+ vadd.vv \c2, \c2, \d2
+ vadd.vv \c3, \c3, \d3
+ vxor.vv \b0, \b0, \c0
+ vxor.vv \b1, \b1, \c1
+ vxor.vv \b2, \b2, \c2
+ vxor.vv \b3, \b3, \c3
+ vror.vi \b0, \b0, 32 - 7
+ vror.vi \b1, \b1, 32 - 7
+ vror.vi \b2, \b2, 32 - 7
+ vror.vi \b3, \b3, 32 - 7
+.endm
+
+// void chacha20_zvkb(const u32 key[8], const u8 *in, u8 *out, size_t len,
+// const u32 iv[4]);
+//
+// |len| must be nonzero and a multiple of 64 (CHACHA_BLOCK_SIZE).
+// The counter is treated as 32-bit, following the RFC7539 convention.
+SYM_FUNC_START(chacha20_zvkb)
+ srli LEN, LEN, 6 // Bytes to blocks
+
+ addi sp, sp, -96
+ sd s0, 0(sp)
+ sd s1, 8(sp)
+ sd s2, 16(sp)
+ sd s3, 24(sp)
+ sd s4, 32(sp)
+ sd s5, 40(sp)
+ sd s6, 48(sp)
+ sd s7, 56(sp)
+ sd s8, 64(sp)
+ sd s9, 72(sp)
+ sd s10, 80(sp)
+ sd s11, 88(sp)
+
+ li STRIDE, 64
+
+ // Set up the initial state matrix in scalar registers.
+ li CONSTS0, 0x61707865 // "expa" little endian
+ li CONSTS1, 0x3320646e // "nd 3" little endian
+ li CONSTS2, 0x79622d32 // "2-by" little endian
+ li CONSTS3, 0x6b206574 // "te k" little endian
+ lw KEY0, 0(KEYP)
+ lw KEY1, 4(KEYP)
+ lw KEY2, 8(KEYP)
+ lw KEY3, 12(KEYP)
+ lw KEY4, 16(KEYP)
+ lw KEY5, 20(KEYP)
+ lw KEY6, 24(KEYP)
+ lw KEY7, 28(KEYP)
+ lw COUNTER, 0(IVP)
+ lw NONCE0, 4(IVP)
+ lw NONCE1, 8(IVP)
+ lw NONCE2, 12(IVP)
+
+.Lblock_loop:
+ // Set vl to the number of blocks to process in this iteration.
+ vsetvli VL, LEN, e32, m1, ta, ma
+
+ // Set up the initial state matrix for the next VL blocks in v0-v15.
+ // v{i} holds the i'th 32-bit word of the state matrix for all blocks.
+ // Note that only the counter word, at index 12, differs across blocks.
+ vmv.v.x v0, CONSTS0
+ vmv.v.x v1, CONSTS1
+ vmv.v.x v2, CONSTS2
+ vmv.v.x v3, CONSTS3
+ vmv.v.x v4, KEY0
+ vmv.v.x v5, KEY1
+ vmv.v.x v6, KEY2
+ vmv.v.x v7, KEY3
+ vmv.v.x v8, KEY4
+ vmv.v.x v9, KEY5
+ vmv.v.x v10, KEY6
+ vmv.v.x v11, KEY7
+ vid.v v12
+ vadd.vx v12, v12, COUNTER
+ vmv.v.x v13, NONCE0
+ vmv.v.x v14, NONCE1
+ vmv.v.x v15, NONCE2
+
+ // Load the first half of the input data for each block into v16-v23.
+ // v{16+i} holds the i'th 32-bit word for all blocks.
+ vlsseg8e32.v v16, (INP), STRIDE
+
+ li NROUNDS, 20
+.Lnext_doubleround:
+ addi NROUNDS, NROUNDS, -2
+ // column round
+ chacha_round v0, v4, v8, v12, v1, v5, v9, v13, \
+ v2, v6, v10, v14, v3, v7, v11, v15
+ // diagonal round
+ chacha_round v0, v5, v10, v15, v1, v6, v11, v12, \
+ v2, v7, v8, v13, v3, v4, v9, v14
+ bnez NROUNDS, .Lnext_doubleround
+
+ // Load the second half of the input data for each block into v24-v31.
+ // v{24+i} holds the {8+i}'th 32-bit word for all blocks.
+ addi TMP, INP, 32
+ vlsseg8e32.v v24, (TMP), STRIDE
+
+ // Finalize the first half of the keystream for each block.
+ vadd.vx v0, v0, CONSTS0
+ vadd.vx v1, v1, CONSTS1
+ vadd.vx v2, v2, CONSTS2
+ vadd.vx v3, v3, CONSTS3
+ vadd.vx v4, v4, KEY0
+ vadd.vx v5, v5, KEY1
+ vadd.vx v6, v6, KEY2
+ vadd.vx v7, v7, KEY3
+
+ // Encrypt/decrypt the first half of the data for each block.
+ vxor.vv v16, v16, v0
+ vxor.vv v17, v17, v1
+ vxor.vv v18, v18, v2
+ vxor.vv v19, v19, v3
+ vxor.vv v20, v20, v4
+ vxor.vv v21, v21, v5
+ vxor.vv v22, v22, v6
+ vxor.vv v23, v23, v7
+
+ // Store the first half of the output data for each block.
+ vssseg8e32.v v16, (OUTP), STRIDE
+
+ // Finalize the second half of the keystream for each block.
+ vadd.vx v8, v8, KEY4
+ vadd.vx v9, v9, KEY5
+ vadd.vx v10, v10, KEY6
+ vadd.vx v11, v11, KEY7
+ vid.v v0
+ vadd.vx v12, v12, COUNTER
+ vadd.vx v13, v13, NONCE0
+ vadd.vx v14, v14, NONCE1
+ vadd.vx v15, v15, NONCE2
+ vadd.vv v12, v12, v0
+
+ // Encrypt/decrypt the second half of the data for each block.
+ vxor.vv v24, v24, v8
+ vxor.vv v25, v25, v9
+ vxor.vv v26, v26, v10
+ vxor.vv v27, v27, v11
+ vxor.vv v29, v29, v13
+ vxor.vv v28, v28, v12
+ vxor.vv v30, v30, v14
+ vxor.vv v31, v31, v15
+
+ // Store the second half of the output data for each block.
+ addi TMP, OUTP, 32
+ vssseg8e32.v v24, (TMP), STRIDE
+
+ // Update the counter, the remaining number of blocks, and the input and
+ // output pointers according to the number of blocks processed (VL).
+ add COUNTER, COUNTER, VL
+ sub LEN, LEN, VL
+ slli TMP, VL, 6
+ add OUTP, OUTP, TMP
+ add INP, INP, TMP
+ bnez LEN, .Lblock_loop
+
+ ld s0, 0(sp)
+ ld s1, 8(sp)
+ ld s2, 16(sp)
+ ld s3, 24(sp)
+ ld s4, 32(sp)
+ ld s5, 40(sp)
+ ld s6, 48(sp)
+ ld s7, 56(sp)
+ ld s8, 64(sp)
+ ld s9, 72(sp)
+ ld s10, 80(sp)
+ ld s11, 88(sp)
+ addi sp, sp, 96
+ ret
+SYM_FUNC_END(chacha20_zvkb)
diff --git a/arch/riscv/crypto/ghash-riscv64-glue.c b/arch/riscv/crypto/ghash-riscv64-glue.c
new file mode 100644
index 000000000000..312e7891fd0a
--- /dev/null
+++ b/arch/riscv/crypto/ghash-riscv64-glue.c
@@ -0,0 +1,168 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * GHASH using the RISC-V vector crypto extensions
+ *
+ * Copyright (C) 2023 VRULL GmbH
+ * Author: Heiko Stuebner <heiko.stuebner@vrull.eu>
+ *
+ * Copyright (C) 2023 SiFive, Inc.
+ * Author: Jerry Shih <jerry.shih@sifive.com>
+ */
+
+#include <asm/simd.h>
+#include <asm/vector.h>
+#include <crypto/ghash.h>
+#include <crypto/internal/hash.h>
+#include <crypto/internal/simd.h>
+#include <linux/linkage.h>
+#include <linux/module.h>
+
+asmlinkage void ghash_zvkg(be128 *accumulator, const be128 *key, const u8 *data,
+ size_t len);
+
+struct riscv64_ghash_tfm_ctx {
+ be128 key;
+};
+
+struct riscv64_ghash_desc_ctx {
+ be128 accumulator;
+ u8 buffer[GHASH_BLOCK_SIZE];
+ u32 bytes;
+};
+
+static int riscv64_ghash_setkey(struct crypto_shash *tfm, const u8 *key,
+ unsigned int keylen)
+{
+ struct riscv64_ghash_tfm_ctx *tctx = crypto_shash_ctx(tfm);
+
+ if (keylen != GHASH_BLOCK_SIZE)
+ return -EINVAL;
+
+ memcpy(&tctx->key, key, GHASH_BLOCK_SIZE);
+
+ return 0;
+}
+
+static int riscv64_ghash_init(struct shash_desc *desc)
+{
+ struct riscv64_ghash_desc_ctx *dctx = shash_desc_ctx(desc);
+
+ *dctx = (struct riscv64_ghash_desc_ctx){};
+
+ return 0;
+}
+
+static inline void
+riscv64_ghash_blocks(const struct riscv64_ghash_tfm_ctx *tctx,
+ struct riscv64_ghash_desc_ctx *dctx,
+ const u8 *src, size_t srclen)
+{
+ /* The srclen is nonzero and a multiple of 16. */
+ if (crypto_simd_usable()) {
+ kernel_vector_begin();
+ ghash_zvkg(&dctx->accumulator, &tctx->key, src, srclen);
+ kernel_vector_end();
+ } else {
+ do {
+ crypto_xor((u8 *)&dctx->accumulator, src,
+ GHASH_BLOCK_SIZE);
+ gf128mul_lle(&dctx->accumulator, &tctx->key);
+ src += GHASH_BLOCK_SIZE;
+ srclen -= GHASH_BLOCK_SIZE;
+ } while (srclen);
+ }
+}
+
+static int riscv64_ghash_update(struct shash_desc *desc, const u8 *src,
+ unsigned int srclen)
+{
+ const struct riscv64_ghash_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
+ struct riscv64_ghash_desc_ctx *dctx = shash_desc_ctx(desc);
+ unsigned int len;
+
+ if (dctx->bytes) {
+ if (dctx->bytes + srclen < GHASH_BLOCK_SIZE) {
+ memcpy(dctx->buffer + dctx->bytes, src, srclen);
+ dctx->bytes += srclen;
+ return 0;
+ }
+ memcpy(dctx->buffer + dctx->bytes, src,
+ GHASH_BLOCK_SIZE - dctx->bytes);
+ riscv64_ghash_blocks(tctx, dctx, dctx->buffer,
+ GHASH_BLOCK_SIZE);
+ src += GHASH_BLOCK_SIZE - dctx->bytes;
+ srclen -= GHASH_BLOCK_SIZE - dctx->bytes;
+ dctx->bytes = 0;
+ }
+
+ len = round_down(srclen, GHASH_BLOCK_SIZE);
+ if (len) {
+ riscv64_ghash_blocks(tctx, dctx, src, len);
+ src += len;
+ srclen -= len;
+ }
+
+ if (srclen) {
+ memcpy(dctx->buffer, src, srclen);
+ dctx->bytes = srclen;
+ }
+
+ return 0;
+}
+
+static int riscv64_ghash_final(struct shash_desc *desc, u8 *out)
+{
+ const struct riscv64_ghash_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
+ struct riscv64_ghash_desc_ctx *dctx = shash_desc_ctx(desc);
+ int i;
+
+ if (dctx->bytes) {
+ for (i = dctx->bytes; i < GHASH_BLOCK_SIZE; i++)
+ dctx->buffer[i] = 0;
+
+ riscv64_ghash_blocks(tctx, dctx, dctx->buffer,
+ GHASH_BLOCK_SIZE);
+ }
+
+ memcpy(out, &dctx->accumulator, GHASH_DIGEST_SIZE);
+ return 0;
+}
+
+static struct shash_alg riscv64_ghash_alg = {
+ .init = riscv64_ghash_init,
+ .update = riscv64_ghash_update,
+ .final = riscv64_ghash_final,
+ .setkey = riscv64_ghash_setkey,
+ .descsize = sizeof(struct riscv64_ghash_desc_ctx),
+ .digestsize = GHASH_DIGEST_SIZE,
+ .base = {
+ .cra_blocksize = GHASH_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct riscv64_ghash_tfm_ctx),
+ .cra_priority = 300,
+ .cra_name = "ghash",
+ .cra_driver_name = "ghash-riscv64-zvkg",
+ .cra_module = THIS_MODULE,
+ },
+};
+
+static int __init riscv64_ghash_mod_init(void)
+{
+ if (riscv_isa_extension_available(NULL, ZVKG) &&
+ riscv_vector_vlen() >= 128)
+ return crypto_register_shash(&riscv64_ghash_alg);
+
+ return -ENODEV;
+}
+
+static void __exit riscv64_ghash_mod_exit(void)
+{
+ crypto_unregister_shash(&riscv64_ghash_alg);
+}
+
+module_init(riscv64_ghash_mod_init);
+module_exit(riscv64_ghash_mod_exit);
+
+MODULE_DESCRIPTION("GHASH (RISC-V accelerated)");
+MODULE_AUTHOR("Heiko Stuebner <heiko.stuebner@vrull.eu>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_CRYPTO("ghash");
diff --git a/arch/riscv/crypto/ghash-riscv64-zvkg.S b/arch/riscv/crypto/ghash-riscv64-zvkg.S
new file mode 100644
index 000000000000..f2b43fb4d434
--- /dev/null
+++ b/arch/riscv/crypto/ghash-riscv64-zvkg.S
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause */
+//
+// This file is dual-licensed, meaning that you can use it under your
+// choice of either of the following two licenses:
+//
+// Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
+//
+// Licensed under the Apache License 2.0 (the "License"). You can obtain
+// a copy in the file LICENSE in the source distribution or at
+// https://www.openssl.org/source/license.html
+//
+// or
+//
+// Copyright (c) 2023, Christoph Müllner <christoph.muellner@vrull.eu>
+// Copyright (c) 2023, Jerry Shih <jerry.shih@sifive.com>
+// Copyright 2024 Google LLC
+// All rights reserved.
+//
+// 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
+// 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.
+
+// The generated code of this file depends on the following RISC-V extensions:
+// - RV64I
+// - RISC-V Vector ('V') with VLEN >= 128
+// - RISC-V Vector GCM/GMAC extension ('Zvkg')
+
+#include <linux/linkage.h>
+
+.text
+.option arch, +zvkg
+
+#define ACCUMULATOR a0
+#define KEY a1
+#define DATA a2
+#define LEN a3
+
+// void ghash_zvkg(be128 *accumulator, const be128 *key, const u8 *data,
+// size_t len);
+//
+// |len| must be nonzero and a multiple of 16 (GHASH_BLOCK_SIZE).
+SYM_FUNC_START(ghash_zvkg)
+ vsetivli zero, 4, e32, m1, ta, ma
+ vle32.v v1, (ACCUMULATOR)
+ vle32.v v2, (KEY)
+.Lnext_block:
+ vle32.v v3, (DATA)
+ vghsh.vv v1, v2, v3
+ addi DATA, DATA, 16
+ addi LEN, LEN, -16
+ bnez LEN, .Lnext_block
+
+ vse32.v v1, (ACCUMULATOR)
+ ret
+SYM_FUNC_END(ghash_zvkg)
diff --git a/arch/riscv/crypto/sha256-riscv64-glue.c b/arch/riscv/crypto/sha256-riscv64-glue.c
new file mode 100644
index 000000000000..71e051e40a64
--- /dev/null
+++ b/arch/riscv/crypto/sha256-riscv64-glue.c
@@ -0,0 +1,137 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * SHA-256 and SHA-224 using the RISC-V vector crypto extensions
+ *
+ * Copyright (C) 2022 VRULL GmbH
+ * Author: Heiko Stuebner <heiko.stuebner@vrull.eu>
+ *
+ * Copyright (C) 2023 SiFive, Inc.
+ * Author: Jerry Shih <jerry.shih@sifive.com>
+ */
+
+#include <asm/simd.h>
+#include <asm/vector.h>
+#include <crypto/internal/hash.h>
+#include <crypto/internal/simd.h>
+#include <crypto/sha256_base.h>
+#include <linux/linkage.h>
+#include <linux/module.h>
+
+/*
+ * Note: the asm function only uses the 'state' field of struct sha256_state.
+ * It is assumed to be the first field.
+ */
+asmlinkage void sha256_transform_zvknha_or_zvknhb_zvkb(
+ struct sha256_state *state, const u8 *data, int num_blocks);
+
+static int riscv64_sha256_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+{
+ /*
+ * Ensure struct sha256_state begins directly with the SHA-256
+ * 256-bit internal state, as this is what the asm function expects.
+ */
+ BUILD_BUG_ON(offsetof(struct sha256_state, state) != 0);
+
+ if (crypto_simd_usable()) {
+ kernel_vector_begin();
+ sha256_base_do_update(desc, data, len,
+ sha256_transform_zvknha_or_zvknhb_zvkb);
+ kernel_vector_end();
+ } else {
+ crypto_sha256_update(desc, data, len);
+ }
+ return 0;
+}
+
+static int riscv64_sha256_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+{
+ if (crypto_simd_usable()) {
+ kernel_vector_begin();
+ if (len)
+ sha256_base_do_update(
+ desc, data, len,
+ sha256_transform_zvknha_or_zvknhb_zvkb);
+ sha256_base_do_finalize(
+ desc, sha256_transform_zvknha_or_zvknhb_zvkb);
+ kernel_vector_end();
+
+ return sha256_base_finish(desc, out);
+ }
+
+ return crypto_sha256_finup(desc, data, len, out);
+}
+
+static int riscv64_sha256_final(struct shash_desc *desc, u8 *out)
+{
+ return riscv64_sha256_finup(desc, NULL, 0, out);
+}
+
+static int riscv64_sha256_digest(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+{
+ return sha256_base_init(desc) ?:
+ riscv64_sha256_finup(desc, data, len, out);
+}
+
+static struct shash_alg riscv64_sha256_algs[] = {
+ {
+ .init = sha256_base_init,
+ .update = riscv64_sha256_update,
+ .final = riscv64_sha256_final,
+ .finup = riscv64_sha256_finup,
+ .digest = riscv64_sha256_digest,
+ .descsize = sizeof(struct sha256_state),
+ .digestsize = SHA256_DIGEST_SIZE,
+ .base = {
+ .cra_blocksize = SHA256_BLOCK_SIZE,
+ .cra_priority = 300,
+ .cra_name = "sha256",
+ .cra_driver_name = "sha256-riscv64-zvknha_or_zvknhb-zvkb",
+ .cra_module = THIS_MODULE,
+ },
+ }, {
+ .init = sha224_base_init,
+ .update = riscv64_sha256_update,
+ .final = riscv64_sha256_final,
+ .finup = riscv64_sha256_finup,
+ .descsize = sizeof(struct sha256_state),
+ .digestsize = SHA224_DIGEST_SIZE,
+ .base = {
+ .cra_blocksize = SHA224_BLOCK_SIZE,
+ .cra_priority = 300,
+ .cra_name = "sha224",
+ .cra_driver_name = "sha224-riscv64-zvknha_or_zvknhb-zvkb",
+ .cra_module = THIS_MODULE,
+ },
+ },
+};
+
+static int __init riscv64_sha256_mod_init(void)
+{
+ /* Both zvknha and zvknhb provide the SHA-256 instructions. */
+ if ((riscv_isa_extension_available(NULL, ZVKNHA) ||
+ riscv_isa_extension_available(NULL, ZVKNHB)) &&
+ riscv_isa_extension_available(NULL, ZVKB) &&
+ riscv_vector_vlen() >= 128)
+ return crypto_register_shashes(riscv64_sha256_algs,
+ ARRAY_SIZE(riscv64_sha256_algs));
+
+ return -ENODEV;
+}
+
+static void __exit riscv64_sha256_mod_exit(void)
+{
+ crypto_unregister_shashes(riscv64_sha256_algs,
+ ARRAY_SIZE(riscv64_sha256_algs));
+}
+
+module_init(riscv64_sha256_mod_init);
+module_exit(riscv64_sha256_mod_exit);
+
+MODULE_DESCRIPTION("SHA-256 (RISC-V accelerated)");
+MODULE_AUTHOR("Heiko Stuebner <heiko.stuebner@vrull.eu>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_CRYPTO("sha256");
+MODULE_ALIAS_CRYPTO("sha224");
diff --git a/arch/riscv/crypto/sha256-riscv64-zvknha_or_zvknhb-zvkb.S b/arch/riscv/crypto/sha256-riscv64-zvknha_or_zvknhb-zvkb.S
new file mode 100644
index 000000000000..8ebcc17de4dc
--- /dev/null
+++ b/arch/riscv/crypto/sha256-riscv64-zvknha_or_zvknhb-zvkb.S
@@ -0,0 +1,225 @@
+/* SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause */
+//
+// This file is dual-licensed, meaning that you can use it under your
+// choice of either of the following two licenses:
+//
+// Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
+//
+// Licensed under the Apache License 2.0 (the "License"). You can obtain
+// a copy in the file LICENSE in the source distribution or at
+// https://www.openssl.org/source/license.html
+//
+// or
+//
+// Copyright (c) 2023, Christoph Müllner <christoph.muellner@vrull.eu>
+// Copyright (c) 2023, Phoebe Chen <phoebe.chen@sifive.com>
+// Copyright 2024 Google LLC
+// All rights reserved.
+//
+// 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
+// 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.
+
+// The generated code of this file depends on the following RISC-V extensions:
+// - RV64I
+// - RISC-V Vector ('V') with VLEN >= 128
+// - RISC-V Vector SHA-2 Secure Hash extension ('Zvknha' or 'Zvknhb')
+// - RISC-V Vector Cryptography Bit-manipulation extension ('Zvkb')
+
+#include <linux/cfi_types.h>
+
+.text
+.option arch, +zvknha, +zvkb
+
+#define STATEP a0
+#define DATA a1
+#define NUM_BLOCKS a2
+
+#define STATEP_C a3
+
+#define MASK v0
+#define INDICES v1
+#define W0 v2
+#define W1 v3
+#define W2 v4
+#define W3 v5
+#define VTMP v6
+#define FEBA v7
+#define HGDC v8
+#define K0 v10
+#define K1 v11
+#define K2 v12
+#define K3 v13
+#define K4 v14
+#define K5 v15
+#define K6 v16
+#define K7 v17
+#define K8 v18
+#define K9 v19
+#define K10 v20
+#define K11 v21
+#define K12 v22
+#define K13 v23
+#define K14 v24
+#define K15 v25
+#define PREV_FEBA v26
+#define PREV_HGDC v27
+
+// Do 4 rounds of SHA-256. w0 contains the current 4 message schedule words.
+//
+// If not all the message schedule words have been computed yet, then this also
+// computes 4 more message schedule words. w1-w3 contain the next 3 groups of 4
+// message schedule words; this macro computes the group after w3 and writes it
+// to w0. This means that the next (w0, w1, w2, w3) is the current (w1, w2, w3,
+// w0), so the caller must cycle through the registers accordingly.
+.macro sha256_4rounds last, k, w0, w1, w2, w3
+ vadd.vv VTMP, \k, \w0
+ vsha2cl.vv HGDC, FEBA, VTMP
+ vsha2ch.vv FEBA, HGDC, VTMP
+.if !\last
+ vmerge.vvm VTMP, \w2, \w1, MASK
+ vsha2ms.vv \w0, VTMP, \w3
+.endif
+.endm
+
+.macro sha256_16rounds last, k0, k1, k2, k3
+ sha256_4rounds \last, \k0, W0, W1, W2, W3
+ sha256_4rounds \last, \k1, W1, W2, W3, W0
+ sha256_4rounds \last, \k2, W2, W3, W0, W1
+ sha256_4rounds \last, \k3, W3, W0, W1, W2
+.endm
+
+// void sha256_transform_zvknha_or_zvknhb_zvkb(u32 state[8], const u8 *data,
+// int num_blocks);
+SYM_TYPED_FUNC_START(sha256_transform_zvknha_or_zvknhb_zvkb)
+
+ // Load the round constants into K0-K15.
+ vsetivli zero, 4, e32, m1, ta, ma
+ la t0, K256
+ vle32.v K0, (t0)
+ addi t0, t0, 16
+ vle32.v K1, (t0)
+ addi t0, t0, 16
+ vle32.v K2, (t0)
+ addi t0, t0, 16
+ vle32.v K3, (t0)
+ addi t0, t0, 16
+ vle32.v K4, (t0)
+ addi t0, t0, 16
+ vle32.v K5, (t0)
+ addi t0, t0, 16
+ vle32.v K6, (t0)
+ addi t0, t0, 16
+ vle32.v K7, (t0)
+ addi t0, t0, 16
+ vle32.v K8, (t0)
+ addi t0, t0, 16
+ vle32.v K9, (t0)
+ addi t0, t0, 16
+ vle32.v K10, (t0)
+ addi t0, t0, 16
+ vle32.v K11, (t0)
+ addi t0, t0, 16
+ vle32.v K12, (t0)
+ addi t0, t0, 16
+ vle32.v K13, (t0)
+ addi t0, t0, 16
+ vle32.v K14, (t0)
+ addi t0, t0, 16
+ vle32.v K15, (t0)
+
+ // Setup mask for the vmerge to replace the first word (idx==0) in
+ // message scheduling. There are 4 words, so an 8-bit mask suffices.
+ vsetivli zero, 1, e8, m1, ta, ma
+ vmv.v.i MASK, 0x01
+
+ // Load the state. The state is stored as {a,b,c,d,e,f,g,h}, but we
+ // need {f,e,b,a},{h,g,d,c}. The dst vtype is e32m1 and the index vtype
+ // is e8mf4. We use index-load with the i8 indices {20, 16, 4, 0},
+ // loaded using the 32-bit little endian value 0x00041014.
+ li t0, 0x00041014
+ vsetivli zero, 1, e32, m1, ta, ma
+ vmv.v.x INDICES, t0
+ addi STATEP_C, STATEP, 8
+ vsetivli zero, 4, e32, m1, ta, ma
+ vluxei8.v FEBA, (STATEP), INDICES
+ vluxei8.v HGDC, (STATEP_C), INDICES
+
+.Lnext_block:
+ addi NUM_BLOCKS, NUM_BLOCKS, -1
+
+ // Save the previous state, as it's needed later.
+ vmv.v.v PREV_FEBA, FEBA
+ vmv.v.v PREV_HGDC, HGDC
+
+ // Load the next 512-bit message block and endian-swap each 32-bit word.
+ vle32.v W0, (DATA)
+ vrev8.v W0, W0
+ addi DATA, DATA, 16
+ vle32.v W1, (DATA)
+ vrev8.v W1, W1
+ addi DATA, DATA, 16
+ vle32.v W2, (DATA)
+ vrev8.v W2, W2
+ addi DATA, DATA, 16
+ vle32.v W3, (DATA)
+ vrev8.v W3, W3
+ addi DATA, DATA, 16
+
+ // Do the 64 rounds of SHA-256.
+ sha256_16rounds 0, K0, K1, K2, K3
+ sha256_16rounds 0, K4, K5, K6, K7
+ sha256_16rounds 0, K8, K9, K10, K11
+ sha256_16rounds 1, K12, K13, K14, K15
+
+ // Add the previous state.
+ vadd.vv FEBA, FEBA, PREV_FEBA
+ vadd.vv HGDC, HGDC, PREV_HGDC
+
+ // Repeat if more blocks remain.
+ bnez NUM_BLOCKS, .Lnext_block
+
+ // Store the new state and return.
+ vsuxei8.v FEBA, (STATEP), INDICES
+ vsuxei8.v HGDC, (STATEP_C), INDICES
+ ret
+SYM_FUNC_END(sha256_transform_zvknha_or_zvknhb_zvkb)
+
+.section ".rodata"
+.p2align 2
+.type K256, @object
+K256:
+ .word 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5
+ .word 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5
+ .word 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3
+ .word 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174
+ .word 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc
+ .word 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da
+ .word 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7
+ .word 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967
+ .word 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13
+ .word 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85
+ .word 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3
+ .word 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070
+ .word 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5
+ .word 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3
+ .word 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208
+ .word 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+.size K256, . - K256
diff --git a/arch/riscv/crypto/sha512-riscv64-glue.c b/arch/riscv/crypto/sha512-riscv64-glue.c
new file mode 100644
index 000000000000..43b56a08aeb5
--- /dev/null
+++ b/arch/riscv/crypto/sha512-riscv64-glue.c
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * SHA-512 and SHA-384 using the RISC-V vector crypto extensions
+ *
+ * Copyright (C) 2023 VRULL GmbH
+ * Author: Heiko Stuebner <heiko.stuebner@vrull.eu>
+ *
+ * Copyright (C) 2023 SiFive, Inc.
+ * Author: Jerry Shih <jerry.shih@sifive.com>
+ */
+
+#include <asm/simd.h>
+#include <asm/vector.h>
+#include <crypto/internal/hash.h>
+#include <crypto/internal/simd.h>
+#include <crypto/sha512_base.h>
+#include <linux/linkage.h>
+#include <linux/module.h>
+
+/*
+ * Note: the asm function only uses the 'state' field of struct sha512_state.
+ * It is assumed to be the first field.
+ */
+asmlinkage void sha512_transform_zvknhb_zvkb(
+ struct sha512_state *state, const u8 *data, int num_blocks);
+
+static int riscv64_sha512_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+{
+ /*
+ * Ensure struct sha512_state begins directly with the SHA-512
+ * 512-bit internal state, as this is what the asm function expects.
+ */
+ BUILD_BUG_ON(offsetof(struct sha512_state, state) != 0);
+
+ if (crypto_simd_usable()) {
+ kernel_vector_begin();
+ sha512_base_do_update(desc, data, len,
+ sha512_transform_zvknhb_zvkb);
+ kernel_vector_end();
+ } else {
+ crypto_sha512_update(desc, data, len);
+ }
+ return 0;
+}
+
+static int riscv64_sha512_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+{
+ if (crypto_simd_usable()) {
+ kernel_vector_begin();
+ if (len)
+ sha512_base_do_update(desc, data, len,
+ sha512_transform_zvknhb_zvkb);
+ sha512_base_do_finalize(desc, sha512_transform_zvknhb_zvkb);
+ kernel_vector_end();
+
+ return sha512_base_finish(desc, out);
+ }
+
+ return crypto_sha512_finup(desc, data, len, out);
+}
+
+static int riscv64_sha512_final(struct shash_desc *desc, u8 *out)
+{
+ return riscv64_sha512_finup(desc, NULL, 0, out);
+}
+
+static int riscv64_sha512_digest(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+{
+ return sha512_base_init(desc) ?:
+ riscv64_sha512_finup(desc, data, len, out);
+}
+
+static struct shash_alg riscv64_sha512_algs[] = {
+ {
+ .init = sha512_base_init,
+ .update = riscv64_sha512_update,
+ .final = riscv64_sha512_final,
+ .finup = riscv64_sha512_finup,
+ .digest = riscv64_sha512_digest,
+ .descsize = sizeof(struct sha512_state),
+ .digestsize = SHA512_DIGEST_SIZE,
+ .base = {
+ .cra_blocksize = SHA512_BLOCK_SIZE,
+ .cra_priority = 300,
+ .cra_name = "sha512",
+ .cra_driver_name = "sha512-riscv64-zvknhb-zvkb",
+ .cra_module = THIS_MODULE,
+ },
+ }, {
+ .init = sha384_base_init,
+ .update = riscv64_sha512_update,
+ .final = riscv64_sha512_final,
+ .finup = riscv64_sha512_finup,
+ .descsize = sizeof(struct sha512_state),
+ .digestsize = SHA384_DIGEST_SIZE,
+ .base = {
+ .cra_blocksize = SHA384_BLOCK_SIZE,
+ .cra_priority = 300,
+ .cra_name = "sha384",
+ .cra_driver_name = "sha384-riscv64-zvknhb-zvkb",
+ .cra_module = THIS_MODULE,
+ },
+ },
+};
+
+static int __init riscv64_sha512_mod_init(void)
+{
+ if (riscv_isa_extension_available(NULL, ZVKNHB) &&
+ riscv_isa_extension_available(NULL, ZVKB) &&
+ riscv_vector_vlen() >= 128)
+ return crypto_register_shashes(riscv64_sha512_algs,
+ ARRAY_SIZE(riscv64_sha512_algs));
+
+ return -ENODEV;
+}
+
+static void __exit riscv64_sha512_mod_exit(void)
+{
+ crypto_unregister_shashes(riscv64_sha512_algs,
+ ARRAY_SIZE(riscv64_sha512_algs));
+}
+
+module_init(riscv64_sha512_mod_init);
+module_exit(riscv64_sha512_mod_exit);
+
+MODULE_DESCRIPTION("SHA-512 (RISC-V accelerated)");
+MODULE_AUTHOR("Heiko Stuebner <heiko.stuebner@vrull.eu>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_CRYPTO("sha512");
+MODULE_ALIAS_CRYPTO("sha384");
diff --git a/arch/riscv/crypto/sha512-riscv64-zvknhb-zvkb.S b/arch/riscv/crypto/sha512-riscv64-zvknhb-zvkb.S
new file mode 100644
index 000000000000..3a9ae210f915
--- /dev/null
+++ b/arch/riscv/crypto/sha512-riscv64-zvknhb-zvkb.S
@@ -0,0 +1,203 @@
+/* SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause */
+//
+// This file is dual-licensed, meaning that you can use it under your
+// choice of either of the following two licenses:
+//
+// Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
+//
+// Licensed under the Apache License 2.0 (the "License"). You can obtain
+// a copy in the file LICENSE in the source distribution or at
+// https://www.openssl.org/source/license.html
+//
+// or
+//
+// Copyright (c) 2023, Christoph Müllner <christoph.muellner@vrull.eu>
+// Copyright (c) 2023, Phoebe Chen <phoebe.chen@sifive.com>
+// Copyright 2024 Google LLC
+// All rights reserved.
+//
+// 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
+// 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.
+
+// The generated code of this file depends on the following RISC-V extensions:
+// - RV64I
+// - RISC-V Vector ('V') with VLEN >= 128
+// - RISC-V Vector SHA-2 Secure Hash extension ('Zvknhb')
+// - RISC-V Vector Cryptography Bit-manipulation extension ('Zvkb')
+
+#include <linux/cfi_types.h>
+
+.text
+.option arch, +zvknhb, +zvkb
+
+#define STATEP a0
+#define DATA a1
+#define NUM_BLOCKS a2
+
+#define STATEP_C a3
+#define K a4
+
+#define MASK v0
+#define INDICES v1
+#define W0 v10 // LMUL=2
+#define W1 v12 // LMUL=2
+#define W2 v14 // LMUL=2
+#define W3 v16 // LMUL=2
+#define VTMP v20 // LMUL=2
+#define FEBA v22 // LMUL=2
+#define HGDC v24 // LMUL=2
+#define PREV_FEBA v26 // LMUL=2
+#define PREV_HGDC v28 // LMUL=2
+
+// Do 4 rounds of SHA-512. w0 contains the current 4 message schedule words.
+//
+// If not all the message schedule words have been computed yet, then this also
+// computes 4 more message schedule words. w1-w3 contain the next 3 groups of 4
+// message schedule words; this macro computes the group after w3 and writes it
+// to w0. This means that the next (w0, w1, w2, w3) is the current (w1, w2, w3,
+// w0), so the caller must cycle through the registers accordingly.
+.macro sha512_4rounds last, w0, w1, w2, w3
+ vle64.v VTMP, (K)
+ addi K, K, 32
+ vadd.vv VTMP, VTMP, \w0
+ vsha2cl.vv HGDC, FEBA, VTMP
+ vsha2ch.vv FEBA, HGDC, VTMP
+.if !\last
+ vmerge.vvm VTMP, \w2, \w1, MASK
+ vsha2ms.vv \w0, VTMP, \w3
+.endif
+.endm
+
+.macro sha512_16rounds last
+ sha512_4rounds \last, W0, W1, W2, W3
+ sha512_4rounds \last, W1, W2, W3, W0
+ sha512_4rounds \last, W2, W3, W0, W1
+ sha512_4rounds \last, W3, W0, W1, W2
+.endm
+
+// void sha512_transform_zvknhb_zvkb(u64 state[8], const u8 *data,
+// int num_blocks);
+SYM_TYPED_FUNC_START(sha512_transform_zvknhb_zvkb)
+
+ // Setup mask for the vmerge to replace the first word (idx==0) in
+ // message scheduling. There are 4 words, so an 8-bit mask suffices.
+ vsetivli zero, 1, e8, m1, ta, ma
+ vmv.v.i MASK, 0x01
+
+ // Load the state. The state is stored as {a,b,c,d,e,f,g,h}, but we
+ // need {f,e,b,a},{h,g,d,c}. The dst vtype is e64m2 and the index vtype
+ // is e8mf4. We use index-load with the i8 indices {40, 32, 8, 0},
+ // loaded using the 32-bit little endian value 0x00082028.
+ li t0, 0x00082028
+ vsetivli zero, 1, e32, m1, ta, ma
+ vmv.v.x INDICES, t0
+ addi STATEP_C, STATEP, 16
+ vsetivli zero, 4, e64, m2, ta, ma
+ vluxei8.v FEBA, (STATEP), INDICES
+ vluxei8.v HGDC, (STATEP_C), INDICES
+
+.Lnext_block:
+ la K, K512
+ addi NUM_BLOCKS, NUM_BLOCKS, -1
+
+ // Save the previous state, as it's needed later.
+ vmv.v.v PREV_FEBA, FEBA
+ vmv.v.v PREV_HGDC, HGDC
+
+ // Load the next 1024-bit message block and endian-swap each 64-bit word
+ vle64.v W0, (DATA)
+ vrev8.v W0, W0
+ addi DATA, DATA, 32
+ vle64.v W1, (DATA)
+ vrev8.v W1, W1
+ addi DATA, DATA, 32
+ vle64.v W2, (DATA)
+ vrev8.v W2, W2
+ addi DATA, DATA, 32
+ vle64.v W3, (DATA)
+ vrev8.v W3, W3
+ addi DATA, DATA, 32
+
+ // Do the 80 rounds of SHA-512.
+ sha512_16rounds 0
+ sha512_16rounds 0
+ sha512_16rounds 0
+ sha512_16rounds 0
+ sha512_16rounds 1
+
+ // Add the previous state.
+ vadd.vv FEBA, FEBA, PREV_FEBA
+ vadd.vv HGDC, HGDC, PREV_HGDC
+
+ // Repeat if more blocks remain.
+ bnez NUM_BLOCKS, .Lnext_block
+
+ // Store the new state and return.
+ vsuxei8.v FEBA, (STATEP), INDICES
+ vsuxei8.v HGDC, (STATEP_C), INDICES
+ ret
+SYM_FUNC_END(sha512_transform_zvknhb_zvkb)
+
+.section ".rodata"
+.p2align 3
+.type K512, @object
+K512:
+ .dword 0x428a2f98d728ae22, 0x7137449123ef65cd
+ .dword 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc
+ .dword 0x3956c25bf348b538, 0x59f111f1b605d019
+ .dword 0x923f82a4af194f9b, 0xab1c5ed5da6d8118
+ .dword 0xd807aa98a3030242, 0x12835b0145706fbe
+ .dword 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2
+ .dword 0x72be5d74f27b896f, 0x80deb1fe3b1696b1
+ .dword 0x9bdc06a725c71235, 0xc19bf174cf692694
+ .dword 0xe49b69c19ef14ad2, 0xefbe4786384f25e3
+ .dword 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65
+ .dword 0x2de92c6f592b0275, 0x4a7484aa6ea6e483
+ .dword 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5
+ .dword 0x983e5152ee66dfab, 0xa831c66d2db43210
+ .dword 0xb00327c898fb213f, 0xbf597fc7beef0ee4
+ .dword 0xc6e00bf33da88fc2, 0xd5a79147930aa725
+ .dword 0x06ca6351e003826f, 0x142929670a0e6e70
+ .dword 0x27b70a8546d22ffc, 0x2e1b21385c26c926
+ .dword 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df
+ .dword 0x650a73548baf63de, 0x766a0abb3c77b2a8
+ .dword 0x81c2c92e47edaee6, 0x92722c851482353b
+ .dword 0xa2bfe8a14cf10364, 0xa81a664bbc423001
+ .dword 0xc24b8b70d0f89791, 0xc76c51a30654be30
+ .dword 0xd192e819d6ef5218, 0xd69906245565a910
+ .dword 0xf40e35855771202a, 0x106aa07032bbd1b8
+ .dword 0x19a4c116b8d2d0c8, 0x1e376c085141ab53
+ .dword 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8
+ .dword 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb
+ .dword 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3
+ .dword 0x748f82ee5defb2fc, 0x78a5636f43172f60
+ .dword 0x84c87814a1f0ab72, 0x8cc702081a6439ec
+ .dword 0x90befffa23631e28, 0xa4506cebde82bde9
+ .dword 0xbef9a3f7b2c67915, 0xc67178f2e372532b
+ .dword 0xca273eceea26619c, 0xd186b8c721c0c207
+ .dword 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178
+ .dword 0x06f067aa72176fba, 0x0a637dc5a2c898a6
+ .dword 0x113f9804bef90dae, 0x1b710b35131c471b
+ .dword 0x28db77f523047d84, 0x32caab7b40c72493
+ .dword 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c
+ .dword 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a
+ .dword 0x5fcb6fab3ad6faec, 0x6c44198c4a475817
+.size K512, . - K512
diff --git a/arch/riscv/crypto/sm3-riscv64-glue.c b/arch/riscv/crypto/sm3-riscv64-glue.c
new file mode 100644
index 000000000000..e1737a970c7c
--- /dev/null
+++ b/arch/riscv/crypto/sm3-riscv64-glue.c
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * SM3 using the RISC-V vector crypto extensions
+ *
+ * Copyright (C) 2023 VRULL GmbH
+ * Author: Heiko Stuebner <heiko.stuebner@vrull.eu>
+ *
+ * Copyright (C) 2023 SiFive, Inc.
+ * Author: Jerry Shih <jerry.shih@sifive.com>
+ */
+
+#include <asm/simd.h>
+#include <asm/vector.h>
+#include <crypto/internal/hash.h>
+#include <crypto/internal/simd.h>
+#include <crypto/sm3_base.h>
+#include <linux/linkage.h>
+#include <linux/module.h>
+
+/*
+ * Note: the asm function only uses the 'state' field of struct sm3_state.
+ * It is assumed to be the first field.
+ */
+asmlinkage void sm3_transform_zvksh_zvkb(
+ struct sm3_state *state, const u8 *data, int num_blocks);
+
+static int riscv64_sm3_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+{
+ /*
+ * Ensure struct sm3_state begins directly with the SM3
+ * 256-bit internal state, as this is what the asm function expects.
+ */
+ BUILD_BUG_ON(offsetof(struct sm3_state, state) != 0);
+
+ if (crypto_simd_usable()) {
+ kernel_vector_begin();
+ sm3_base_do_update(desc, data, len, sm3_transform_zvksh_zvkb);
+ kernel_vector_end();
+ } else {
+ sm3_update(shash_desc_ctx(desc), data, len);
+ }
+ return 0;
+}
+
+static int riscv64_sm3_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+{
+ struct sm3_state *ctx;
+
+ if (crypto_simd_usable()) {
+ kernel_vector_begin();
+ if (len)
+ sm3_base_do_update(desc, data, len,
+ sm3_transform_zvksh_zvkb);
+ sm3_base_do_finalize(desc, sm3_transform_zvksh_zvkb);
+ kernel_vector_end();
+
+ return sm3_base_finish(desc, out);
+ }
+
+ ctx = shash_desc_ctx(desc);
+ if (len)
+ sm3_update(ctx, data, len);
+ sm3_final(ctx, out);
+
+ return 0;
+}
+
+static int riscv64_sm3_final(struct shash_desc *desc, u8 *out)
+{
+ return riscv64_sm3_finup(desc, NULL, 0, out);
+}
+
+static struct shash_alg riscv64_sm3_alg = {
+ .init = sm3_base_init,
+ .update = riscv64_sm3_update,
+ .final = riscv64_sm3_final,
+ .finup = riscv64_sm3_finup,
+ .descsize = sizeof(struct sm3_state),
+ .digestsize = SM3_DIGEST_SIZE,
+ .base = {
+ .cra_blocksize = SM3_BLOCK_SIZE,
+ .cra_priority = 300,
+ .cra_name = "sm3",
+ .cra_driver_name = "sm3-riscv64-zvksh-zvkb",
+ .cra_module = THIS_MODULE,
+ },
+};
+
+static int __init riscv64_sm3_mod_init(void)
+{
+ if (riscv_isa_extension_available(NULL, ZVKSH) &&
+ riscv_isa_extension_available(NULL, ZVKB) &&
+ riscv_vector_vlen() >= 128)
+ return crypto_register_shash(&riscv64_sm3_alg);
+
+ return -ENODEV;
+}
+
+static void __exit riscv64_sm3_mod_exit(void)
+{
+ crypto_unregister_shash(&riscv64_sm3_alg);
+}
+
+module_init(riscv64_sm3_mod_init);
+module_exit(riscv64_sm3_mod_exit);
+
+MODULE_DESCRIPTION("SM3 (RISC-V accelerated)");
+MODULE_AUTHOR("Heiko Stuebner <heiko.stuebner@vrull.eu>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_CRYPTO("sm3");
diff --git a/arch/riscv/crypto/sm3-riscv64-zvksh-zvkb.S b/arch/riscv/crypto/sm3-riscv64-zvksh-zvkb.S
new file mode 100644
index 000000000000..a2b65d961c04
--- /dev/null
+++ b/arch/riscv/crypto/sm3-riscv64-zvksh-zvkb.S
@@ -0,0 +1,123 @@
+/* SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause */
+//
+// This file is dual-licensed, meaning that you can use it under your
+// choice of either of the following two licenses:
+//
+// Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
+//
+// Licensed under the Apache License 2.0 (the "License"). You can obtain
+// a copy in the file LICENSE in the source distribution or at
+// https://www.openssl.org/source/license.html
+//
+// or
+//
+// Copyright (c) 2023, Christoph Müllner <christoph.muellner@vrull.eu>
+// Copyright (c) 2023, Jerry Shih <jerry.shih@sifive.com>
+// Copyright 2024 Google LLC
+// All rights reserved.
+//
+// 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
+// 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.
+
+// The generated code of this file depends on the following RISC-V extensions:
+// - RV64I
+// - RISC-V Vector ('V') with VLEN >= 128
+// - RISC-V Vector SM3 Secure Hash extension ('Zvksh')
+// - RISC-V Vector Cryptography Bit-manipulation extension ('Zvkb')
+
+#include <linux/cfi_types.h>
+
+.text
+.option arch, +zvksh, +zvkb
+
+#define STATEP a0
+#define DATA a1
+#define NUM_BLOCKS a2
+
+#define STATE v0 // LMUL=2
+#define PREV_STATE v2 // LMUL=2
+#define W0 v4 // LMUL=2
+#define W1 v6 // LMUL=2
+#define VTMP v8 // LMUL=2
+
+.macro sm3_8rounds i, w0, w1
+ // Do 4 rounds using W_{0+i}..W_{7+i}.
+ vsm3c.vi STATE, \w0, \i + 0
+ vslidedown.vi VTMP, \w0, 2
+ vsm3c.vi STATE, VTMP, \i + 1
+
+ // Compute W_{4+i}..W_{11+i}.
+ vslidedown.vi VTMP, \w0, 4
+ vslideup.vi VTMP, \w1, 4
+
+ // Do 4 rounds using W_{4+i}..W_{11+i}.
+ vsm3c.vi STATE, VTMP, \i + 2
+ vslidedown.vi VTMP, VTMP, 2
+ vsm3c.vi STATE, VTMP, \i + 3
+
+.if \i < 28
+ // Compute W_{16+i}..W_{23+i}.
+ vsm3me.vv \w0, \w1, \w0
+.endif
+ // For the next 8 rounds, w0 and w1 are swapped.
+.endm
+
+// void sm3_transform_zvksh_zvkb(u32 state[8], const u8 *data, int num_blocks);
+SYM_TYPED_FUNC_START(sm3_transform_zvksh_zvkb)
+
+ // Load the state and endian-swap each 32-bit word.
+ vsetivli zero, 8, e32, m2, ta, ma
+ vle32.v STATE, (STATEP)
+ vrev8.v STATE, STATE
+
+.Lnext_block:
+ addi NUM_BLOCKS, NUM_BLOCKS, -1
+
+ // Save the previous state, as it's needed later.
+ vmv.v.v PREV_STATE, STATE
+
+ // Load the next 512-bit message block into W0-W1.
+ vle32.v W0, (DATA)
+ addi DATA, DATA, 32
+ vle32.v W1, (DATA)
+ addi DATA, DATA, 32
+
+ // Do the 64 rounds of SM3.
+ sm3_8rounds 0, W0, W1
+ sm3_8rounds 4, W1, W0
+ sm3_8rounds 8, W0, W1
+ sm3_8rounds 12, W1, W0
+ sm3_8rounds 16, W0, W1
+ sm3_8rounds 20, W1, W0
+ sm3_8rounds 24, W0, W1
+ sm3_8rounds 28, W1, W0
+
+ // XOR in the previous state.
+ vxor.vv STATE, STATE, PREV_STATE
+
+ // Repeat if more blocks remain.
+ bnez NUM_BLOCKS, .Lnext_block
+
+ // Store the new state and return.
+ vrev8.v STATE, STATE
+ vse32.v STATE, (STATEP)
+ ret
+SYM_FUNC_END(sm3_transform_zvksh_zvkb)
diff --git a/arch/riscv/crypto/sm4-riscv64-glue.c b/arch/riscv/crypto/sm4-riscv64-glue.c
new file mode 100644
index 000000000000..47fb84ebe577
--- /dev/null
+++ b/arch/riscv/crypto/sm4-riscv64-glue.c
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * SM4 using the RISC-V vector crypto extensions
+ *
+ * Copyright (C) 2023 VRULL GmbH
+ * Author: Heiko Stuebner <heiko.stuebner@vrull.eu>
+ *
+ * Copyright (C) 2023 SiFive, Inc.
+ * Author: Jerry Shih <jerry.shih@sifive.com>
+ */
+
+#include <asm/simd.h>
+#include <asm/vector.h>
+#include <crypto/internal/cipher.h>
+#include <crypto/internal/simd.h>
+#include <crypto/sm4.h>
+#include <linux/linkage.h>
+#include <linux/module.h>
+
+asmlinkage void sm4_expandkey_zvksed_zvkb(const u8 user_key[SM4_KEY_SIZE],
+ u32 rkey_enc[SM4_RKEY_WORDS],
+ u32 rkey_dec[SM4_RKEY_WORDS]);
+asmlinkage void sm4_crypt_zvksed_zvkb(const u32 rkey[SM4_RKEY_WORDS],
+ const u8 in[SM4_BLOCK_SIZE],
+ u8 out[SM4_BLOCK_SIZE]);
+
+static int riscv64_sm4_setkey(struct crypto_tfm *tfm, const u8 *key,
+ unsigned int keylen)
+{
+ struct sm4_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ if (crypto_simd_usable()) {
+ if (keylen != SM4_KEY_SIZE)
+ return -EINVAL;
+ kernel_vector_begin();
+ sm4_expandkey_zvksed_zvkb(key, ctx->rkey_enc, ctx->rkey_dec);
+ kernel_vector_end();
+ return 0;
+ }
+ return sm4_expandkey(ctx, key, keylen);
+}
+
+static void riscv64_sm4_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+{
+ const struct sm4_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ if (crypto_simd_usable()) {
+ kernel_vector_begin();
+ sm4_crypt_zvksed_zvkb(ctx->rkey_enc, src, dst);
+ kernel_vector_end();
+ } else {
+ sm4_crypt_block(ctx->rkey_enc, dst, src);
+ }
+}
+
+static void riscv64_sm4_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+{
+ const struct sm4_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ if (crypto_simd_usable()) {
+ kernel_vector_begin();
+ sm4_crypt_zvksed_zvkb(ctx->rkey_dec, src, dst);
+ kernel_vector_end();
+ } else {
+ sm4_crypt_block(ctx->rkey_dec, dst, src);
+ }
+}
+
+static struct crypto_alg riscv64_sm4_alg = {
+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+ .cra_blocksize = SM4_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct sm4_ctx),
+ .cra_priority = 300,
+ .cra_name = "sm4",
+ .cra_driver_name = "sm4-riscv64-zvksed-zvkb",
+ .cra_cipher = {
+ .cia_min_keysize = SM4_KEY_SIZE,
+ .cia_max_keysize = SM4_KEY_SIZE,
+ .cia_setkey = riscv64_sm4_setkey,
+ .cia_encrypt = riscv64_sm4_encrypt,
+ .cia_decrypt = riscv64_sm4_decrypt,
+ },
+ .cra_module = THIS_MODULE,
+};
+
+static int __init riscv64_sm4_mod_init(void)
+{
+ if (riscv_isa_extension_available(NULL, ZVKSED) &&
+ riscv_isa_extension_available(NULL, ZVKB) &&
+ riscv_vector_vlen() >= 128)
+ return crypto_register_alg(&riscv64_sm4_alg);
+
+ return -ENODEV;
+}
+
+static void __exit riscv64_sm4_mod_exit(void)
+{
+ crypto_unregister_alg(&riscv64_sm4_alg);
+}
+
+module_init(riscv64_sm4_mod_init);
+module_exit(riscv64_sm4_mod_exit);
+
+MODULE_DESCRIPTION("SM4 (RISC-V accelerated)");
+MODULE_AUTHOR("Heiko Stuebner <heiko.stuebner@vrull.eu>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_CRYPTO("sm4");
diff --git a/arch/riscv/crypto/sm4-riscv64-zvksed-zvkb.S b/arch/riscv/crypto/sm4-riscv64-zvksed-zvkb.S
new file mode 100644
index 000000000000..fae62179a4a3
--- /dev/null
+++ b/arch/riscv/crypto/sm4-riscv64-zvksed-zvkb.S
@@ -0,0 +1,117 @@
+/* SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause */
+//
+// This file is dual-licensed, meaning that you can use it under your
+// choice of either of the following two licenses:
+//
+// Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
+//
+// Licensed under the Apache License 2.0 (the "License"). You can obtain
+// a copy in the file LICENSE in the source distribution or at
+// https://www.openssl.org/source/license.html
+//
+// or
+//
+// Copyright (c) 2023, Christoph Müllner <christoph.muellner@vrull.eu>
+// Copyright (c) 2023, Jerry Shih <jerry.shih@sifive.com>
+// Copyright 2024 Google LLC
+// All rights reserved.
+//
+// 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
+// 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.
+
+// The generated code of this file depends on the following RISC-V extensions:
+// - RV64I
+// - RISC-V Vector ('V') with VLEN >= 128
+// - RISC-V Vector SM4 Block Cipher extension ('Zvksed')
+// - RISC-V Vector Cryptography Bit-manipulation extension ('Zvkb')
+
+#include <linux/linkage.h>
+
+.text
+.option arch, +zvksed, +zvkb
+
+// void sm4_expandkey_zksed_zvkb(const u8 user_key[16], u32 rkey_enc[32],
+// u32 rkey_dec[32]);
+SYM_FUNC_START(sm4_expandkey_zvksed_zvkb)
+ vsetivli zero, 4, e32, m1, ta, ma
+
+ // Load the user key.
+ vle32.v v1, (a0)
+ vrev8.v v1, v1
+
+ // XOR the user key with the family key.
+ la t0, FAMILY_KEY
+ vle32.v v2, (t0)
+ vxor.vv v1, v1, v2
+
+ // Compute the round keys. Store them in forwards order in rkey_enc
+ // and in reverse order in rkey_dec.
+ addi a2, a2, 31*4
+ li t0, -4
+ .set i, 0
+.rept 8
+ vsm4k.vi v1, v1, i
+ vse32.v v1, (a1) // Store to rkey_enc.
+ vsse32.v v1, (a2), t0 // Store to rkey_dec.
+.if i < 7
+ addi a1, a1, 16
+ addi a2, a2, -16
+.endif
+ .set i, i + 1
+.endr
+
+ ret
+SYM_FUNC_END(sm4_expandkey_zvksed_zvkb)
+
+// void sm4_crypt_zvksed_zvkb(const u32 rkey[32], const u8 in[16], u8 out[16]);
+SYM_FUNC_START(sm4_crypt_zvksed_zvkb)
+ vsetivli zero, 4, e32, m1, ta, ma
+
+ // Load the input data.
+ vle32.v v1, (a1)
+ vrev8.v v1, v1
+
+ // Do the 32 rounds of SM4, 4 at a time.
+ .set i, 0
+.rept 8
+ vle32.v v2, (a0)
+ vsm4r.vs v1, v2
+.if i < 7
+ addi a0, a0, 16
+.endif
+ .set i, i + 1
+.endr
+
+ // Store the output data (in reverse element order).
+ vrev8.v v1, v1
+ li t0, -4
+ addi a2, a2, 12
+ vsse32.v v1, (a2), t0
+
+ ret
+SYM_FUNC_END(sm4_crypt_zvksed_zvkb)
+
+.section ".rodata"
+.p2align 2
+.type FAMILY_KEY, @object
+FAMILY_KEY:
+ .word 0xA3B1BAC6, 0x56AA3350, 0x677D9197, 0xB27022DC
+.size FAMILY_KEY, . - FAMILY_KEY
diff --git a/arch/riscv/errata/andes/errata.c b/arch/riscv/errata/andes/errata.c
index 17a904869724..f2708a9494a1 100644
--- a/arch/riscv/errata/andes/errata.c
+++ b/arch/riscv/errata/andes/errata.c
@@ -18,9 +18,9 @@
#include <asm/sbi.h>
#include <asm/vendorid_list.h>
-#define ANDESTECH_AX45MP_MARCHID 0x8000000000008a45UL
-#define ANDESTECH_AX45MP_MIMPID 0x500UL
-#define ANDESTECH_SBI_EXT_ANDES 0x0900031E
+#define ANDES_AX45MP_MARCHID 0x8000000000008a45UL
+#define ANDES_AX45MP_MIMPID 0x500UL
+#define ANDES_SBI_EXT_ANDES 0x0900031E
#define ANDES_SBI_EXT_IOCP_SW_WORKAROUND 1
@@ -32,7 +32,7 @@ static long ax45mp_iocp_sw_workaround(void)
* ANDES_SBI_EXT_IOCP_SW_WORKAROUND SBI EXT checks if the IOCP is missing and
* cache is controllable only then CMO will be applied to the platform.
*/
- ret = sbi_ecall(ANDESTECH_SBI_EXT_ANDES, ANDES_SBI_EXT_IOCP_SW_WORKAROUND,
+ ret = sbi_ecall(ANDES_SBI_EXT_ANDES, ANDES_SBI_EXT_IOCP_SW_WORKAROUND,
0, 0, 0, 0, 0, 0);
return ret.error ? 0 : ret.value;
@@ -50,7 +50,7 @@ static void errata_probe_iocp(unsigned int stage, unsigned long arch_id, unsigne
done = true;
- if (arch_id != ANDESTECH_AX45MP_MARCHID || impid != ANDESTECH_AX45MP_MIMPID)
+ if (arch_id != ANDES_AX45MP_MARCHID || impid != ANDES_AX45MP_MIMPID)
return;
if (!ax45mp_iocp_sw_workaround())
diff --git a/arch/riscv/include/asm/asm.h b/arch/riscv/include/asm/asm.h
index b0487b39e674..776354895b81 100644
--- a/arch/riscv/include/asm/asm.h
+++ b/arch/riscv/include/asm/asm.h
@@ -183,6 +183,16 @@
REG_L x31, PT_T6(sp)
.endm
+/* Annotate a function as being unsuitable for kprobes. */
+#ifdef CONFIG_KPROBES
+#define ASM_NOKPROBE(name) \
+ .pushsection "_kprobe_blacklist", "aw"; \
+ RISCV_PTR name; \
+ .popsection
+#else
+#define ASM_NOKPROBE(name)
+#endif
+
#endif /* __ASSEMBLY__ */
#endif /* _ASM_RISCV_ASM_H */
diff --git a/arch/riscv/include/asm/atomic.h b/arch/riscv/include/asm/atomic.h
index f5dfef6c2153..0e0522e588ca 100644
--- a/arch/riscv/include/asm/atomic.h
+++ b/arch/riscv/include/asm/atomic.h
@@ -17,7 +17,6 @@
#endif
#include <asm/cmpxchg.h>
-#include <asm/barrier.h>
#define __atomic_acquire_fence() \
__asm__ __volatile__(RISCV_ACQUIRE_BARRIER "" ::: "memory")
@@ -207,7 +206,7 @@ static __always_inline int arch_atomic_fetch_add_unless(atomic_t *v, int a, int
" add %[rc], %[p], %[a]\n"
" sc.w.rl %[rc], %[rc], %[c]\n"
" bnez %[rc], 0b\n"
- " fence rw, rw\n"
+ RISCV_FULL_BARRIER
"1:\n"
: [p]"=&r" (prev), [rc]"=&r" (rc), [c]"+A" (v->counter)
: [a]"r" (a), [u]"r" (u)
@@ -228,7 +227,7 @@ static __always_inline s64 arch_atomic64_fetch_add_unless(atomic64_t *v, s64 a,
" add %[rc], %[p], %[a]\n"
" sc.d.rl %[rc], %[rc], %[c]\n"
" bnez %[rc], 0b\n"
- " fence rw, rw\n"
+ RISCV_FULL_BARRIER
"1:\n"
: [p]"=&r" (prev), [rc]"=&r" (rc), [c]"+A" (v->counter)
: [a]"r" (a), [u]"r" (u)
@@ -248,7 +247,7 @@ static __always_inline bool arch_atomic_inc_unless_negative(atomic_t *v)
" addi %[rc], %[p], 1\n"
" sc.w.rl %[rc], %[rc], %[c]\n"
" bnez %[rc], 0b\n"
- " fence rw, rw\n"
+ RISCV_FULL_BARRIER
"1:\n"
: [p]"=&r" (prev), [rc]"=&r" (rc), [c]"+A" (v->counter)
:
@@ -268,7 +267,7 @@ static __always_inline bool arch_atomic_dec_unless_positive(atomic_t *v)
" addi %[rc], %[p], -1\n"
" sc.w.rl %[rc], %[rc], %[c]\n"
" bnez %[rc], 0b\n"
- " fence rw, rw\n"
+ RISCV_FULL_BARRIER
"1:\n"
: [p]"=&r" (prev), [rc]"=&r" (rc), [c]"+A" (v->counter)
:
@@ -288,7 +287,7 @@ static __always_inline int arch_atomic_dec_if_positive(atomic_t *v)
" bltz %[rc], 1f\n"
" sc.w.rl %[rc], %[rc], %[c]\n"
" bnez %[rc], 0b\n"
- " fence rw, rw\n"
+ RISCV_FULL_BARRIER
"1:\n"
: [p]"=&r" (prev), [rc]"=&r" (rc), [c]"+A" (v->counter)
:
@@ -310,7 +309,7 @@ static __always_inline bool arch_atomic64_inc_unless_negative(atomic64_t *v)
" addi %[rc], %[p], 1\n"
" sc.d.rl %[rc], %[rc], %[c]\n"
" bnez %[rc], 0b\n"
- " fence rw, rw\n"
+ RISCV_FULL_BARRIER
"1:\n"
: [p]"=&r" (prev), [rc]"=&r" (rc), [c]"+A" (v->counter)
:
@@ -331,7 +330,7 @@ static __always_inline bool arch_atomic64_dec_unless_positive(atomic64_t *v)
" addi %[rc], %[p], -1\n"
" sc.d.rl %[rc], %[rc], %[c]\n"
" bnez %[rc], 0b\n"
- " fence rw, rw\n"
+ RISCV_FULL_BARRIER
"1:\n"
: [p]"=&r" (prev), [rc]"=&r" (rc), [c]"+A" (v->counter)
:
@@ -352,7 +351,7 @@ static __always_inline s64 arch_atomic64_dec_if_positive(atomic64_t *v)
" bltz %[rc], 1f\n"
" sc.d.rl %[rc], %[rc], %[c]\n"
" bnez %[rc], 0b\n"
- " fence rw, rw\n"
+ RISCV_FULL_BARRIER
"1:\n"
: [p]"=&r" (prev), [rc]"=&r" (rc), [c]"+A" (v->counter)
:
diff --git a/arch/riscv/include/asm/barrier.h b/arch/riscv/include/asm/barrier.h
index 110752594228..880b56d8480d 100644
--- a/arch/riscv/include/asm/barrier.h
+++ b/arch/riscv/include/asm/barrier.h
@@ -11,28 +11,27 @@
#define _ASM_RISCV_BARRIER_H
#ifndef __ASSEMBLY__
+#include <asm/fence.h>
#define nop() __asm__ __volatile__ ("nop")
#define __nops(n) ".rept " #n "\nnop\n.endr\n"
#define nops(n) __asm__ __volatile__ (__nops(n))
-#define RISCV_FENCE(p, s) \
- __asm__ __volatile__ ("fence " #p "," #s : : : "memory")
/* These barriers need to enforce ordering on both devices or memory. */
-#define mb() RISCV_FENCE(iorw,iorw)
-#define rmb() RISCV_FENCE(ir,ir)
-#define wmb() RISCV_FENCE(ow,ow)
+#define __mb() RISCV_FENCE(iorw, iorw)
+#define __rmb() RISCV_FENCE(ir, ir)
+#define __wmb() RISCV_FENCE(ow, ow)
/* These barriers do not need to enforce ordering on devices, just memory. */
-#define __smp_mb() RISCV_FENCE(rw,rw)
-#define __smp_rmb() RISCV_FENCE(r,r)
-#define __smp_wmb() RISCV_FENCE(w,w)
+#define __smp_mb() RISCV_FENCE(rw, rw)
+#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); \
+ RISCV_FENCE(rw, w); \
WRITE_ONCE(*p, v); \
} while (0)
@@ -40,7 +39,7 @@ do { \
({ \
typeof(*p) ___p1 = READ_ONCE(*p); \
compiletime_assert_atomic_type(*p); \
- RISCV_FENCE(r,rw); \
+ RISCV_FENCE(r, rw); \
___p1; \
})
@@ -69,7 +68,7 @@ do { \
* instances the scheduler pairs this with an mb(), so nothing is necessary on
* the new hart.
*/
-#define smp_mb__after_spinlock() RISCV_FENCE(iorw,iorw)
+#define smp_mb__after_spinlock() RISCV_FENCE(iorw, iorw)
#include <asm-generic/barrier.h>
diff --git a/arch/riscv/include/asm/bitops.h b/arch/riscv/include/asm/bitops.h
index 329d8244a9b3..880606b0469a 100644
--- a/arch/riscv/include/asm/bitops.h
+++ b/arch/riscv/include/asm/bitops.h
@@ -22,6 +22,16 @@
#include <asm-generic/bitops/fls.h>
#else
+#define __HAVE_ARCH___FFS
+#define __HAVE_ARCH___FLS
+#define __HAVE_ARCH_FFS
+#define __HAVE_ARCH_FLS
+
+#include <asm-generic/bitops/__ffs.h>
+#include <asm-generic/bitops/__fls.h>
+#include <asm-generic/bitops/ffs.h>
+#include <asm-generic/bitops/fls.h>
+
#include <asm/alternative-macros.h>
#include <asm/hwcap.h>
@@ -37,8 +47,6 @@
static __always_inline unsigned long variable__ffs(unsigned long word)
{
- int num;
-
asm goto(ALTERNATIVE("j %l[legacy]", "nop", 0,
RISCV_ISA_EXT_ZBB, 1)
: : : : legacy);
@@ -52,32 +60,7 @@ static __always_inline unsigned long variable__ffs(unsigned long word)
return word;
legacy:
- num = 0;
-#if BITS_PER_LONG == 64
- if ((word & 0xffffffff) == 0) {
- num += 32;
- word >>= 32;
- }
-#endif
- if ((word & 0xffff) == 0) {
- num += 16;
- word >>= 16;
- }
- if ((word & 0xff) == 0) {
- num += 8;
- word >>= 8;
- }
- if ((word & 0xf) == 0) {
- num += 4;
- word >>= 4;
- }
- if ((word & 0x3) == 0) {
- num += 2;
- word >>= 2;
- }
- if ((word & 0x1) == 0)
- num += 1;
- return num;
+ return generic___ffs(word);
}
/**
@@ -93,8 +76,6 @@ legacy:
static __always_inline unsigned long variable__fls(unsigned long word)
{
- int num;
-
asm goto(ALTERNATIVE("j %l[legacy]", "nop", 0,
RISCV_ISA_EXT_ZBB, 1)
: : : : legacy);
@@ -108,32 +89,7 @@ static __always_inline unsigned long variable__fls(unsigned long word)
return BITS_PER_LONG - 1 - word;
legacy:
- num = BITS_PER_LONG - 1;
-#if BITS_PER_LONG == 64
- if (!(word & (~0ul << 32))) {
- num -= 32;
- word <<= 32;
- }
-#endif
- if (!(word & (~0ul << (BITS_PER_LONG - 16)))) {
- num -= 16;
- word <<= 16;
- }
- if (!(word & (~0ul << (BITS_PER_LONG - 8)))) {
- num -= 8;
- word <<= 8;
- }
- if (!(word & (~0ul << (BITS_PER_LONG - 4)))) {
- num -= 4;
- word <<= 4;
- }
- if (!(word & (~0ul << (BITS_PER_LONG - 2)))) {
- num -= 2;
- word <<= 2;
- }
- if (!(word & (~0ul << (BITS_PER_LONG - 1))))
- num -= 1;
- return num;
+ return generic___fls(word);
}
/**
@@ -149,46 +105,23 @@ legacy:
static __always_inline int variable_ffs(int x)
{
- int r;
-
- if (!x)
- return 0;
-
asm goto(ALTERNATIVE("j %l[legacy]", "nop", 0,
RISCV_ISA_EXT_ZBB, 1)
: : : : legacy);
+ if (!x)
+ return 0;
+
asm volatile (".option push\n"
".option arch,+zbb\n"
CTZW "%0, %1\n"
".option pop\n"
- : "=r" (r) : "r" (x) :);
+ : "=r" (x) : "r" (x) :);
- return r + 1;
+ return x + 1;
legacy:
- r = 1;
- if (!(x & 0xffff)) {
- x >>= 16;
- r += 16;
- }
- if (!(x & 0xff)) {
- x >>= 8;
- r += 8;
- }
- if (!(x & 0xf)) {
- x >>= 4;
- r += 4;
- }
- if (!(x & 3)) {
- x >>= 2;
- r += 2;
- }
- if (!(x & 1)) {
- x >>= 1;
- r += 1;
- }
- return r;
+ return generic_ffs(x);
}
/**
@@ -204,46 +137,23 @@ legacy:
static __always_inline int variable_fls(unsigned int x)
{
- int r;
-
- if (!x)
- return 0;
-
asm goto(ALTERNATIVE("j %l[legacy]", "nop", 0,
RISCV_ISA_EXT_ZBB, 1)
: : : : legacy);
+ if (!x)
+ return 0;
+
asm volatile (".option push\n"
".option arch,+zbb\n"
CLZW "%0, %1\n"
".option pop\n"
- : "=r" (r) : "r" (x) :);
+ : "=r" (x) : "r" (x) :);
- return 32 - r;
+ return 32 - x;
legacy:
- r = 32;
- if (!(x & 0xffff0000u)) {
- x <<= 16;
- r -= 16;
- }
- if (!(x & 0xff000000u)) {
- x <<= 8;
- r -= 8;
- }
- if (!(x & 0xf0000000u)) {
- x <<= 4;
- r -= 4;
- }
- if (!(x & 0xc0000000u)) {
- x <<= 2;
- r -= 2;
- }
- if (!(x & 0x80000000u)) {
- x <<= 1;
- r -= 1;
- }
- return r;
+ return generic_fls(x);
}
/**
diff --git a/arch/riscv/include/asm/cfi.h b/arch/riscv/include/asm/cfi.h
index 8f7a62257044..fb9696d7a3f2 100644
--- a/arch/riscv/include/asm/cfi.h
+++ b/arch/riscv/include/asm/cfi.h
@@ -13,11 +13,28 @@ struct pt_regs;
#ifdef CONFIG_CFI_CLANG
enum bug_trap_type handle_cfi_failure(struct pt_regs *regs);
+#define __bpfcall
+static inline int cfi_get_offset(void)
+{
+ return 4;
+}
+
+#define cfi_get_offset cfi_get_offset
+extern u32 cfi_bpf_hash;
+extern u32 cfi_bpf_subprog_hash;
+extern u32 cfi_get_func_hash(void *func);
#else
static inline enum bug_trap_type handle_cfi_failure(struct pt_regs *regs)
{
return BUG_TRAP_TYPE_NONE;
}
+
+#define cfi_bpf_hash 0U
+#define cfi_bpf_subprog_hash 0U
+static inline u32 cfi_get_func_hash(void *func)
+{
+ return 0;
+}
#endif /* CONFIG_CFI_CLANG */
#endif /* _ASM_RISCV_CFI_H */
diff --git a/arch/riscv/include/asm/cmpxchg.h b/arch/riscv/include/asm/cmpxchg.h
index 2f4726d3cfcc..2fee65cc8443 100644
--- a/arch/riscv/include/asm/cmpxchg.h
+++ b/arch/riscv/include/asm/cmpxchg.h
@@ -8,7 +8,6 @@
#include <linux/bug.h>
-#include <asm/barrier.h>
#include <asm/fence.h>
#define __xchg_relaxed(ptr, new, size) \
@@ -313,7 +312,7 @@
" bne %0, %z3, 1f\n" \
" sc.w.rl %1, %z4, %2\n" \
" bnez %1, 0b\n" \
- " fence rw, rw\n" \
+ RISCV_FULL_BARRIER \
"1:\n" \
: "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \
: "rJ" ((long)__old), "rJ" (__new) \
@@ -325,7 +324,7 @@
" bne %0, %z3, 1f\n" \
" sc.d.rl %1, %z4, %2\n" \
" bnez %1, 0b\n" \
- " fence rw, rw\n" \
+ RISCV_FULL_BARRIER \
"1:\n" \
: "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \
: "rJ" (__old), "rJ" (__new) \
diff --git a/arch/riscv/include/asm/compat.h b/arch/riscv/include/asm/compat.h
index 2ac955b51148..aa103530a5c8 100644
--- a/arch/riscv/include/asm/compat.h
+++ b/arch/riscv/include/asm/compat.h
@@ -14,9 +14,28 @@
static inline int is_compat_task(void)
{
+ if (!IS_ENABLED(CONFIG_COMPAT))
+ return 0;
+
return test_thread_flag(TIF_32BIT);
}
+static inline int is_compat_thread(struct thread_info *thread)
+{
+ if (!IS_ENABLED(CONFIG_COMPAT))
+ return 0;
+
+ return test_ti_thread_flag(thread, TIF_32BIT);
+}
+
+static inline void set_compat_task(bool is_compat)
+{
+ if (is_compat)
+ set_thread_flag(TIF_32BIT);
+ else
+ clear_thread_flag(TIF_32BIT);
+}
+
struct compat_user_regs_struct {
compat_ulong_t pc;
compat_ulong_t ra;
diff --git a/arch/riscv/include/asm/cpufeature.h b/arch/riscv/include/asm/cpufeature.h
index 0bd11862b760..347805446151 100644
--- a/arch/riscv/include/asm/cpufeature.h
+++ b/arch/riscv/include/asm/cpufeature.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright 2022-2023 Rivos, Inc
+ * Copyright 2022-2024 Rivos, Inc
*/
#ifndef _ASM_CPUFEATURE_H
@@ -28,29 +28,38 @@ struct riscv_isainfo {
DECLARE_PER_CPU(struct riscv_cpuinfo, riscv_cpuinfo);
-DECLARE_PER_CPU(long, misaligned_access_speed);
-
/* Per-cpu ISA extensions. */
extern struct riscv_isainfo hart_isa[NR_CPUS];
void riscv_user_isa_enable(void);
-#ifdef CONFIG_RISCV_MISALIGNED
-bool unaligned_ctl_available(void);
-bool check_unaligned_access_emulated(int cpu);
+#if defined(CONFIG_RISCV_MISALIGNED)
+bool check_unaligned_access_emulated_all_cpus(void);
void unaligned_emulation_finish(void);
+bool unaligned_ctl_available(void);
+DECLARE_PER_CPU(long, misaligned_access_speed);
#else
static inline bool unaligned_ctl_available(void)
{
return false;
}
+#endif
+
+#if defined(CONFIG_RISCV_PROBE_UNALIGNED_ACCESS)
+DECLARE_STATIC_KEY_FALSE(fast_unaligned_access_speed_key);
-static inline bool check_unaligned_access_emulated(int cpu)
+static __always_inline bool has_fast_unaligned_accesses(void)
{
- return false;
+ return static_branch_likely(&fast_unaligned_access_speed_key);
+}
+#else
+static __always_inline bool has_fast_unaligned_accesses(void)
+{
+ if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS))
+ return true;
+ else
+ return false;
}
-
-static inline void unaligned_emulation_finish(void) {}
#endif
unsigned long riscv_get_elf_hwcap(void);
@@ -135,6 +144,4 @@ static __always_inline bool riscv_cpu_has_extension_unlikely(int cpu, const unsi
return __riscv_isa_extension_available(hart_isa[cpu].isa, ext);
}
-DECLARE_STATIC_KEY_FALSE(fast_misaligned_access_speed_key);
-
#endif
diff --git a/arch/riscv/include/asm/crash_core.h b/arch/riscv/include/asm/crash_reserve.h
index e1874b23feaf..013962e63587 100644
--- a/arch/riscv/include/asm/crash_core.h
+++ b/arch/riscv/include/asm/crash_reserve.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-#ifndef _RISCV_CRASH_CORE_H
-#define _RISCV_CRASH_CORE_H
+#ifndef _RISCV_CRASH_RESERVE_H
+#define _RISCV_CRASH_RESERVE_H
#define CRASH_ALIGN PMD_SIZE
diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
index 06c236bfab53..c7aea7886d22 100644
--- a/arch/riscv/include/asm/elf.h
+++ b/arch/riscv/include/asm/elf.h
@@ -53,13 +53,9 @@ extern bool compat_elf_check_arch(Elf32_Ehdr *hdr);
#define ELF_ET_DYN_BASE ((DEFAULT_MAP_WINDOW / 3) * 2)
#ifdef CONFIG_64BIT
-#ifdef CONFIG_COMPAT
-#define STACK_RND_MASK (test_thread_flag(TIF_32BIT) ? \
+#define STACK_RND_MASK (is_compat_task() ? \
0x7ff >> (PAGE_SHIFT - 12) : \
0x3ffff >> (PAGE_SHIFT - 12))
-#else
-#define STACK_RND_MASK (0x3ffff >> (PAGE_SHIFT - 12))
-#endif
#endif
/*
@@ -139,10 +135,7 @@ do { \
#ifdef CONFIG_COMPAT
#define SET_PERSONALITY(ex) \
-do { if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
- set_thread_flag(TIF_32BIT); \
- else \
- clear_thread_flag(TIF_32BIT); \
+do { set_compat_task((ex).e_ident[EI_CLASS] == ELFCLASS32); \
if (personality(current->personality) != PER_LINUX32) \
set_personality(PER_LINUX | \
(current->personality & (~PER_MASK))); \
diff --git a/arch/riscv/include/asm/errata_list.h b/arch/riscv/include/asm/errata_list.h
index ea33288f8a25..1f2dbfb8a8bf 100644
--- a/arch/riscv/include/asm/errata_list.h
+++ b/arch/riscv/include/asm/errata_list.h
@@ -12,8 +12,8 @@
#include <asm/vendorid_list.h>
#ifdef CONFIG_ERRATA_ANDES
-#define ERRATA_ANDESTECH_NO_IOCP 0
-#define ERRATA_ANDESTECH_NUMBER 1
+#define ERRATA_ANDES_NO_IOCP 0
+#define ERRATA_ANDES_NUMBER 1
#endif
#ifdef CONFIG_ERRATA_SIFIVE
@@ -112,15 +112,6 @@ asm volatile(ALTERNATIVE( \
#define THEAD_C9XX_RV_IRQ_PMU 17
#define THEAD_C9XX_CSR_SCOUNTEROF 0x5c5
-#define ALT_SBI_PMU_OVERFLOW(__ovl) \
-asm volatile(ALTERNATIVE( \
- "csrr %0, " __stringify(CSR_SSCOUNTOVF), \
- "csrr %0, " __stringify(THEAD_C9XX_CSR_SCOUNTEROF), \
- THEAD_VENDOR_ID, ERRATA_THEAD_PMU, \
- CONFIG_ERRATA_THEAD_PMU) \
- : "=r" (__ovl) : \
- : "memory")
-
#endif /* __ASSEMBLY__ */
#endif
diff --git a/arch/riscv/include/asm/fence.h b/arch/riscv/include/asm/fence.h
index 2b443a3a487f..6bcd80325dfc 100644
--- a/arch/riscv/include/asm/fence.h
+++ b/arch/riscv/include/asm/fence.h
@@ -1,12 +1,18 @@
#ifndef _ASM_RISCV_FENCE_H
#define _ASM_RISCV_FENCE_H
+#define RISCV_FENCE_ASM(p, s) "\tfence " #p "," #s "\n"
+#define RISCV_FENCE(p, s) \
+ ({ __asm__ __volatile__ (RISCV_FENCE_ASM(p, s) : : : "memory"); })
+
#ifdef CONFIG_SMP
-#define RISCV_ACQUIRE_BARRIER "\tfence r , rw\n"
-#define RISCV_RELEASE_BARRIER "\tfence rw, w\n"
+#define RISCV_ACQUIRE_BARRIER RISCV_FENCE_ASM(r, rw)
+#define RISCV_RELEASE_BARRIER RISCV_FENCE_ASM(rw, w)
+#define RISCV_FULL_BARRIER RISCV_FENCE_ASM(rw, rw)
#else
#define RISCV_ACQUIRE_BARRIER
#define RISCV_RELEASE_BARRIER
+#define RISCV_FULL_BARRIER
#endif
#endif /* _ASM_RISCV_FENCE_H */
diff --git a/arch/riscv/include/asm/ftrace.h b/arch/riscv/include/asm/ftrace.h
index 15055f9df4da..1276d7d9ca8b 100644
--- a/arch/riscv/include/asm/ftrace.h
+++ b/arch/riscv/include/asm/ftrace.h
@@ -13,16 +13,6 @@
#endif
#define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
-/*
- * Clang prior to 13 had "mcount" instead of "_mcount":
- * https://reviews.llvm.org/D98881
- */
-#if defined(CONFIG_CC_IS_GCC) || CONFIG_CLANG_VERSION >= 130000
-#define MCOUNT_NAME _mcount
-#else
-#define MCOUNT_NAME mcount
-#endif
-
#define ARCH_SUPPORTS_FTRACE_OPS 1
#ifndef __ASSEMBLY__
@@ -30,7 +20,7 @@ extern void *return_address(unsigned int level);
#define ftrace_return_address(n) return_address(n)
-void MCOUNT_NAME(void);
+void _mcount(void);
static inline unsigned long ftrace_call_adjust(unsigned long addr)
{
return addr;
@@ -80,7 +70,7 @@ struct dyn_arch_ftrace {
* both auipc and jalr at the same time.
*/
-#define MCOUNT_ADDR ((unsigned long)MCOUNT_NAME)
+#define MCOUNT_ADDR ((unsigned long)_mcount)
#define JALR_SIGN_MASK (0x00000800)
#define JALR_OFFSET_MASK (0x00000fff)
#define AUIPC_OFFSET_MASK (0xfffff000)
diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h
index 1f2d2599c655..e17d0078a651 100644
--- a/arch/riscv/include/asm/hwcap.h
+++ b/arch/riscv/include/asm/hwcap.h
@@ -80,6 +80,7 @@
#define RISCV_ISA_EXT_ZFA 71
#define RISCV_ISA_EXT_ZTSO 72
#define RISCV_ISA_EXT_ZACAS 73
+#define RISCV_ISA_EXT_XANDESPMU 74
#define RISCV_ISA_EXT_XLINUXENVCFG 127
diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h
index 42497d487a17..1c5c641075d2 100644
--- a/arch/riscv/include/asm/io.h
+++ b/arch/riscv/include/asm/io.h
@@ -47,10 +47,10 @@
* sufficient to ensure this works sanely on controllers that support I/O
* writes.
*/
-#define __io_pbr() __asm__ __volatile__ ("fence io,i" : : : "memory");
-#define __io_par(v) __asm__ __volatile__ ("fence i,ior" : : : "memory");
-#define __io_pbw() __asm__ __volatile__ ("fence iow,o" : : : "memory");
-#define __io_paw() __asm__ __volatile__ ("fence o,io" : : : "memory");
+#define __io_pbr() RISCV_FENCE(io, i)
+#define __io_par(v) RISCV_FENCE(i, ior)
+#define __io_pbw() RISCV_FENCE(iow, o)
+#define __io_paw() RISCV_FENCE(o, io)
/*
* Accesses from a single hart to a single I/O address must be ordered. This
diff --git a/arch/riscv/include/asm/membarrier.h b/arch/riscv/include/asm/membarrier.h
new file mode 100644
index 000000000000..47b240d0d596
--- /dev/null
+++ b/arch/riscv/include/asm/membarrier.h
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _ASM_RISCV_MEMBARRIER_H
+#define _ASM_RISCV_MEMBARRIER_H
+
+static inline void membarrier_arch_switch_mm(struct mm_struct *prev,
+ struct mm_struct *next,
+ struct task_struct *tsk)
+{
+ /*
+ * Only need the full barrier when switching between processes.
+ * Barrier when switching from kernel to userspace is not
+ * required here, given that it is implied by mmdrop(). Barrier
+ * when switching from userspace to kernel is not needed after
+ * store to rq->curr.
+ */
+ if (IS_ENABLED(CONFIG_SMP) &&
+ likely(!(atomic_read(&next->membarrier_state) &
+ (MEMBARRIER_STATE_PRIVATE_EXPEDITED |
+ MEMBARRIER_STATE_GLOBAL_EXPEDITED)) || !prev))
+ return;
+
+ /*
+ * The membarrier system call requires a full memory barrier
+ * after storing to rq->curr, before going back to user-space.
+ *
+ * This barrier is also needed for the SYNC_CORE command when
+ * switching between processes; in particular, on a transition
+ * from a thread belonging to another mm to a thread belonging
+ * to the mm for which a membarrier SYNC_CORE is done on CPU0:
+ *
+ * - [CPU0] sets all bits in the mm icache_stale_mask (in
+ * prepare_sync_core_cmd());
+ *
+ * - [CPU1] stores to rq->curr (by the scheduler);
+ *
+ * - [CPU0] loads rq->curr within membarrier and observes
+ * cpu_rq(1)->curr->mm != mm, so the IPI is skipped on
+ * CPU1; this means membarrier relies on switch_mm() to
+ * issue the sync-core;
+ *
+ * - [CPU1] switch_mm() loads icache_stale_mask; if the bit
+ * is zero, switch_mm() may incorrectly skip the sync-core.
+ *
+ * Matches a full barrier in the proximity of the membarrier
+ * system call entry.
+ */
+ smp_mb();
+}
+
+#endif /* _ASM_RISCV_MEMBARRIER_H */
diff --git a/arch/riscv/include/asm/mmio.h b/arch/riscv/include/asm/mmio.h
index 4c58ee7f95ec..06cadfd7a237 100644
--- a/arch/riscv/include/asm/mmio.h
+++ b/arch/riscv/include/asm/mmio.h
@@ -12,6 +12,7 @@
#define _ASM_RISCV_MMIO_H
#include <linux/types.h>
+#include <asm/fence.h>
#include <asm/mmiowb.h>
/* Generic IO read/write. These perform native-endian accesses. */
@@ -131,8 +132,8 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
* doesn't define any ordering between the memory space and the I/O space.
*/
#define __io_br() do {} while (0)
-#define __io_ar(v) ({ __asm__ __volatile__ ("fence i,ir" : : : "memory"); })
-#define __io_bw() ({ __asm__ __volatile__ ("fence w,o" : : : "memory"); })
+#define __io_ar(v) RISCV_FENCE(i, ir)
+#define __io_bw() RISCV_FENCE(w, o)
#define __io_aw() mmiowb_set_pending()
#define readb(c) ({ u8 __v; __io_br(); __v = readb_cpu(c); __io_ar(__v); __v; })
diff --git a/arch/riscv/include/asm/mmiowb.h b/arch/riscv/include/asm/mmiowb.h
index 0b2333e71fdc..52ce4a399d9b 100644
--- a/arch/riscv/include/asm/mmiowb.h
+++ b/arch/riscv/include/asm/mmiowb.h
@@ -7,7 +7,7 @@
* "o,w" is sufficient to ensure that all writes to the device have completed
* before the write to the spinlock is allowed to commit.
*/
-#define mmiowb() __asm__ __volatile__ ("fence o,w" : : : "memory");
+#define mmiowb() RISCV_FENCE(o, w)
#include <linux/smp.h>
#include <asm-generic/mmiowb.h>
diff --git a/arch/riscv/include/asm/page.h b/arch/riscv/include/asm/page.h
index 57e887bfa34c..2947423b5082 100644
--- a/arch/riscv/include/asm/page.h
+++ b/arch/riscv/include/asm/page.h
@@ -12,7 +12,7 @@
#include <linux/pfn.h>
#include <linux/const.h>
-#define PAGE_SHIFT (12)
+#define PAGE_SHIFT CONFIG_PAGE_SHIFT
#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE - 1))
diff --git a/arch/riscv/include/asm/pgalloc.h b/arch/riscv/include/asm/pgalloc.h
index c80bb9990d32..deaf971253a2 100644
--- a/arch/riscv/include/asm/pgalloc.h
+++ b/arch/riscv/include/asm/pgalloc.h
@@ -95,13 +95,19 @@ static inline void pud_free(struct mm_struct *mm, pud_t *pud)
__pud_free(mm, pud);
}
-#define __pud_free_tlb(tlb, pud, addr) \
-do { \
- if (pgtable_l4_enabled) { \
- pagetable_pud_dtor(virt_to_ptdesc(pud)); \
- tlb_remove_page_ptdesc((tlb), virt_to_ptdesc(pud)); \
- } \
-} while (0)
+static inline void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pud,
+ unsigned long addr)
+{
+ if (pgtable_l4_enabled) {
+ 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);
+ }
+}
#define p4d_alloc_one p4d_alloc_one
static inline p4d_t *p4d_alloc_one(struct mm_struct *mm, unsigned long addr)
@@ -130,11 +136,16 @@ static inline void p4d_free(struct mm_struct *mm, p4d_t *p4d)
__p4d_free(mm, p4d);
}
-#define __p4d_free_tlb(tlb, p4d, addr) \
-do { \
- if (pgtable_l5_enabled) \
- tlb_remove_page_ptdesc((tlb), virt_to_ptdesc(p4d)); \
-} while (0)
+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));
+ }
+}
#endif /* __PAGETABLE_PMD_FOLDED */
static inline void sync_kernel_mappings(pgd_t *pgd)
@@ -159,19 +170,31 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
#ifndef __PAGETABLE_PMD_FOLDED
-#define __pmd_free_tlb(tlb, pmd, addr) \
-do { \
- pagetable_pmd_dtor(virt_to_ptdesc(pmd)); \
- tlb_remove_page_ptdesc((tlb), virt_to_ptdesc(pmd)); \
-} while (0)
+static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd,
+ unsigned long addr)
+{
+ 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);
+}
#endif /* __PAGETABLE_PMD_FOLDED */
-#define __pte_free_tlb(tlb, pte, buf) \
-do { \
- pagetable_pte_dtor(page_ptdesc(pte)); \
- tlb_remove_page_ptdesc((tlb), page_ptdesc(pte));\
-} while (0)
+static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
+ unsigned long addr)
+{
+ 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);
+}
#endif /* CONFIG_MMU */
#endif /* _ASM_RISCV_PGALLOC_H */
diff --git a/arch/riscv/include/asm/pgtable-64.h b/arch/riscv/include/asm/pgtable-64.h
index b99bd66107a6..221a5c1ee287 100644
--- a/arch/riscv/include/asm/pgtable-64.h
+++ b/arch/riscv/include/asm/pgtable-64.h
@@ -190,7 +190,7 @@ static inline int pud_bad(pud_t pud)
}
#define pud_leaf pud_leaf
-static inline int pud_leaf(pud_t pud)
+static inline bool pud_leaf(pud_t pud)
{
return pud_present(pud) && (pud_val(pud) & _PAGE_LEAF);
}
diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
index 6066822e7396..9f8ea0e33eb1 100644
--- a/arch/riscv/include/asm/pgtable.h
+++ b/arch/riscv/include/asm/pgtable.h
@@ -127,17 +127,11 @@
#define VA_USER_SV48 (UL(1) << (VA_BITS_SV48 - 1))
#define VA_USER_SV57 (UL(1) << (VA_BITS_SV57 - 1))
-#ifdef CONFIG_COMPAT
#define MMAP_VA_BITS_64 ((VA_BITS >= VA_BITS_SV48) ? VA_BITS_SV48 : VA_BITS)
#define MMAP_MIN_VA_BITS_64 (VA_BITS_SV39)
#define MMAP_VA_BITS (is_compat_task() ? VA_BITS_SV32 : MMAP_VA_BITS_64)
#define MMAP_MIN_VA_BITS (is_compat_task() ? VA_BITS_SV32 : MMAP_MIN_VA_BITS_64)
#else
-#define MMAP_VA_BITS ((VA_BITS >= VA_BITS_SV48) ? VA_BITS_SV48 : VA_BITS)
-#define MMAP_MIN_VA_BITS (VA_BITS_SV39)
-#endif /* CONFIG_COMPAT */
-
-#else
#include <asm/pgtable-32.h>
#endif /* CONFIG_64BIT */
@@ -241,7 +235,7 @@ static inline int pmd_bad(pmd_t pmd)
}
#define pmd_leaf pmd_leaf
-static inline int pmd_leaf(pmd_t pmd)
+static inline bool pmd_leaf(pmd_t pmd)
{
return pmd_present(pmd) && (pmd_val(pmd) & _PAGE_LEAF);
}
@@ -439,9 +433,11 @@ static inline pte_t pte_mkhuge(pte_t pte)
return pte;
}
+#ifdef CONFIG_RISCV_ISA_SVNAPOT
#define pte_leaf_size(pte) (pte_napot(pte) ? \
napot_cont_size(napot_cont_order(pte)) :\
PAGE_SIZE)
+#endif
#ifdef CONFIG_NUMA_BALANCING
/*
@@ -517,23 +513,25 @@ static inline void set_pte(pte_t *ptep, pte_t pteval)
WRITE_ONCE(*ptep, pteval);
}
-void flush_icache_pte(pte_t pte);
+void flush_icache_pte(struct mm_struct *mm, pte_t pte);
-static inline void __set_pte_at(pte_t *ptep, pte_t pteval)
+static inline void __set_pte_at(struct mm_struct *mm, pte_t *ptep, pte_t pteval)
{
if (pte_present(pteval) && pte_exec(pteval))
- flush_icache_pte(pteval);
+ flush_icache_pte(mm, pteval);
set_pte(ptep, pteval);
}
+#define PFN_PTE_SHIFT _PAGE_PFN_SHIFT
+
static inline void set_ptes(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pteval, unsigned int nr)
{
page_table_check_ptes_set(mm, ptep, pteval, nr);
for (;;) {
- __set_pte_at(ptep, pteval);
+ __set_pte_at(mm, ptep, pteval);
if (--nr == 0)
break;
ptep++;
@@ -545,7 +543,7 @@ static inline void set_ptes(struct mm_struct *mm, unsigned long addr,
static inline void pte_clear(struct mm_struct *mm,
unsigned long addr, pte_t *ptep)
{
- __set_pte_at(ptep, __pte(0));
+ __set_pte_at(mm, ptep, __pte(0));
}
#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS /* defined in mm/pgtable.c */
@@ -595,6 +593,12 @@ static inline int ptep_clear_flush_young(struct vm_area_struct *vma,
return ptep_test_and_clear_young(vma, address, ptep);
}
+#define pgprot_nx pgprot_nx
+static inline pgprot_t pgprot_nx(pgprot_t _prot)
+{
+ return __pgprot(pgprot_val(_prot) & ~_PAGE_EXEC);
+}
+
#define pgprot_noncached pgprot_noncached
static inline pgprot_t pgprot_noncached(pgprot_t _prot)
{
@@ -660,6 +664,12 @@ static inline int pmd_write(pmd_t pmd)
return pte_write(pmd_pte(pmd));
}
+#define pud_write pud_write
+static inline int pud_write(pud_t pud)
+{
+ return pte_write(pud_pte(pud));
+}
+
#define pmd_dirty pmd_dirty
static inline int pmd_dirty(pmd_t pmd)
{
@@ -711,14 +721,14 @@ static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
pmd_t *pmdp, pmd_t pmd)
{
page_table_check_pmd_set(mm, pmdp, pmd);
- return __set_pte_at((pte_t *)pmdp, pmd_pte(pmd));
+ return __set_pte_at(mm, (pte_t *)pmdp, pmd_pte(pmd));
}
static inline void set_pud_at(struct mm_struct *mm, unsigned long addr,
pud_t *pudp, pud_t pud)
{
page_table_check_pud_set(mm, pudp, pud);
- return __set_pte_at((pte_t *)pudp, pud_pte(pud));
+ return __set_pte_at(mm, (pte_t *)pudp, pud_pte(pud));
}
#ifdef CONFIG_PAGE_TABLE_CHECK
@@ -869,8 +879,8 @@ static inline pte_t pte_swp_clear_exclusive(pte_t pte)
#define TASK_SIZE_MIN (PGDIR_SIZE_L3 * PTRS_PER_PGD / 2)
#ifdef CONFIG_COMPAT
-#define TASK_SIZE_32 (_AC(0x80000000, UL))
-#define TASK_SIZE (test_thread_flag(TIF_32BIT) ? \
+#define TASK_SIZE_32 (_AC(0x80000000, UL) - PAGE_SIZE)
+#define TASK_SIZE (is_compat_task() ? \
TASK_SIZE_32 : TASK_SIZE_64)
#else
#define TASK_SIZE TASK_SIZE_64
diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h
index a8509cc31ab2..0faf5f161f1e 100644
--- a/arch/riscv/include/asm/processor.h
+++ b/arch/riscv/include/asm/processor.h
@@ -14,22 +14,21 @@
#include <asm/ptrace.h>
-#ifdef CONFIG_64BIT
-#define DEFAULT_MAP_WINDOW (UL(1) << (MMAP_VA_BITS - 1))
-#define STACK_TOP_MAX TASK_SIZE
-
+/*
+ * addr is a hint to the maximum userspace address that mmap should provide, so
+ * this macro needs to return the largest address space available so that
+ * mmap_end < addr, being mmap_end the top of that address space.
+ * See Documentation/arch/riscv/vm-layout.rst for more details.
+ */
#define arch_get_mmap_end(addr, len, flags) \
({ \
unsigned long mmap_end; \
typeof(addr) _addr = (addr); \
- if ((_addr) == 0 || (IS_ENABLED(CONFIG_COMPAT) && is_compat_task())) \
- mmap_end = STACK_TOP_MAX; \
- else if ((_addr) >= VA_USER_SV57) \
+ if ((_addr) == 0 || is_compat_task() || \
+ ((_addr + len) > BIT(VA_BITS - 1))) \
mmap_end = STACK_TOP_MAX; \
- else if ((((_addr) >= VA_USER_SV48)) && (VA_BITS >= VA_BITS_SV48)) \
- mmap_end = VA_USER_SV48; \
else \
- mmap_end = VA_USER_SV39; \
+ mmap_end = (_addr + len); \
mmap_end; \
})
@@ -39,17 +38,17 @@
typeof(addr) _addr = (addr); \
typeof(base) _base = (base); \
unsigned long rnd_gap = DEFAULT_MAP_WINDOW - (_base); \
- if ((_addr) == 0 || (IS_ENABLED(CONFIG_COMPAT) && is_compat_task())) \
+ if ((_addr) == 0 || is_compat_task() || \
+ ((_addr + len) > BIT(VA_BITS - 1))) \
mmap_base = (_base); \
- else if (((_addr) >= VA_USER_SV57) && (VA_BITS >= VA_BITS_SV57)) \
- mmap_base = VA_USER_SV57 - rnd_gap; \
- else if ((((_addr) >= VA_USER_SV48)) && (VA_BITS >= VA_BITS_SV48)) \
- mmap_base = VA_USER_SV48 - rnd_gap; \
else \
- mmap_base = VA_USER_SV39 - rnd_gap; \
+ mmap_base = (_addr + len) - rnd_gap; \
mmap_base; \
})
+#ifdef CONFIG_64BIT
+#define DEFAULT_MAP_WINDOW (UL(1) << (MMAP_VA_BITS - 1))
+#define STACK_TOP_MAX TASK_SIZE_64
#else
#define DEFAULT_MAP_WINDOW TASK_SIZE
#define STACK_TOP_MAX TASK_SIZE
diff --git a/arch/riscv/include/asm/ptdump.h b/arch/riscv/include/asm/ptdump.h
deleted file mode 100644
index 3c9ea6dd5af7..000000000000
--- a/arch/riscv/include/asm/ptdump.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2019 SiFive
- */
-
-#ifndef _ASM_RISCV_PTDUMP_H
-#define _ASM_RISCV_PTDUMP_H
-
-void ptdump_check_wx(void);
-
-#ifdef CONFIG_DEBUG_WX
-static inline void debug_checkwx(void)
-{
- ptdump_check_wx();
-}
-#else
-static inline void debug_checkwx(void)
-{
-}
-#endif
-
-#endif /* _ASM_RISCV_PTDUMP_H */
diff --git a/arch/riscv/include/asm/simd.h b/arch/riscv/include/asm/simd.h
index 54efbf523d49..adb50f3ec205 100644
--- a/arch/riscv/include/asm/simd.h
+++ b/arch/riscv/include/asm/simd.h
@@ -34,9 +34,9 @@ static __must_check inline bool may_use_simd(void)
return false;
/*
- * Nesting is acheived in preempt_v by spreading the control for
+ * Nesting is achieved in preempt_v by spreading the control for
* preemptible and non-preemptible kernel-mode Vector into two fields.
- * Always try to match with prempt_v if kernel V-context exists. Then,
+ * Always try to match with preempt_v if kernel V-context exists. Then,
* fallback to check non preempt_v if nesting happens, or if the config
* is not set.
*/
diff --git a/arch/riscv/include/asm/suspend.h b/arch/riscv/include/asm/suspend.h
index 491296a335d0..4718096fa5e3 100644
--- a/arch/riscv/include/asm/suspend.h
+++ b/arch/riscv/include/asm/suspend.h
@@ -56,4 +56,7 @@ int hibernate_resume_nonboot_cpu_disable(void);
asmlinkage void hibernate_restore_image(unsigned long resume_satp, unsigned long satp_temp,
unsigned long cpu_resume);
asmlinkage int hibernate_core_restore_code(void);
+bool riscv_sbi_hsm_is_supported(void);
+bool riscv_sbi_suspend_state_is_valid(u32 state);
+int riscv_sbi_hart_suspend(u32 state);
#endif
diff --git a/arch/riscv/include/asm/sync_core.h b/arch/riscv/include/asm/sync_core.h
new file mode 100644
index 000000000000..9153016da8f1
--- /dev/null
+++ b/arch/riscv/include/asm/sync_core.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_RISCV_SYNC_CORE_H
+#define _ASM_RISCV_SYNC_CORE_H
+
+/*
+ * RISC-V implements return to user-space through an xRET instruction,
+ * which is not core serializing.
+ */
+static inline void sync_core_before_usermode(void)
+{
+ asm volatile ("fence.i" ::: "memory");
+}
+
+#ifdef CONFIG_SMP
+/*
+ * Ensure the next switch_mm() on every CPU issues a core serializing
+ * instruction for the given @mm.
+ */
+static inline void prepare_sync_core_cmd(struct mm_struct *mm)
+{
+ cpumask_setall(&mm->context.icache_stale_mask);
+}
+#else
+static inline void prepare_sync_core_cmd(struct mm_struct *mm)
+{
+}
+#endif /* CONFIG_SMP */
+
+#endif /* _ASM_RISCV_SYNC_CORE_H */
diff --git a/arch/riscv/include/asm/syscall_wrapper.h b/arch/riscv/include/asm/syscall_wrapper.h
index eeec04b7dae6..ac80216549ff 100644
--- a/arch/riscv/include/asm/syscall_wrapper.h
+++ b/arch/riscv/include/asm/syscall_wrapper.h
@@ -12,25 +12,52 @@
asmlinkage long __riscv_sys_ni_syscall(const struct pt_regs *);
-#define SC_RISCV_REGS_TO_ARGS(x, ...) \
- __MAP(x,__SC_ARGS \
- ,,regs->orig_a0,,regs->a1,,regs->a2 \
+#ifdef CONFIG_64BIT
+
+#define __SYSCALL_SE_DEFINEx(x, prefix, name, ...) \
+ static long __se_##prefix##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \
+ static long __se_##prefix##name(__MAP(x,__SC_LONG,__VA_ARGS__))
+
+#define SC_RISCV_REGS_TO_ARGS(x, ...) \
+ __MAP(x,__SC_ARGS \
+ ,,regs->orig_a0,,regs->a1,,regs->a2 \
,,regs->a3,,regs->a4,,regs->a5,,regs->a6)
+#else
+/*
+ * Use type aliasing to ensure registers a0-a6 are correctly passed to the syscall
+ * implementation when >word-size arguments are used.
+ */
+#define __SYSCALL_SE_DEFINEx(x, prefix, name, ...) \
+ __diag_push(); \
+ __diag_ignore(GCC, 8, "-Wattribute-alias", \
+ "Type aliasing is used to sanitize syscall arguments"); \
+ static long __se_##prefix##name(ulong, ulong, ulong, ulong, ulong, ulong, \
+ ulong) \
+ __attribute__((alias(__stringify(___se_##prefix##name)))); \
+ __diag_pop(); \
+ static long noinline ___se_##prefix##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \
+ __used; \
+ static long ___se_##prefix##name(__MAP(x,__SC_LONG,__VA_ARGS__))
+
+#define SC_RISCV_REGS_TO_ARGS(x, ...) \
+ regs->orig_a0,regs->a1,regs->a2,regs->a3,regs->a4,regs->a5,regs->a6
+
+#endif /* CONFIG_64BIT */
+
#ifdef CONFIG_COMPAT
#define COMPAT_SYSCALL_DEFINEx(x, name, ...) \
asmlinkage long __riscv_compat_sys##name(const struct pt_regs *regs); \
ALLOW_ERROR_INJECTION(__riscv_compat_sys##name, ERRNO); \
- static long __se_compat_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \
static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \
- asmlinkage long __riscv_compat_sys##name(const struct pt_regs *regs) \
+ __SYSCALL_SE_DEFINEx(x, compat_sys, name, __VA_ARGS__) \
{ \
- return __se_compat_sys##name(SC_RISCV_REGS_TO_ARGS(x,__VA_ARGS__)); \
+ return __do_compat_sys##name(__MAP(x,__SC_DELOUSE,__VA_ARGS__)); \
} \
- static long __se_compat_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \
+ asmlinkage long __riscv_compat_sys##name(const struct pt_regs *regs) \
{ \
- return __do_compat_sys##name(__MAP(x,__SC_DELOUSE,__VA_ARGS__)); \
+ return __se_compat_sys##name(SC_RISCV_REGS_TO_ARGS(x,__VA_ARGS__)); \
} \
static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
@@ -51,19 +78,18 @@ asmlinkage long __riscv_sys_ni_syscall(const struct pt_regs *);
#define __SYSCALL_DEFINEx(x, name, ...) \
asmlinkage long __riscv_sys##name(const struct pt_regs *regs); \
ALLOW_ERROR_INJECTION(__riscv_sys##name, ERRNO); \
- static long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \
static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \
- asmlinkage long __riscv_sys##name(const struct pt_regs *regs) \
- { \
- return __se_sys##name(SC_RISCV_REGS_TO_ARGS(x,__VA_ARGS__)); \
- } \
- static long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \
+ __SYSCALL_SE_DEFINEx(x, sys, name, __VA_ARGS__) \
{ \
long ret = __do_sys##name(__MAP(x,__SC_CAST,__VA_ARGS__)); \
__MAP(x,__SC_TEST,__VA_ARGS__); \
__PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); \
return ret; \
} \
+ asmlinkage long __riscv_sys##name(const struct pt_regs *regs) \
+ { \
+ return __se_sys##name(SC_RISCV_REGS_TO_ARGS(x,__VA_ARGS__)); \
+ } \
static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
#define SYSCALL_DEFINE0(sname) \
diff --git a/arch/riscv/include/asm/tlb.h b/arch/riscv/include/asm/tlb.h
index 50b63b5c15bd..1f6c38420d8e 100644
--- a/arch/riscv/include/asm/tlb.h
+++ b/arch/riscv/include/asm/tlb.h
@@ -10,6 +10,24 @@ struct mmu_gather;
static void tlb_flush(struct mmu_gather *tlb);
+#ifdef CONFIG_MMU
+#include <linux/swap.h>
+
+/*
+ * While riscv platforms with riscv_ipi_for_rfence as true require an IPI to
+ * perform TLB shootdown, some platforms with riscv_ipi_for_rfence as false use
+ * SBI to perform TLB shootdown. To keep software pagetable walkers safe in this
+ * case we switch to RCU based table free (MMU_GATHER_RCU_TABLE_FREE). See the
+ * comment below 'ifdef CONFIG_MMU_GATHER_RCU_TABLE_FREE' in include/asm-generic/tlb.h
+ * for more details.
+ */
+static inline void __tlb_remove_table(void *table)
+{
+ free_page_and_swap_cache(table);
+}
+
+#endif /* CONFIG_MMU */
+
#define tlb_flush tlb_flush
#include <asm-generic/tlb.h>
diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h
index ec0cab9fbddd..72ec1d9bd3f3 100644
--- a/arch/riscv/include/asm/uaccess.h
+++ b/arch/riscv/include/asm/uaccess.h
@@ -319,7 +319,7 @@ unsigned long __must_check clear_user(void __user *to, unsigned long n)
#define __get_kernel_nofault(dst, src, type, err_label) \
do { \
- long __kr_err; \
+ long __kr_err = 0; \
\
__get_user_nocheck(*((type *)(dst)), (type *)(src), __kr_err); \
if (unlikely(__kr_err)) \
@@ -328,7 +328,7 @@ do { \
#define __put_kernel_nofault(dst, src, type, err_label) \
do { \
- long __kr_err; \
+ long __kr_err = 0; \
\
__put_user_nocheck(*((type *)(src)), (type *)(dst), __kr_err); \
if (unlikely(__kr_err)) \
diff --git a/arch/riscv/include/asm/vector.h b/arch/riscv/include/asm/vector.h
index 0cd6f0a027d1..731dcd0ed4de 100644
--- a/arch/riscv/include/asm/vector.h
+++ b/arch/riscv/include/asm/vector.h
@@ -284,4 +284,15 @@ static inline bool riscv_v_vstate_ctrl_user_allowed(void) { return false; }
#endif /* CONFIG_RISCV_ISA_V */
+/*
+ * Return the implementation's vlen value.
+ *
+ * riscv_v_vsize contains the value of "32 vector registers with vlenb length"
+ * so rebuild the vlen value in bits from it.
+ */
+static inline int riscv_vector_vlen(void)
+{
+ return riscv_v_vsize / 32 * 8;
+}
+
#endif /* ! __ASM_RISCV_VECTOR_H */
diff --git a/arch/riscv/include/asm/vendorid_list.h b/arch/riscv/include/asm/vendorid_list.h
index e55407ace0c3..2f2bb0c84f9a 100644
--- a/arch/riscv/include/asm/vendorid_list.h
+++ b/arch/riscv/include/asm/vendorid_list.h
@@ -5,7 +5,7 @@
#ifndef ASM_VENDOR_LIST_H
#define ASM_VENDOR_LIST_H
-#define ANDESTECH_VENDOR_ID 0x31e
+#define ANDES_VENDOR_ID 0x31e
#define SIFIVE_VENDOR_ID 0x489
#define THEAD_VENDOR_ID 0x5b7
diff --git a/arch/riscv/include/asm/word-at-a-time.h b/arch/riscv/include/asm/word-at-a-time.h
index f3f031e34191..3802cda71ab7 100644
--- a/arch/riscv/include/asm/word-at-a-time.h
+++ b/arch/riscv/include/asm/word-at-a-time.h
@@ -10,7 +10,8 @@
#include <asm/asm-extable.h>
-#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/wordpart.h>
struct word_at_a_time {
const unsigned long one_bits, high_bits;
diff --git a/arch/riscv/include/uapi/asm/auxvec.h b/arch/riscv/include/uapi/asm/auxvec.h
index 10aaa83db89e..95050ebe9ad0 100644
--- a/arch/riscv/include/uapi/asm/auxvec.h
+++ b/arch/riscv/include/uapi/asm/auxvec.h
@@ -34,7 +34,7 @@
#define AT_L3_CACHEGEOMETRY 47
/* entries in ARCH_DLINFO */
-#define AT_VECTOR_SIZE_ARCH 9
+#define AT_VECTOR_SIZE_ARCH 10
#define AT_MINSIGSTKSZ 51
#endif /* _UAPI_ASM_RISCV_AUXVEC_H */
diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h
index 7499e88a947c..b1c503c2959c 100644
--- a/arch/riscv/include/uapi/asm/kvm.h
+++ b/arch/riscv/include/uapi/asm/kvm.h
@@ -16,7 +16,6 @@
#include <asm/ptrace.h>
#define __KVM_HAVE_IRQ_LINE
-#define __KVM_HAVE_READONLY_MEM
#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
@@ -166,6 +165,8 @@ enum KVM_RISCV_ISA_EXT_ID {
KVM_RISCV_ISA_EXT_ZVFH,
KVM_RISCV_ISA_EXT_ZVFHMIN,
KVM_RISCV_ISA_EXT_ZFA,
+ KVM_RISCV_ISA_EXT_ZTSO,
+ KVM_RISCV_ISA_EXT_ZACAS,
KVM_RISCV_ISA_EXT_MAX,
};
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 604d6bf7e476..81d94a8ee10f 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -39,7 +39,6 @@ extra-y += vmlinux.lds
obj-y += head.o
obj-y += soc.o
obj-$(CONFIG_RISCV_ALTERNATIVE) += alternative.o
-obj-y += copy-unaligned.o
obj-y += cpu.o
obj-y += cpufeature.o
obj-y += entry.o
@@ -64,6 +63,9 @@ obj-y += tests/
obj-$(CONFIG_MMU) += vdso.o vdso/
obj-$(CONFIG_RISCV_MISALIGNED) += traps_misaligned.o
+obj-$(CONFIG_RISCV_MISALIGNED) += unaligned_access_speed.o
+obj-$(CONFIG_RISCV_PROBE_UNALIGNED_ACCESS) += copy-unaligned.o
+
obj-$(CONFIG_FPU) += fpu.o
obj-$(CONFIG_RISCV_ISA_V) += vector.o
obj-$(CONFIG_RISCV_ISA_V) += kernel_mode_vector.o
@@ -94,7 +96,7 @@ obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_KEXEC_CORE) += kexec_relocate.o crash_save_regs.o machine_kexec.o
obj-$(CONFIG_KEXEC_FILE) += elf_kexec.o machine_kexec_file.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
-obj-$(CONFIG_CRASH_CORE) += crash_core.o
+obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o
obj-$(CONFIG_JUMP_LABEL) += jump_label.o
diff --git a/arch/riscv/kernel/alternative.c b/arch/riscv/kernel/alternative.c
index 319a1da0358b..0128b161bfda 100644
--- a/arch/riscv/kernel/alternative.c
+++ b/arch/riscv/kernel/alternative.c
@@ -43,7 +43,7 @@ static void riscv_fill_cpu_mfr_info(struct cpu_manufacturer_info_t *cpu_mfr_info
switch (cpu_mfr_info->vendor_id) {
#ifdef CONFIG_ERRATA_ANDES
- case ANDESTECH_VENDOR_ID:
+ case ANDES_VENDOR_ID:
cpu_mfr_info->patch_func = andes_errata_patch_func;
break;
#endif
diff --git a/arch/riscv/kernel/cfi.c b/arch/riscv/kernel/cfi.c
index 6ec9dbd7292e..64bdd3e1ab8c 100644
--- a/arch/riscv/kernel/cfi.c
+++ b/arch/riscv/kernel/cfi.c
@@ -75,3 +75,56 @@ enum bug_trap_type handle_cfi_failure(struct pt_regs *regs)
return report_cfi_failure(regs, regs->epc, &target, type);
}
+
+#ifdef CONFIG_CFI_CLANG
+struct bpf_insn;
+
+/* Must match bpf_func_t / DEFINE_BPF_PROG_RUN() */
+extern unsigned int __bpf_prog_runX(const void *ctx,
+ const struct bpf_insn *insn);
+
+/*
+ * Force a reference to the external symbol so the compiler generates
+ * __kcfi_typid.
+ */
+__ADDRESSABLE(__bpf_prog_runX);
+
+/* u32 __ro_after_init cfi_bpf_hash = __kcfi_typeid___bpf_prog_runX; */
+asm (
+" .pushsection .data..ro_after_init,\"aw\",@progbits \n"
+" .type cfi_bpf_hash,@object \n"
+" .globl cfi_bpf_hash \n"
+" .p2align 2, 0x0 \n"
+"cfi_bpf_hash: \n"
+" .word __kcfi_typeid___bpf_prog_runX \n"
+" .size cfi_bpf_hash, 4 \n"
+" .popsection \n"
+);
+
+/* Must match bpf_callback_t */
+extern u64 __bpf_callback_fn(u64, u64, u64, u64, u64);
+
+__ADDRESSABLE(__bpf_callback_fn);
+
+/* u32 __ro_after_init cfi_bpf_subprog_hash = __kcfi_typeid___bpf_callback_fn; */
+asm (
+" .pushsection .data..ro_after_init,\"aw\",@progbits \n"
+" .type cfi_bpf_subprog_hash,@object \n"
+" .globl cfi_bpf_subprog_hash \n"
+" .p2align 2, 0x0 \n"
+"cfi_bpf_subprog_hash: \n"
+" .word __kcfi_typeid___bpf_callback_fn \n"
+" .size cfi_bpf_subprog_hash, 4 \n"
+" .popsection \n"
+);
+
+u32 cfi_get_func_hash(void *func)
+{
+ u32 hash;
+
+ if (get_kernel_nofault(hash, func - cfi_get_offset()))
+ return 0;
+
+ return hash;
+}
+#endif
diff --git a/arch/riscv/kernel/compat_vdso/Makefile b/arch/riscv/kernel/compat_vdso/Makefile
index 62fa393b2eb2..3df4cb788c1f 100644
--- a/arch/riscv/kernel/compat_vdso/Makefile
+++ b/arch/riscv/kernel/compat_vdso/Makefile
@@ -74,5 +74,5 @@ quiet_cmd_compat_vdsold = VDSOLD $@
rm $@.tmp
# actual build commands
-quiet_cmd_compat_vdsoas = VDSOAS $@
+quiet_cmd_compat_vdsoas = VDSOAS $@
cmd_compat_vdsoas = $(COMPAT_CC) $(a_flags) $(COMPAT_CC_FLAGS) -c -o $@ $<
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index 79a5a35fab96..3ed2359eae35 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -11,7 +11,6 @@
#include <linux/cpu.h>
#include <linux/cpuhotplug.h>
#include <linux/ctype.h>
-#include <linux/jump_label.h>
#include <linux/log2.h>
#include <linux/memory.h>
#include <linux/module.h>
@@ -21,21 +20,13 @@
#include <asm/cacheflush.h>
#include <asm/cpufeature.h>
#include <asm/hwcap.h>
-#include <asm/hwprobe.h>
#include <asm/patch.h>
#include <asm/processor.h>
#include <asm/sbi.h>
#include <asm/vector.h>
-#include "copy-unaligned.h"
-
#define NUM_ALPHA_EXTS ('z' - 'a' + 1)
-#define MISALIGNED_ACCESS_JIFFIES_LG2 1
-#define MISALIGNED_BUFFER_SIZE 0x4000
-#define MISALIGNED_BUFFER_ORDER get_order(MISALIGNED_BUFFER_SIZE)
-#define MISALIGNED_COPY_SIZE ((MISALIGNED_BUFFER_SIZE / 2) - 0x80)
-
unsigned long elf_hwcap __read_mostly;
/* Host ISA bitmap */
@@ -44,11 +35,6 @@ static DECLARE_BITMAP(riscv_isa, RISCV_ISA_EXT_MAX) __read_mostly;
/* Per-cpu ISA extensions. */
struct riscv_isainfo hart_isa[NR_CPUS];
-/* Performance information */
-DEFINE_PER_CPU(long, misaligned_access_speed);
-
-static cpumask_t fast_misaligned_access;
-
/**
* riscv_isa_extension_base() - Get base extension word
*
@@ -318,6 +304,7 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
__RISCV_ISA_EXT_DATA(svinval, RISCV_ISA_EXT_SVINVAL),
__RISCV_ISA_EXT_DATA(svnapot, RISCV_ISA_EXT_SVNAPOT),
__RISCV_ISA_EXT_DATA(svpbmt, RISCV_ISA_EXT_SVPBMT),
+ __RISCV_ISA_EXT_DATA(xandespmu, RISCV_ISA_EXT_XANDESPMU),
};
const size_t riscv_isa_ext_count = ARRAY_SIZE(riscv_isa_ext);
@@ -731,247 +718,6 @@ unsigned long riscv_get_elf_hwcap(void)
return hwcap;
}
-static int check_unaligned_access(void *param)
-{
- int cpu = smp_processor_id();
- u64 start_cycles, end_cycles;
- u64 word_cycles;
- u64 byte_cycles;
- int ratio;
- unsigned long start_jiffies, now;
- struct page *page = param;
- void *dst;
- void *src;
- long speed = RISCV_HWPROBE_MISALIGNED_SLOW;
-
- if (check_unaligned_access_emulated(cpu))
- return 0;
-
- /* Make an unaligned destination buffer. */
- dst = (void *)((unsigned long)page_address(page) | 0x1);
- /* Unalign src as well, but differently (off by 1 + 2 = 3). */
- src = dst + (MISALIGNED_BUFFER_SIZE / 2);
- src += 2;
- word_cycles = -1ULL;
- /* Do a warmup. */
- __riscv_copy_words_unaligned(dst, src, MISALIGNED_COPY_SIZE);
- preempt_disable();
- start_jiffies = jiffies;
- while ((now = jiffies) == start_jiffies)
- cpu_relax();
-
- /*
- * For a fixed amount of time, repeatedly try the function, and take
- * the best time in cycles as the measurement.
- */
- while (time_before(jiffies, now + (1 << MISALIGNED_ACCESS_JIFFIES_LG2))) {
- start_cycles = get_cycles64();
- /* Ensure the CSR read can't reorder WRT to the copy. */
- mb();
- __riscv_copy_words_unaligned(dst, src, MISALIGNED_COPY_SIZE);
- /* Ensure the copy ends before the end time is snapped. */
- mb();
- end_cycles = get_cycles64();
- if ((end_cycles - start_cycles) < word_cycles)
- word_cycles = end_cycles - start_cycles;
- }
-
- byte_cycles = -1ULL;
- __riscv_copy_bytes_unaligned(dst, src, MISALIGNED_COPY_SIZE);
- start_jiffies = jiffies;
- while ((now = jiffies) == start_jiffies)
- cpu_relax();
-
- while (time_before(jiffies, now + (1 << MISALIGNED_ACCESS_JIFFIES_LG2))) {
- start_cycles = get_cycles64();
- mb();
- __riscv_copy_bytes_unaligned(dst, src, MISALIGNED_COPY_SIZE);
- mb();
- end_cycles = get_cycles64();
- if ((end_cycles - start_cycles) < byte_cycles)
- byte_cycles = end_cycles - start_cycles;
- }
-
- preempt_enable();
-
- /* Don't divide by zero. */
- if (!word_cycles || !byte_cycles) {
- pr_warn("cpu%d: rdtime lacks granularity needed to measure unaligned access speed\n",
- cpu);
-
- return 0;
- }
-
- if (word_cycles < byte_cycles)
- speed = RISCV_HWPROBE_MISALIGNED_FAST;
-
- ratio = div_u64((byte_cycles * 100), word_cycles);
- pr_info("cpu%d: Ratio of byte access time to unaligned word access is %d.%02d, unaligned accesses are %s\n",
- cpu,
- ratio / 100,
- ratio % 100,
- (speed == RISCV_HWPROBE_MISALIGNED_FAST) ? "fast" : "slow");
-
- per_cpu(misaligned_access_speed, cpu) = speed;
-
- /*
- * Set the value of fast_misaligned_access of a CPU. These operations
- * are atomic to avoid race conditions.
- */
- if (speed == RISCV_HWPROBE_MISALIGNED_FAST)
- cpumask_set_cpu(cpu, &fast_misaligned_access);
- else
- cpumask_clear_cpu(cpu, &fast_misaligned_access);
-
- return 0;
-}
-
-static void check_unaligned_access_nonboot_cpu(void *param)
-{
- unsigned int cpu = smp_processor_id();
- struct page **pages = param;
-
- if (smp_processor_id() != 0)
- check_unaligned_access(pages[cpu]);
-}
-
-DEFINE_STATIC_KEY_FALSE(fast_misaligned_access_speed_key);
-
-static void modify_unaligned_access_branches(cpumask_t *mask, int weight)
-{
- if (cpumask_weight(mask) == weight)
- static_branch_enable_cpuslocked(&fast_misaligned_access_speed_key);
- else
- static_branch_disable_cpuslocked(&fast_misaligned_access_speed_key);
-}
-
-static void set_unaligned_access_static_branches_except_cpu(int cpu)
-{
- /*
- * Same as set_unaligned_access_static_branches, except excludes the
- * given CPU from the result. When a CPU is hotplugged into an offline
- * state, this function is called before the CPU is set to offline in
- * the cpumask, and thus the CPU needs to be explicitly excluded.
- */
-
- cpumask_t fast_except_me;
-
- cpumask_and(&fast_except_me, &fast_misaligned_access, cpu_online_mask);
- cpumask_clear_cpu(cpu, &fast_except_me);
-
- modify_unaligned_access_branches(&fast_except_me, num_online_cpus() - 1);
-}
-
-static void set_unaligned_access_static_branches(void)
-{
- /*
- * This will be called after check_unaligned_access_all_cpus so the
- * result of unaligned access speed for all CPUs will be available.
- *
- * To avoid the number of online cpus changing between reading
- * cpu_online_mask and calling num_online_cpus, cpus_read_lock must be
- * held before calling this function.
- */
-
- cpumask_t fast_and_online;
-
- cpumask_and(&fast_and_online, &fast_misaligned_access, cpu_online_mask);
-
- modify_unaligned_access_branches(&fast_and_online, num_online_cpus());
-}
-
-static int lock_and_set_unaligned_access_static_branch(void)
-{
- cpus_read_lock();
- set_unaligned_access_static_branches();
- cpus_read_unlock();
-
- return 0;
-}
-
-arch_initcall_sync(lock_and_set_unaligned_access_static_branch);
-
-static int riscv_online_cpu(unsigned int cpu)
-{
- static struct page *buf;
-
- /* We are already set since the last check */
- if (per_cpu(misaligned_access_speed, cpu) != RISCV_HWPROBE_MISALIGNED_UNKNOWN)
- goto exit;
-
- buf = alloc_pages(GFP_KERNEL, MISALIGNED_BUFFER_ORDER);
- if (!buf) {
- pr_warn("Allocation failure, not measuring misaligned performance\n");
- return -ENOMEM;
- }
-
- check_unaligned_access(buf);
- __free_pages(buf, MISALIGNED_BUFFER_ORDER);
-
-exit:
- set_unaligned_access_static_branches();
-
- return 0;
-}
-
-static int riscv_offline_cpu(unsigned int cpu)
-{
- set_unaligned_access_static_branches_except_cpu(cpu);
-
- return 0;
-}
-
-/* Measure unaligned access on all CPUs present at boot in parallel. */
-static int check_unaligned_access_all_cpus(void)
-{
- unsigned int cpu;
- unsigned int cpu_count = num_possible_cpus();
- struct page **bufs = kzalloc(cpu_count * sizeof(struct page *),
- GFP_KERNEL);
-
- if (!bufs) {
- pr_warn("Allocation failure, not measuring misaligned performance\n");
- return 0;
- }
-
- /*
- * Allocate separate buffers for each CPU so there's no fighting over
- * cache lines.
- */
- for_each_cpu(cpu, cpu_online_mask) {
- bufs[cpu] = alloc_pages(GFP_KERNEL, MISALIGNED_BUFFER_ORDER);
- if (!bufs[cpu]) {
- pr_warn("Allocation failure, not measuring misaligned performance\n");
- goto out;
- }
- }
-
- /* Check everybody except 0, who stays behind to tend jiffies. */
- on_each_cpu(check_unaligned_access_nonboot_cpu, bufs, 1);
-
- /* Check core 0. */
- smp_call_on_cpu(0, check_unaligned_access, bufs[0], true);
-
- /*
- * Setup hotplug callbacks for any new CPUs that come online or go
- * offline.
- */
- cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "riscv:online",
- riscv_online_cpu, riscv_offline_cpu);
-
-out:
- unaligned_emulation_finish();
- for_each_cpu(cpu, cpu_online_mask) {
- if (bufs[cpu])
- __free_pages(bufs[cpu], MISALIGNED_BUFFER_ORDER);
- }
-
- kfree(bufs);
- return 0;
-}
-
-arch_initcall(check_unaligned_access_all_cpus);
-
void riscv_user_isa_enable(void)
{
if (riscv_cpu_has_extension_unlikely(smp_processor_id(), RISCV_ISA_EXT_ZICBOZ))
diff --git a/arch/riscv/kernel/elf_kexec.c b/arch/riscv/kernel/elf_kexec.c
index 5bd1ec3341fe..54260c16f991 100644
--- a/arch/riscv/kernel/elf_kexec.c
+++ b/arch/riscv/kernel/elf_kexec.c
@@ -117,6 +117,7 @@ static int elf_find_pbase(struct kimage *image, unsigned long kernel_len,
return ret;
}
+#ifdef CONFIG_CRASH_DUMP
static int get_nr_ram_ranges_callback(struct resource *res, void *arg)
{
unsigned int *nr_ranges = arg;
@@ -189,6 +190,7 @@ static char *setup_kdump_cmdline(struct kimage *image, char *cmdline,
cmdline_ptr[COMMAND_LINE_SIZE - 1] = '\0';
return cmdline_ptr;
}
+#endif
static void *elf_kexec_load(struct kimage *image, char *kernel_buf,
unsigned long kernel_len, char *initrd,
@@ -196,12 +198,11 @@ static void *elf_kexec_load(struct kimage *image, char *kernel_buf,
unsigned long cmdline_len)
{
int ret;
+ void *fdt;
unsigned long old_kernel_pbase = ULONG_MAX;
unsigned long new_kernel_pbase = 0UL;
unsigned long initrd_pbase = 0UL;
- unsigned long headers_sz;
unsigned long kernel_start;
- void *fdt, *headers;
struct elfhdr ehdr;
struct kexec_buf kbuf;
struct kexec_elf_info elf_info;
@@ -227,8 +228,11 @@ static void *elf_kexec_load(struct kimage *image, char *kernel_buf,
kbuf.buf_min = new_kernel_pbase + kernel_len;
kbuf.buf_max = ULONG_MAX;
+#ifdef CONFIG_CRASH_DUMP
/* Add elfcorehdr */
if (image->type == KEXEC_TYPE_CRASH) {
+ void *headers;
+ unsigned long headers_sz;
ret = prepare_elf_headers(&headers, &headers_sz);
if (ret) {
pr_err("Preparing elf core header failed\n");
@@ -264,6 +268,7 @@ static void *elf_kexec_load(struct kimage *image, char *kernel_buf,
}
cmdline = modified_cmdline;
}
+#endif
#ifdef CONFIG_ARCH_SUPPORTS_KEXEC_PURGATORY
/* Add purgatory to the image */
diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index 9d1a305d5508..68a24cf9481a 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -111,6 +111,7 @@ SYM_CODE_START(handle_exception)
1:
tail do_trap_unknown
SYM_CODE_END(handle_exception)
+ASM_NOKPROBE(handle_exception)
/*
* The ret_from_exception must be called with interrupt disabled. Here is the
@@ -184,6 +185,7 @@ SYM_CODE_START_NOALIGN(ret_from_exception)
sret
#endif
SYM_CODE_END(ret_from_exception)
+ASM_NOKPROBE(ret_from_exception)
#ifdef CONFIG_VMAP_STACK
SYM_CODE_START_LOCAL(handle_kernel_stack_overflow)
@@ -219,6 +221,7 @@ SYM_CODE_START_LOCAL(handle_kernel_stack_overflow)
move a0, sp
tail handle_bad_stack
SYM_CODE_END(handle_kernel_stack_overflow)
+ASM_NOKPROBE(handle_kernel_stack_overflow)
#endif
SYM_CODE_START(ret_from_fork)
diff --git a/arch/riscv/kernel/mcount.S b/arch/riscv/kernel/mcount.S
index d7ec69ac6910..3a42f6287909 100644
--- a/arch/riscv/kernel/mcount.S
+++ b/arch/riscv/kernel/mcount.S
@@ -50,8 +50,8 @@
SYM_TYPED_FUNC_START(ftrace_stub)
#ifdef CONFIG_DYNAMIC_FTRACE
- .global MCOUNT_NAME
- .set MCOUNT_NAME, ftrace_stub
+ .global _mcount
+ .set _mcount, ftrace_stub
#endif
ret
SYM_FUNC_END(ftrace_stub)
@@ -80,7 +80,7 @@ SYM_FUNC_END(return_to_handler)
#endif
#ifndef CONFIG_DYNAMIC_FTRACE
-SYM_FUNC_START(MCOUNT_NAME)
+SYM_FUNC_START(_mcount)
la t4, ftrace_stub
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
la t0, ftrace_graph_return
@@ -126,6 +126,6 @@ SYM_FUNC_START(MCOUNT_NAME)
jalr t5
RESTORE_ABI_STATE
ret
-SYM_FUNC_END(MCOUNT_NAME)
+SYM_FUNC_END(_mcount)
#endif
-EXPORT_SYMBOL(MCOUNT_NAME)
+EXPORT_SYMBOL(_mcount)
diff --git a/arch/riscv/kernel/patch.c b/arch/riscv/kernel/patch.c
index 37e87fdcf6a0..30e12b310cab 100644
--- a/arch/riscv/kernel/patch.c
+++ b/arch/riscv/kernel/patch.c
@@ -80,6 +80,8 @@ static int __patch_insn_set(void *addr, u8 c, size_t len)
*/
lockdep_assert_held(&text_mutex);
+ preempt_disable();
+
if (across_pages)
patch_map(addr + PAGE_SIZE, FIX_TEXT_POKE1);
@@ -92,6 +94,8 @@ static int __patch_insn_set(void *addr, u8 c, size_t len)
if (across_pages)
patch_unmap(FIX_TEXT_POKE1);
+ preempt_enable();
+
return 0;
}
NOKPROBE_SYMBOL(__patch_insn_set);
@@ -122,6 +126,8 @@ static int __patch_insn_write(void *addr, const void *insn, size_t len)
if (!riscv_patch_in_stop_machine)
lockdep_assert_held(&text_mutex);
+ preempt_disable();
+
if (across_pages)
patch_map(addr + PAGE_SIZE, FIX_TEXT_POKE1);
@@ -134,6 +140,8 @@ static int __patch_insn_write(void *addr, const void *insn, size_t len)
if (across_pages)
patch_unmap(FIX_TEXT_POKE1);
+ preempt_enable();
+
return ret;
}
NOKPROBE_SYMBOL(__patch_insn_write);
diff --git a/arch/riscv/kernel/pi/Makefile b/arch/riscv/kernel/pi/Makefile
index 07915dc9279e..b75f150b923d 100644
--- a/arch/riscv/kernel/pi/Makefile
+++ b/arch/riscv/kernel/pi/Makefile
@@ -9,6 +9,9 @@ KBUILD_CFLAGS := $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) -fpie \
-fno-asynchronous-unwind-tables -fno-unwind-tables \
$(call cc-option,-fno-addrsig)
+# Disable LTO
+KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_LTO), $(KBUILD_CFLAGS))
+
KBUILD_CFLAGS += -mcmodel=medany
CFLAGS_cmdline_early.o += -D__NO_FORTIFY
diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
index 92922dbd5b5c..e4bc61c4e58a 100644
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c
@@ -27,8 +27,6 @@
#include <asm/vector.h>
#include <asm/cpufeature.h>
-register unsigned long gp_in_global __asm__("gp");
-
#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_STACKPROTECTOR_PER_TASK)
#include <linux/stackprotector.h>
unsigned long __stack_chk_guard __read_mostly;
@@ -37,7 +35,7 @@ EXPORT_SYMBOL(__stack_chk_guard);
extern asmlinkage void ret_from_fork(void);
-void arch_cpu_idle(void)
+void noinstr arch_cpu_idle(void)
{
cpu_do_idle();
}
@@ -207,7 +205,6 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
if (unlikely(args->fn)) {
/* Kernel thread */
memset(childregs, 0, sizeof(struct pt_regs));
- childregs->gp = gp_in_global;
/* Supervisor/Machine, irqs on: */
childregs->status = SR_PP | SR_PIE;
diff --git a/arch/riscv/kernel/ptrace.c b/arch/riscv/kernel/ptrace.c
index e8515aa9d80b..92731ff8c79a 100644
--- a/arch/riscv/kernel/ptrace.c
+++ b/arch/riscv/kernel/ptrace.c
@@ -377,14 +377,14 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
return ret;
}
+#else
+static const struct user_regset_view compat_riscv_user_native_view = {};
#endif /* CONFIG_COMPAT */
const struct user_regset_view *task_user_regset_view(struct task_struct *task)
{
-#ifdef CONFIG_COMPAT
- if (test_tsk_thread_flag(task, TIF_32BIT))
+ if (is_compat_thread(&task->thread_info))
return &compat_riscv_user_native_view;
else
-#endif
return &riscv_user_native_view;
}
diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c
index 501e66debf69..5a2edd7f027e 100644
--- a/arch/riscv/kernel/signal.c
+++ b/arch/riscv/kernel/signal.c
@@ -119,6 +119,13 @@ static long __restore_v_state(struct pt_regs *regs, void __user *sc_vec)
struct __sc_riscv_v_state __user *state = sc_vec;
void __user *datap;
+ /*
+ * Mark the vstate as clean prior performing the actual copy,
+ * to avoid getting the vstate incorrectly clobbered by the
+ * discarded vector state.
+ */
+ riscv_v_vstate_set_restore(current, regs);
+
/* Copy everything of __sc_riscv_v_state except datap. */
err = __copy_from_user(&current->thread.vstate, &state->v_state,
offsetof(struct __riscv_v_ext_state, datap));
@@ -133,13 +140,7 @@ static long __restore_v_state(struct pt_regs *regs, void __user *sc_vec)
* Copy the whole vector content from user space datap. Use
* copy_from_user to prevent information leak.
*/
- err = copy_from_user(current->thread.vstate.datap, datap, riscv_v_vsize);
- if (unlikely(err))
- return err;
-
- riscv_v_vstate_set_restore(current, regs);
-
- return err;
+ return copy_from_user(current->thread.vstate.datap, datap, riscv_v_vsize);
}
#else
#define save_v_state(task, regs) (0)
diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c
index 519b6bd946e5..d41090fc3203 100644
--- a/arch/riscv/kernel/smpboot.c
+++ b/arch/riscv/kernel/smpboot.c
@@ -28,7 +28,6 @@
#include <asm/cpufeature.h>
#include <asm/cpu_ops.h>
-#include <asm/cpufeature.h>
#include <asm/irq.h>
#include <asm/mmu_context.h>
#include <asm/numa.h>
@@ -42,10 +41,6 @@
static DECLARE_COMPLETION(cpu_running);
-void __init smp_prepare_boot_cpu(void)
-{
-}
-
void __init smp_prepare_cpus(unsigned int max_cpus)
{
int cpuid;
diff --git a/arch/riscv/kernel/suspend.c b/arch/riscv/kernel/suspend.c
index 299795341e8a..8a327b485b90 100644
--- a/arch/riscv/kernel/suspend.c
+++ b/arch/riscv/kernel/suspend.c
@@ -132,4 +132,53 @@ static int __init sbi_system_suspend_init(void)
}
arch_initcall(sbi_system_suspend_init);
+
+static int sbi_suspend_finisher(unsigned long suspend_type,
+ unsigned long resume_addr,
+ unsigned long opaque)
+{
+ struct sbiret ret;
+
+ ret = sbi_ecall(SBI_EXT_HSM, SBI_EXT_HSM_HART_SUSPEND,
+ suspend_type, resume_addr, opaque, 0, 0, 0);
+
+ return (ret.error) ? sbi_err_map_linux_errno(ret.error) : 0;
+}
+
+int riscv_sbi_hart_suspend(u32 state)
+{
+ if (state & SBI_HSM_SUSP_NON_RET_BIT)
+ return cpu_suspend(state, sbi_suspend_finisher);
+ else
+ return sbi_suspend_finisher(state, 0, 0);
+}
+
+bool riscv_sbi_suspend_state_is_valid(u32 state)
+{
+ if (state > SBI_HSM_SUSPEND_RET_DEFAULT &&
+ state < SBI_HSM_SUSPEND_RET_PLATFORM)
+ return false;
+
+ if (state > SBI_HSM_SUSPEND_NON_RET_DEFAULT &&
+ state < SBI_HSM_SUSPEND_NON_RET_PLATFORM)
+ return false;
+
+ return true;
+}
+
+bool riscv_sbi_hsm_is_supported(void)
+{
+ /*
+ * The SBI HSM suspend function is only available when:
+ * 1) SBI version is 0.3 or higher
+ * 2) SBI HSM extension is available
+ */
+ if (sbi_spec_version < sbi_mk_version(0, 3) ||
+ !sbi_probe_extension(SBI_EXT_HSM)) {
+ pr_info("HSM suspend not available\n");
+ return false;
+ }
+
+ return true;
+}
#endif /* CONFIG_RISCV_SBI */
diff --git a/arch/riscv/kernel/sys_hwprobe.c b/arch/riscv/kernel/sys_hwprobe.c
index a7c56b41efd2..8cae41a502dd 100644
--- a/arch/riscv/kernel/sys_hwprobe.c
+++ b/arch/riscv/kernel/sys_hwprobe.c
@@ -147,6 +147,7 @@ static bool hwprobe_ext0_has(const struct cpumask *cpus, unsigned long ext)
return (pair.value & ext);
}
+#if defined(CONFIG_RISCV_PROBE_UNALIGNED_ACCESS)
static u64 hwprobe_misaligned(const struct cpumask *cpus)
{
int cpu;
@@ -169,6 +170,18 @@ static u64 hwprobe_misaligned(const struct cpumask *cpus)
return perf;
}
+#else
+static u64 hwprobe_misaligned(const struct cpumask *cpus)
+{
+ if (IS_ENABLED(CONFIG_RISCV_EFFICIENT_UNALIGNED_ACCESS))
+ return RISCV_HWPROBE_MISALIGNED_FAST;
+
+ if (IS_ENABLED(CONFIG_RISCV_EMULATED_UNALIGNED_ACCESS) && unaligned_ctl_available())
+ return RISCV_HWPROBE_MISALIGNED_EMULATED;
+
+ return RISCV_HWPROBE_MISALIGNED_SLOW;
+}
+#endif
static void hwprobe_one_pair(struct riscv_hwprobe *pair,
const struct cpumask *cpus)
diff --git a/arch/riscv/kernel/tests/Kconfig.debug b/arch/riscv/kernel/tests/Kconfig.debug
index 5dba64e8e977..78cea5d2c270 100644
--- a/arch/riscv/kernel/tests/Kconfig.debug
+++ b/arch/riscv/kernel/tests/Kconfig.debug
@@ -6,7 +6,7 @@ config AS_HAS_ULEB128
menuconfig RUNTIME_KERNEL_TESTING_MENU
bool "arch/riscv/kernel runtime Testing"
- def_bool y
+ default y
help
Enable riscv kernel runtime testing.
diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
index a1b9be3c4332..05a16b1f0aee 100644
--- a/arch/riscv/kernel/traps.c
+++ b/arch/riscv/kernel/traps.c
@@ -6,6 +6,7 @@
#include <linux/cpu.h>
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/randomize_kstack.h>
#include <linux/sched.h>
#include <linux/sched/debug.h>
#include <linux/sched/signal.h>
@@ -121,7 +122,7 @@ void do_trap(struct pt_regs *regs, int signo, int code, unsigned long addr)
print_vma_addr(KERN_CONT " in ", instruction_pointer(regs));
pr_cont("\n");
__show_regs(regs);
- dump_instr(KERN_EMERG, regs);
+ dump_instr(KERN_INFO, regs);
}
force_sig_fault(signo, code, (void __user *)addr);
@@ -310,7 +311,8 @@ asmlinkage __visible __trap_section void do_trap_break(struct pt_regs *regs)
}
}
-asmlinkage __visible __trap_section void do_trap_ecall_u(struct pt_regs *regs)
+asmlinkage __visible __trap_section __no_stack_protector
+void do_trap_ecall_u(struct pt_regs *regs)
{
if (user_mode(regs)) {
long syscall = regs->a7;
@@ -322,10 +324,23 @@ asmlinkage __visible __trap_section void do_trap_ecall_u(struct pt_regs *regs)
syscall = syscall_enter_from_user_mode(regs, syscall);
+ add_random_kstack_offset();
+
if (syscall >= 0 && syscall < NR_syscalls)
syscall_handler(regs, syscall);
else if (syscall != -1)
regs->a0 = -ENOSYS;
+ /*
+ * Ultimately, this value will get limited by KSTACK_OFFSET_MAX(),
+ * so the maximum stack offset is 1k bytes (10 bits).
+ *
+ * The actual entropy will be further reduced by the compiler when
+ * applying stack alignment constraints: 16-byte (i.e. 4-bit) aligned
+ * for RV32I or RV64I.
+ *
+ * The resulting 6 bits of entropy is seen in SP[9:4].
+ */
+ choose_random_kstack_offset(get_random_u16());
syscall_exit_to_user_mode(regs);
} else {
diff --git a/arch/riscv/kernel/traps_misaligned.c b/arch/riscv/kernel/traps_misaligned.c
index 8ded225e8c5b..2adb7c3e4dd5 100644
--- a/arch/riscv/kernel/traps_misaligned.c
+++ b/arch/riscv/kernel/traps_misaligned.c
@@ -413,7 +413,9 @@ int handle_misaligned_load(struct pt_regs *regs)
perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, addr);
+#ifdef CONFIG_RISCV_PROBE_UNALIGNED_ACCESS
*this_cpu_ptr(&misaligned_access_speed) = RISCV_HWPROBE_MISALIGNED_EMULATED;
+#endif
if (!unaligned_enabled)
return -1;
@@ -596,7 +598,7 @@ int handle_misaligned_store(struct pt_regs *regs)
return 0;
}
-bool check_unaligned_access_emulated(int cpu)
+static bool check_unaligned_access_emulated(int cpu)
{
long *mas_ptr = per_cpu_ptr(&misaligned_access_speed, cpu);
unsigned long tmp_var, tmp_val;
@@ -623,7 +625,7 @@ bool check_unaligned_access_emulated(int cpu)
return misaligned_emu_detected;
}
-void unaligned_emulation_finish(void)
+bool check_unaligned_access_emulated_all_cpus(void)
{
int cpu;
@@ -632,13 +634,12 @@ void unaligned_emulation_finish(void)
* accesses emulated since tasks requesting such control can run on any
* CPU.
*/
- for_each_present_cpu(cpu) {
- if (per_cpu(misaligned_access_speed, cpu) !=
- RISCV_HWPROBE_MISALIGNED_EMULATED) {
- return;
- }
- }
+ for_each_online_cpu(cpu)
+ if (!check_unaligned_access_emulated(cpu))
+ return false;
+
unaligned_ctl = true;
+ return true;
}
bool unaligned_ctl_available(void)
diff --git a/arch/riscv/kernel/unaligned_access_speed.c b/arch/riscv/kernel/unaligned_access_speed.c
new file mode 100644
index 000000000000..a9a6bcb02acf
--- /dev/null
+++ b/arch/riscv/kernel/unaligned_access_speed.c
@@ -0,0 +1,281 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2024 Rivos Inc.
+ */
+
+#include <linux/cpu.h>
+#include <linux/cpumask.h>
+#include <linux/jump_label.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/types.h>
+#include <asm/cpufeature.h>
+#include <asm/hwprobe.h>
+
+#include "copy-unaligned.h"
+
+#define MISALIGNED_ACCESS_JIFFIES_LG2 1
+#define MISALIGNED_BUFFER_SIZE 0x4000
+#define MISALIGNED_BUFFER_ORDER get_order(MISALIGNED_BUFFER_SIZE)
+#define MISALIGNED_COPY_SIZE ((MISALIGNED_BUFFER_SIZE / 2) - 0x80)
+
+DEFINE_PER_CPU(long, misaligned_access_speed);
+
+#ifdef CONFIG_RISCV_PROBE_UNALIGNED_ACCESS
+static cpumask_t fast_misaligned_access;
+static int check_unaligned_access(void *param)
+{
+ int cpu = smp_processor_id();
+ u64 start_cycles, end_cycles;
+ u64 word_cycles;
+ u64 byte_cycles;
+ int ratio;
+ unsigned long start_jiffies, now;
+ struct page *page = param;
+ void *dst;
+ void *src;
+ long speed = RISCV_HWPROBE_MISALIGNED_SLOW;
+
+ if (per_cpu(misaligned_access_speed, cpu) != RISCV_HWPROBE_MISALIGNED_UNKNOWN)
+ return 0;
+
+ /* Make an unaligned destination buffer. */
+ dst = (void *)((unsigned long)page_address(page) | 0x1);
+ /* Unalign src as well, but differently (off by 1 + 2 = 3). */
+ src = dst + (MISALIGNED_BUFFER_SIZE / 2);
+ src += 2;
+ word_cycles = -1ULL;
+ /* Do a warmup. */
+ __riscv_copy_words_unaligned(dst, src, MISALIGNED_COPY_SIZE);
+ preempt_disable();
+ start_jiffies = jiffies;
+ while ((now = jiffies) == start_jiffies)
+ cpu_relax();
+
+ /*
+ * For a fixed amount of time, repeatedly try the function, and take
+ * the best time in cycles as the measurement.
+ */
+ while (time_before(jiffies, now + (1 << MISALIGNED_ACCESS_JIFFIES_LG2))) {
+ start_cycles = get_cycles64();
+ /* Ensure the CSR read can't reorder WRT to the copy. */
+ mb();
+ __riscv_copy_words_unaligned(dst, src, MISALIGNED_COPY_SIZE);
+ /* Ensure the copy ends before the end time is snapped. */
+ mb();
+ end_cycles = get_cycles64();
+ if ((end_cycles - start_cycles) < word_cycles)
+ word_cycles = end_cycles - start_cycles;
+ }
+
+ byte_cycles = -1ULL;
+ __riscv_copy_bytes_unaligned(dst, src, MISALIGNED_COPY_SIZE);
+ start_jiffies = jiffies;
+ while ((now = jiffies) == start_jiffies)
+ cpu_relax();
+
+ while (time_before(jiffies, now + (1 << MISALIGNED_ACCESS_JIFFIES_LG2))) {
+ start_cycles = get_cycles64();
+ mb();
+ __riscv_copy_bytes_unaligned(dst, src, MISALIGNED_COPY_SIZE);
+ mb();
+ end_cycles = get_cycles64();
+ if ((end_cycles - start_cycles) < byte_cycles)
+ byte_cycles = end_cycles - start_cycles;
+ }
+
+ preempt_enable();
+
+ /* Don't divide by zero. */
+ if (!word_cycles || !byte_cycles) {
+ pr_warn("cpu%d: rdtime lacks granularity needed to measure unaligned access speed\n",
+ cpu);
+
+ return 0;
+ }
+
+ if (word_cycles < byte_cycles)
+ speed = RISCV_HWPROBE_MISALIGNED_FAST;
+
+ ratio = div_u64((byte_cycles * 100), word_cycles);
+ pr_info("cpu%d: Ratio of byte access time to unaligned word access is %d.%02d, unaligned accesses are %s\n",
+ cpu,
+ ratio / 100,
+ ratio % 100,
+ (speed == RISCV_HWPROBE_MISALIGNED_FAST) ? "fast" : "slow");
+
+ per_cpu(misaligned_access_speed, cpu) = speed;
+
+ /*
+ * Set the value of fast_misaligned_access of a CPU. These operations
+ * are atomic to avoid race conditions.
+ */
+ if (speed == RISCV_HWPROBE_MISALIGNED_FAST)
+ cpumask_set_cpu(cpu, &fast_misaligned_access);
+ else
+ cpumask_clear_cpu(cpu, &fast_misaligned_access);
+
+ return 0;
+}
+
+static void check_unaligned_access_nonboot_cpu(void *param)
+{
+ unsigned int cpu = smp_processor_id();
+ struct page **pages = param;
+
+ if (smp_processor_id() != 0)
+ check_unaligned_access(pages[cpu]);
+}
+
+DEFINE_STATIC_KEY_FALSE(fast_unaligned_access_speed_key);
+
+static void modify_unaligned_access_branches(cpumask_t *mask, int weight)
+{
+ if (cpumask_weight(mask) == weight)
+ static_branch_enable_cpuslocked(&fast_unaligned_access_speed_key);
+ else
+ static_branch_disable_cpuslocked(&fast_unaligned_access_speed_key);
+}
+
+static void set_unaligned_access_static_branches_except_cpu(int cpu)
+{
+ /*
+ * Same as set_unaligned_access_static_branches, except excludes the
+ * given CPU from the result. When a CPU is hotplugged into an offline
+ * state, this function is called before the CPU is set to offline in
+ * the cpumask, and thus the CPU needs to be explicitly excluded.
+ */
+
+ cpumask_t fast_except_me;
+
+ cpumask_and(&fast_except_me, &fast_misaligned_access, cpu_online_mask);
+ cpumask_clear_cpu(cpu, &fast_except_me);
+
+ modify_unaligned_access_branches(&fast_except_me, num_online_cpus() - 1);
+}
+
+static void set_unaligned_access_static_branches(void)
+{
+ /*
+ * This will be called after check_unaligned_access_all_cpus so the
+ * result of unaligned access speed for all CPUs will be available.
+ *
+ * To avoid the number of online cpus changing between reading
+ * cpu_online_mask and calling num_online_cpus, cpus_read_lock must be
+ * held before calling this function.
+ */
+
+ cpumask_t fast_and_online;
+
+ cpumask_and(&fast_and_online, &fast_misaligned_access, cpu_online_mask);
+
+ modify_unaligned_access_branches(&fast_and_online, num_online_cpus());
+}
+
+static int lock_and_set_unaligned_access_static_branch(void)
+{
+ cpus_read_lock();
+ set_unaligned_access_static_branches();
+ cpus_read_unlock();
+
+ return 0;
+}
+
+arch_initcall_sync(lock_and_set_unaligned_access_static_branch);
+
+static int riscv_online_cpu(unsigned int cpu)
+{
+ static struct page *buf;
+
+ /* We are already set since the last check */
+ if (per_cpu(misaligned_access_speed, cpu) != RISCV_HWPROBE_MISALIGNED_UNKNOWN)
+ goto exit;
+
+ buf = alloc_pages(GFP_KERNEL, MISALIGNED_BUFFER_ORDER);
+ if (!buf) {
+ pr_warn("Allocation failure, not measuring misaligned performance\n");
+ return -ENOMEM;
+ }
+
+ check_unaligned_access(buf);
+ __free_pages(buf, MISALIGNED_BUFFER_ORDER);
+
+exit:
+ set_unaligned_access_static_branches();
+
+ return 0;
+}
+
+static int riscv_offline_cpu(unsigned int cpu)
+{
+ set_unaligned_access_static_branches_except_cpu(cpu);
+
+ return 0;
+}
+
+/* Measure unaligned access speed on all CPUs present at boot in parallel. */
+static int check_unaligned_access_speed_all_cpus(void)
+{
+ unsigned int cpu;
+ unsigned int cpu_count = num_possible_cpus();
+ struct page **bufs = kcalloc(cpu_count, sizeof(*bufs), GFP_KERNEL);
+
+ if (!bufs) {
+ pr_warn("Allocation failure, not measuring misaligned performance\n");
+ return 0;
+ }
+
+ /*
+ * Allocate separate buffers for each CPU so there's no fighting over
+ * cache lines.
+ */
+ for_each_cpu(cpu, cpu_online_mask) {
+ bufs[cpu] = alloc_pages(GFP_KERNEL, MISALIGNED_BUFFER_ORDER);
+ if (!bufs[cpu]) {
+ pr_warn("Allocation failure, not measuring misaligned performance\n");
+ goto out;
+ }
+ }
+
+ /* Check everybody except 0, who stays behind to tend jiffies. */
+ on_each_cpu(check_unaligned_access_nonboot_cpu, bufs, 1);
+
+ /* Check core 0. */
+ smp_call_on_cpu(0, check_unaligned_access, bufs[0], true);
+
+ /*
+ * Setup hotplug callbacks for any new CPUs that come online or go
+ * offline.
+ */
+ cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "riscv:online",
+ riscv_online_cpu, riscv_offline_cpu);
+
+out:
+ for_each_cpu(cpu, cpu_online_mask) {
+ if (bufs[cpu])
+ __free_pages(bufs[cpu], MISALIGNED_BUFFER_ORDER);
+ }
+
+ kfree(bufs);
+ return 0;
+}
+
+static int check_unaligned_access_all_cpus(void)
+{
+ bool all_cpus_emulated = check_unaligned_access_emulated_all_cpus();
+
+ if (!all_cpus_emulated)
+ return check_unaligned_access_speed_all_cpus();
+
+ return 0;
+}
+#else /* CONFIG_RISCV_PROBE_UNALIGNED_ACCESS */
+static int check_unaligned_access_all_cpus(void)
+{
+ check_unaligned_access_emulated_all_cpus();
+
+ return 0;
+}
+#endif
+
+arch_initcall(check_unaligned_access_all_cpus);
diff --git a/arch/riscv/kernel/vdso.c b/arch/riscv/kernel/vdso.c
index 2cf76218a5bd..98315b98256d 100644
--- a/arch/riscv/kernel/vdso.c
+++ b/arch/riscv/kernel/vdso.c
@@ -30,14 +30,8 @@ enum rv_vdso_map {
#define VVAR_SIZE (VVAR_NR_PAGES << PAGE_SHIFT)
-/*
- * The vDSO data page.
- */
-static union {
- struct vdso_data data;
- u8 page[PAGE_SIZE];
-} vdso_data_store __page_aligned_data;
-struct vdso_data *vdso_data = &vdso_data_store.data;
+static union vdso_data_store vdso_data_store __page_aligned_data;
+struct vdso_data *vdso_data = vdso_data_store.data;
struct __vdso_info {
const char *name;
diff --git a/arch/riscv/kernel/vdso/Makefile b/arch/riscv/kernel/vdso/Makefile
index 9b517fe1b8a8..272c431ac5b9 100644
--- a/arch/riscv/kernel/vdso/Makefile
+++ b/arch/riscv/kernel/vdso/Makefile
@@ -37,6 +37,7 @@ endif
# Disable -pg to prevent insert call site
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
diff --git a/arch/riscv/kernel/crash_core.c b/arch/riscv/kernel/vmcore_info.c
index 8706736fd4e2..6d7a22522d63 100644
--- a/arch/riscv/kernel/crash_core.c
+++ b/arch/riscv/kernel/vmcore_info.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
-#include <linux/crash_core.h>
+#include <linux/vmcore_info.h>
#include <linux/pagemap.h>
void arch_crash_save_vmcoreinfo(void)
@@ -8,7 +8,6 @@ void arch_crash_save_vmcoreinfo(void)
VMCOREINFO_NUMBER(phys_ram_base);
vmcoreinfo_append_str("NUMBER(PAGE_OFFSET)=0x%lx\n", PAGE_OFFSET);
- vmcoreinfo_append_str("NUMBER(VMALLOC_START)=0x%lx\n", VMALLOC_START);
vmcoreinfo_append_str("NUMBER(VMALLOC_END)=0x%lx\n", VMALLOC_END);
#ifdef CONFIG_MMU
VMCOREINFO_NUMBER(VA_BITS);
diff --git a/arch/riscv/kvm/Kconfig b/arch/riscv/kvm/Kconfig
index d490db943858..26d1727f0550 100644
--- a/arch/riscv/kvm/Kconfig
+++ b/arch/riscv/kvm/Kconfig
@@ -24,6 +24,7 @@ config KVM
select HAVE_KVM_IRQ_ROUTING
select HAVE_KVM_MSI
select HAVE_KVM_VCPU_ASYNC_IOCTL
+ select HAVE_KVM_READONLY_MEM
select KVM_COMMON
select KVM_GENERIC_DIRTYLOG_READ_PROTECT
select KVM_GENERIC_HARDWARE_ENABLING
diff --git a/arch/riscv/kvm/aia_aplic.c b/arch/riscv/kvm/aia_aplic.c
index 39e72aa016a4..b467ba5ed910 100644
--- a/arch/riscv/kvm/aia_aplic.c
+++ b/arch/riscv/kvm/aia_aplic.c
@@ -137,11 +137,21 @@ static void aplic_write_pending(struct aplic *aplic, u32 irq, bool pending)
raw_spin_lock_irqsave(&irqd->lock, flags);
sm = irqd->sourcecfg & APLIC_SOURCECFG_SM_MASK;
- if (!pending &&
- ((sm == APLIC_SOURCECFG_SM_LEVEL_HIGH) ||
- (sm == APLIC_SOURCECFG_SM_LEVEL_LOW)))
+ if (sm == APLIC_SOURCECFG_SM_INACTIVE)
goto skip_write_pending;
+ if (sm == APLIC_SOURCECFG_SM_LEVEL_HIGH ||
+ sm == APLIC_SOURCECFG_SM_LEVEL_LOW) {
+ if (!pending)
+ goto skip_write_pending;
+ if ((irqd->state & APLIC_IRQ_STATE_INPUT) &&
+ sm == APLIC_SOURCECFG_SM_LEVEL_LOW)
+ goto skip_write_pending;
+ if (!(irqd->state & APLIC_IRQ_STATE_INPUT) &&
+ sm == APLIC_SOURCECFG_SM_LEVEL_HIGH)
+ goto skip_write_pending;
+ }
+
if (pending)
irqd->state |= APLIC_IRQ_STATE_PENDING;
else
@@ -187,16 +197,31 @@ static void aplic_write_enabled(struct aplic *aplic, u32 irq, bool enabled)
static bool aplic_read_input(struct aplic *aplic, u32 irq)
{
- bool ret;
- unsigned long flags;
+ u32 sourcecfg, sm, raw_input, irq_inverted;
struct aplic_irq *irqd;
+ unsigned long flags;
+ bool ret = false;
if (!irq || aplic->nr_irqs <= irq)
return false;
irqd = &aplic->irqs[irq];
raw_spin_lock_irqsave(&irqd->lock, flags);
- ret = (irqd->state & APLIC_IRQ_STATE_INPUT) ? true : false;
+
+ sourcecfg = irqd->sourcecfg;
+ if (sourcecfg & APLIC_SOURCECFG_D)
+ goto skip;
+
+ sm = sourcecfg & APLIC_SOURCECFG_SM_MASK;
+ if (sm == APLIC_SOURCECFG_SM_INACTIVE)
+ goto skip;
+
+ raw_input = (irqd->state & APLIC_IRQ_STATE_INPUT) ? 1 : 0;
+ irq_inverted = (sm == APLIC_SOURCECFG_SM_LEVEL_LOW ||
+ sm == APLIC_SOURCECFG_SM_EDGE_FALL) ? 1 : 0;
+ ret = !!(raw_input ^ irq_inverted);
+
+skip:
raw_spin_unlock_irqrestore(&irqd->lock, flags);
return ret;
diff --git a/arch/riscv/kvm/vcpu_insn.c b/arch/riscv/kvm/vcpu_insn.c
index 7a6abed41bc1..ee7215f4071f 100644
--- a/arch/riscv/kvm/vcpu_insn.c
+++ b/arch/riscv/kvm/vcpu_insn.c
@@ -7,6 +7,8 @@
#include <linux/bitops.h>
#include <linux/kvm_host.h>
+#include <asm/cpufeature.h>
+
#define INSN_OPCODE_MASK 0x007c
#define INSN_OPCODE_SHIFT 2
#define INSN_OPCODE_SYSTEM 28
@@ -213,9 +215,20 @@ struct csr_func {
unsigned long wr_mask);
};
+static int seed_csr_rmw(struct kvm_vcpu *vcpu, unsigned int csr_num,
+ unsigned long *val, unsigned long new_val,
+ unsigned long wr_mask)
+{
+ if (!riscv_isa_extension_available(vcpu->arch.isa, ZKR))
+ return KVM_INSN_ILLEGAL_TRAP;
+
+ return KVM_INSN_EXIT_TO_USER_SPACE;
+}
+
static const struct csr_func csr_funcs[] = {
KVM_RISCV_VCPU_AIA_CSR_FUNCS
KVM_RISCV_VCPU_HPMCOUNTER_CSR_FUNCS
+ { .base = CSR_SEED, .count = 1, .func = seed_csr_rmw },
};
/**
diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c
index 5f7355e96008..994adc26db4b 100644
--- a/arch/riscv/kvm/vcpu_onereg.c
+++ b/arch/riscv/kvm/vcpu_onereg.c
@@ -40,6 +40,7 @@ static const unsigned long kvm_isa_ext_arr[] = {
KVM_ISA_EXT_ARR(SVINVAL),
KVM_ISA_EXT_ARR(SVNAPOT),
KVM_ISA_EXT_ARR(SVPBMT),
+ KVM_ISA_EXT_ARR(ZACAS),
KVM_ISA_EXT_ARR(ZBA),
KVM_ISA_EXT_ARR(ZBB),
KVM_ISA_EXT_ARR(ZBC),
@@ -66,6 +67,7 @@ static const unsigned long kvm_isa_ext_arr[] = {
KVM_ISA_EXT_ARR(ZKSED),
KVM_ISA_EXT_ARR(ZKSH),
KVM_ISA_EXT_ARR(ZKT),
+ KVM_ISA_EXT_ARR(ZTSO),
KVM_ISA_EXT_ARR(ZVBB),
KVM_ISA_EXT_ARR(ZVBC),
KVM_ISA_EXT_ARR(ZVFH),
@@ -117,6 +119,7 @@ static bool kvm_riscv_vcpu_isa_disable_allowed(unsigned long ext)
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_ZBA:
case KVM_RISCV_ISA_EXT_ZBB:
case KVM_RISCV_ISA_EXT_ZBC:
@@ -141,6 +144,7 @@ static bool kvm_riscv_vcpu_isa_disable_allowed(unsigned long ext)
case KVM_RISCV_ISA_EXT_ZKSED:
case KVM_RISCV_ISA_EXT_ZKSH:
case KVM_RISCV_ISA_EXT_ZKT:
+ case KVM_RISCV_ISA_EXT_ZTSO:
case KVM_RISCV_ISA_EXT_ZVBB:
case KVM_RISCV_ISA_EXT_ZVBC:
case KVM_RISCV_ISA_EXT_ZVFH:
@@ -982,7 +986,7 @@ static int copy_isa_ext_reg_indices(const struct kvm_vcpu *vcpu,
static inline unsigned long num_isa_ext_regs(const struct kvm_vcpu *vcpu)
{
- return copy_isa_ext_reg_indices(vcpu, NULL);;
+ return copy_isa_ext_reg_indices(vcpu, NULL);
}
static int copy_sbi_ext_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
diff --git a/arch/riscv/lib/csum.c b/arch/riscv/lib/csum.c
index 74af3ab520b6..7fb12c59e571 100644
--- a/arch/riscv/lib/csum.c
+++ b/arch/riscv/lib/csum.c
@@ -3,7 +3,7 @@
* Checksum library
*
* Influenced by arch/arm64/lib/csum.c
- * Copyright (C) 2023 Rivos Inc.
+ * Copyright (C) 2023-2024 Rivos Inc.
*/
#include <linux/bitops.h>
#include <linux/compiler.h>
@@ -318,10 +318,7 @@ unsigned int do_csum(const unsigned char *buff, int len)
* branches. The largest chunk of overlap was delegated into the
* do_csum_common function.
*/
- if (static_branch_likely(&fast_misaligned_access_speed_key))
- return do_csum_no_alignment(buff, len);
-
- if (((unsigned long)buff & OFFSET_MASK) == 0)
+ if (has_fast_unaligned_accesses() || (((unsigned long)buff & OFFSET_MASK) == 0))
return do_csum_no_alignment(buff, len);
return do_csum_with_alignment(buff, len);
diff --git a/arch/riscv/lib/uaccess_vector.S b/arch/riscv/lib/uaccess_vector.S
index 51ab5588e9ff..7c45f26de4f7 100644
--- a/arch/riscv/lib/uaccess_vector.S
+++ b/arch/riscv/lib/uaccess_vector.S
@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <linux/linkage.h>
-#include <asm-generic/export.h>
#include <asm/asm.h>
#include <asm/asm-extable.h>
#include <asm/csr.h>
diff --git a/arch/riscv/mm/cacheflush.c b/arch/riscv/mm/cacheflush.c
index 55a34f2020a8..bc61ee5975e4 100644
--- a/arch/riscv/mm/cacheflush.c
+++ b/arch/riscv/mm/cacheflush.c
@@ -82,12 +82,12 @@ void flush_icache_mm(struct mm_struct *mm, bool local)
#endif /* CONFIG_SMP */
#ifdef CONFIG_MMU
-void flush_icache_pte(pte_t pte)
+void flush_icache_pte(struct mm_struct *mm, pte_t pte)
{
struct folio *folio = page_folio(pte_page(pte));
if (!test_bit(PG_dcache_clean, &folio->flags)) {
- flush_icache_all();
+ flush_icache_mm(mm, false);
set_bit(PG_dcache_clean, &folio->flags);
}
}
diff --git a/arch/riscv/mm/context.c b/arch/riscv/mm/context.c
index 217fd4de6134..ba8eb3944687 100644
--- a/arch/riscv/mm/context.c
+++ b/arch/riscv/mm/context.c
@@ -323,6 +323,8 @@ void switch_mm(struct mm_struct *prev, struct mm_struct *next,
if (unlikely(prev == next))
return;
+ membarrier_arch_switch_mm(prev, next, task);
+
/*
* Mark the current MM context as inactive, and the next as
* active. This is at least used by the icache flushing
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index fa34cf55037b..fe8e159394d8 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -29,7 +29,6 @@
#include <asm/io.h>
#include <asm/numa.h>
#include <asm/pgtable.h>
-#include <asm/ptdump.h>
#include <asm/sections.h>
#include <asm/soc.h>
#include <asm/tlbflush.h>
@@ -723,8 +722,6 @@ void mark_rodata_ro(void)
if (IS_ENABLED(CONFIG_64BIT))
set_kernel_memory(lm_alias(__start_rodata), lm_alias(_data),
set_memory_ro);
-
- debug_checkwx();
}
#else
static __init pgprot_t pgprot_from_va(uintptr_t va)
@@ -767,6 +764,11 @@ static int __init print_no5lvl(char *p)
}
early_param("no5lvl", print_no5lvl);
+static void __init set_mmap_rnd_bits_max(void)
+{
+ mmap_rnd_bits_max = MMAP_VA_BITS - PAGE_SHIFT - 3;
+}
+
/*
* There is a simple way to determine if 4-level is supported by the
* underlying hardware: establish 1:1 mapping in 4-level page table mode
@@ -1081,6 +1083,7 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
#if defined(CONFIG_64BIT) && !defined(CONFIG_XIP_KERNEL)
set_satp_mode(dtb_pa);
+ set_mmap_rnd_bits_max();
#endif
/*
@@ -1358,7 +1361,7 @@ static void __init arch_reserve_crashkernel(void)
bool high = false;
int ret;
- if (!IS_ENABLED(CONFIG_KEXEC_CORE))
+ if (!IS_ENABLED(CONFIG_CRASH_RESERVE))
return;
ret = parse_crashkernel(cmdline, memblock_phys_mem_size(),
diff --git a/arch/riscv/mm/pgtable.c b/arch/riscv/mm/pgtable.c
index ef887efcb679..533ec9055fa0 100644
--- a/arch/riscv/mm/pgtable.c
+++ b/arch/riscv/mm/pgtable.c
@@ -10,7 +10,7 @@ int ptep_set_access_flags(struct vm_area_struct *vma,
pte_t entry, int dirty)
{
if (!pte_same(ptep_get(ptep), entry))
- __set_pte_at(ptep, entry);
+ __set_pte_at(vma->vm_mm, ptep, entry);
/*
* update_mmu_cache will unconditionally execute, handling both
* the case that the PTE changed and the spurious fault case.
diff --git a/arch/riscv/mm/ptdump.c b/arch/riscv/mm/ptdump.c
index 657c27bc07a7..1289cc6d3700 100644
--- a/arch/riscv/mm/ptdump.c
+++ b/arch/riscv/mm/ptdump.c
@@ -9,7 +9,6 @@
#include <linux/seq_file.h>
#include <linux/ptdump.h>
-#include <asm/ptdump.h>
#include <linux/pgtable.h>
#include <asm/kasan.h>
@@ -336,7 +335,7 @@ static void ptdump_walk(struct seq_file *s, struct ptd_mm_info *pinfo)
ptdump_walk_pgd(&st.ptdump, pinfo->mm, NULL);
}
-void ptdump_check_wx(void)
+bool ptdump_check_wx(void)
{
struct pg_state st = {
.seq = NULL,
@@ -357,11 +356,16 @@ void ptdump_check_wx(void)
ptdump_walk_pgd(&st.ptdump, &init_mm, NULL);
- if (st.wx_pages)
+ if (st.wx_pages) {
pr_warn("Checked W+X mappings: failed, %lu W+X pages found\n",
st.wx_pages);
- else
+
+ return false;
+ } else {
pr_info("Checked W+X mappings: passed, no W+X pages found\n");
+
+ return true;
+ }
}
static int ptdump_show(struct seq_file *m, void *v)
diff --git a/arch/riscv/mm/tlbflush.c b/arch/riscv/mm/tlbflush.c
index 893566e004b7..07d743f87b3f 100644
--- a/arch/riscv/mm/tlbflush.c
+++ b/arch/riscv/mm/tlbflush.c
@@ -99,7 +99,7 @@ static void __ipi_flush_tlb_range_asid(void *info)
local_flush_tlb_range_asid(d->start, d->size, d->stride, d->asid);
}
-static void __flush_tlb_range(struct cpumask *cmask, unsigned long asid,
+static void __flush_tlb_range(const struct cpumask *cmask, unsigned long asid,
unsigned long start, unsigned long size,
unsigned long stride)
{
@@ -200,7 +200,7 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
void flush_tlb_kernel_range(unsigned long start, unsigned long end)
{
- __flush_tlb_range((struct cpumask *)cpu_online_mask, FLUSH_TLB_NO_ASID,
+ __flush_tlb_range(cpu_online_mask, FLUSH_TLB_NO_ASID,
start, end - start, PAGE_SIZE);
}
diff --git a/arch/riscv/net/bpf_jit.h b/arch/riscv/net/bpf_jit.h
index a5ce1ab76ece..f4b6b3b9edda 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 rvzbb_enabled(void)
+{
+ return IS_ENABLED(CONFIG_RISCV_ISA_ZBB) && riscv_has_extension_likely(RISCV_ISA_EXT_ZBB);
+}
+
enum {
RV_REG_ZERO = 0, /* The constant value 0 */
RV_REG_RA = 1, /* Return address */
@@ -730,6 +735,33 @@ static inline u16 rvc_swsp(u32 imm8, u8 rs2)
return rv_css_insn(0x6, imm, rs2, 0x2);
}
+/* RVZBB instrutions. */
+static inline u32 rvzbb_sextb(u8 rd, u8 rs1)
+{
+ return rv_i_insn(0x604, rs1, 1, rd, 0x13);
+}
+
+static inline u32 rvzbb_sexth(u8 rd, u8 rs1)
+{
+ return rv_i_insn(0x605, rs1, 1, rd, 0x13);
+}
+
+static inline u32 rvzbb_zexth(u8 rd, u8 rs)
+{
+ if (IS_ENABLED(CONFIG_64BIT))
+ return rv_i_insn(0x80, rs, 4, rd, 0x3b);
+
+ return rv_i_insn(0x80, rs, 4, rd, 0x33);
+}
+
+static inline u32 rvzbb_rev8(u8 rd, u8 rs)
+{
+ if (IS_ENABLED(CONFIG_64BIT))
+ return rv_i_insn(0x6b8, rs, 5, rd, 0x13);
+
+ return rv_i_insn(0x698, rs, 5, rd, 0x13);
+}
+
/*
* RV64-only instructions.
*
@@ -1087,9 +1119,111 @@ static inline void emit_subw(u8 rd, u8 rs1, u8 rs2, struct rv_jit_context *ctx)
emit(rv_subw(rd, rs1, rs2), ctx);
}
+static inline void emit_sextb(u8 rd, u8 rs, struct rv_jit_context *ctx)
+{
+ if (rvzbb_enabled()) {
+ emit(rvzbb_sextb(rd, rs), ctx);
+ return;
+ }
+
+ emit_slli(rd, rs, 56, ctx);
+ emit_srai(rd, rd, 56, ctx);
+}
+
+static inline void emit_sexth(u8 rd, u8 rs, struct rv_jit_context *ctx)
+{
+ if (rvzbb_enabled()) {
+ emit(rvzbb_sexth(rd, rs), ctx);
+ return;
+ }
+
+ emit_slli(rd, rs, 48, ctx);
+ emit_srai(rd, rd, 48, ctx);
+}
+
+static inline void emit_sextw(u8 rd, u8 rs, struct rv_jit_context *ctx)
+{
+ emit_addiw(rd, rs, 0, ctx);
+}
+
+static inline void emit_zexth(u8 rd, u8 rs, struct rv_jit_context *ctx)
+{
+ if (rvzbb_enabled()) {
+ emit(rvzbb_zexth(rd, rs), ctx);
+ return;
+ }
+
+ emit_slli(rd, rs, 48, ctx);
+ emit_srli(rd, rd, 48, ctx);
+}
+
+static inline void emit_zextw(u8 rd, u8 rs, struct rv_jit_context *ctx)
+{
+ emit_slli(rd, rs, 32, ctx);
+ emit_srli(rd, rd, 32, ctx);
+}
+
+static inline void emit_bswap(u8 rd, s32 imm, struct rv_jit_context *ctx)
+{
+ if (rvzbb_enabled()) {
+ int bits = 64 - imm;
+
+ emit(rvzbb_rev8(rd, rd), ctx);
+ if (bits)
+ emit_srli(rd, rd, bits, ctx);
+ return;
+ }
+
+ emit_li(RV_REG_T2, 0, ctx);
+
+ emit_andi(RV_REG_T1, rd, 0xff, ctx);
+ emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx);
+ emit_slli(RV_REG_T2, RV_REG_T2, 8, ctx);
+ emit_srli(rd, rd, 8, ctx);
+ if (imm == 16)
+ goto out_be;
+
+ emit_andi(RV_REG_T1, rd, 0xff, ctx);
+ emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx);
+ emit_slli(RV_REG_T2, RV_REG_T2, 8, ctx);
+ emit_srli(rd, rd, 8, ctx);
+
+ emit_andi(RV_REG_T1, rd, 0xff, ctx);
+ emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx);
+ emit_slli(RV_REG_T2, RV_REG_T2, 8, ctx);
+ emit_srli(rd, rd, 8, ctx);
+ if (imm == 32)
+ goto out_be;
+
+ emit_andi(RV_REG_T1, rd, 0xff, ctx);
+ emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx);
+ emit_slli(RV_REG_T2, RV_REG_T2, 8, ctx);
+ emit_srli(rd, rd, 8, ctx);
+
+ emit_andi(RV_REG_T1, rd, 0xff, ctx);
+ emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx);
+ emit_slli(RV_REG_T2, RV_REG_T2, 8, ctx);
+ emit_srli(rd, rd, 8, ctx);
+
+ emit_andi(RV_REG_T1, rd, 0xff, ctx);
+ emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx);
+ emit_slli(RV_REG_T2, RV_REG_T2, 8, ctx);
+ emit_srli(rd, rd, 8, ctx);
+
+ emit_andi(RV_REG_T1, rd, 0xff, ctx);
+ emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx);
+ emit_slli(RV_REG_T2, RV_REG_T2, 8, ctx);
+ emit_srli(rd, rd, 8, ctx);
+out_be:
+ emit_andi(RV_REG_T1, rd, 0xff, ctx);
+ emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx);
+
+ emit_mv(rd, RV_REG_T2, ctx);
+}
+
#endif /* __riscv_xlen == 64 */
-void bpf_jit_build_prologue(struct rv_jit_context *ctx);
+void bpf_jit_build_prologue(struct rv_jit_context *ctx, bool is_subprog);
void bpf_jit_build_epilogue(struct rv_jit_context *ctx);
int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
diff --git a/arch/riscv/net/bpf_jit_comp32.c b/arch/riscv/net/bpf_jit_comp32.c
index 529a83b85c1c..f5ba73bb153d 100644
--- a/arch/riscv/net/bpf_jit_comp32.c
+++ b/arch/riscv/net/bpf_jit_comp32.c
@@ -1301,7 +1301,7 @@ notsupported:
return 0;
}
-void bpf_jit_build_prologue(struct rv_jit_context *ctx)
+void bpf_jit_build_prologue(struct rv_jit_context *ctx, bool is_subprog)
{
const s8 *fp = bpf2rv32[BPF_REG_FP];
const s8 *r1 = bpf2rv32[BPF_REG_1];
diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c
index 719a97e7edb2..1adf2f39ce59 100644
--- a/arch/riscv/net/bpf_jit_comp64.c
+++ b/arch/riscv/net/bpf_jit_comp64.c
@@ -11,6 +11,7 @@
#include <linux/memory.h>
#include <linux/stop_machine.h>
#include <asm/patch.h>
+#include <asm/cfi.h>
#include "bpf_jit.h"
#define RV_FENTRY_NINSNS 2
@@ -141,6 +142,19 @@ static bool in_auipc_jalr_range(s64 val)
val < ((1L << 31) - (1L << 11));
}
+/* Modify rd pointer to alternate reg to avoid corrupting original reg */
+static void emit_sextw_alt(u8 *rd, u8 ra, struct rv_jit_context *ctx)
+{
+ emit_sextw(ra, *rd, ctx);
+ *rd = ra;
+}
+
+static void emit_zextw_alt(u8 *rd, u8 ra, struct rv_jit_context *ctx)
+{
+ emit_zextw(ra, *rd, ctx);
+ *rd = ra;
+}
+
/* Emit fixed-length instructions for address */
static int emit_addr(u8 rd, u64 addr, bool extra_pass, struct rv_jit_context *ctx)
{
@@ -326,12 +340,6 @@ static void emit_branch(u8 cond, u8 rd, u8 rs, int rvoff,
emit(rv_jalr(RV_REG_ZERO, RV_REG_T1, lower), ctx);
}
-static void emit_zext_32(u8 reg, struct rv_jit_context *ctx)
-{
- emit_slli(reg, reg, 32, ctx);
- emit_srli(reg, reg, 32, ctx);
-}
-
static int emit_bpf_tail_call(int insn, struct rv_jit_context *ctx)
{
int tc_ninsn, off, start_insn = ctx->ninsns;
@@ -346,7 +354,7 @@ static int emit_bpf_tail_call(int insn, struct rv_jit_context *ctx)
*/
tc_ninsn = insn ? ctx->offset[insn] - ctx->offset[insn - 1] :
ctx->offset[0];
- emit_zext_32(RV_REG_A2, ctx);
+ emit_zextw(RV_REG_A2, RV_REG_A2, ctx);
off = offsetof(struct bpf_array, map.max_entries);
if (is_12b_check(off, insn))
@@ -405,38 +413,6 @@ static void init_regs(u8 *rd, u8 *rs, const struct bpf_insn *insn,
*rs = bpf_to_rv_reg(insn->src_reg, ctx);
}
-static void emit_zext_32_rd_rs(u8 *rd, u8 *rs, struct rv_jit_context *ctx)
-{
- emit_mv(RV_REG_T2, *rd, ctx);
- emit_zext_32(RV_REG_T2, ctx);
- emit_mv(RV_REG_T1, *rs, ctx);
- emit_zext_32(RV_REG_T1, ctx);
- *rd = RV_REG_T2;
- *rs = RV_REG_T1;
-}
-
-static void emit_sext_32_rd_rs(u8 *rd, u8 *rs, struct rv_jit_context *ctx)
-{
- emit_addiw(RV_REG_T2, *rd, 0, ctx);
- emit_addiw(RV_REG_T1, *rs, 0, ctx);
- *rd = RV_REG_T2;
- *rs = RV_REG_T1;
-}
-
-static void emit_zext_32_rd_t1(u8 *rd, struct rv_jit_context *ctx)
-{
- emit_mv(RV_REG_T2, *rd, ctx);
- emit_zext_32(RV_REG_T2, ctx);
- emit_zext_32(RV_REG_T1, ctx);
- *rd = RV_REG_T2;
-}
-
-static void emit_sext_32_rd(u8 *rd, struct rv_jit_context *ctx)
-{
- emit_addiw(RV_REG_T2, *rd, 0, ctx);
- *rd = RV_REG_T2;
-}
-
static int emit_jump_and_link(u8 rd, s64 rvoff, bool fixed_addr,
struct rv_jit_context *ctx)
{
@@ -480,6 +456,12 @@ static int emit_call(u64 addr, bool fixed_addr, struct rv_jit_context *ctx)
return emit_jump_and_link(RV_REG_RA, off, fixed_addr, ctx);
}
+static inline void emit_kcfi(u32 hash, struct rv_jit_context *ctx)
+{
+ if (IS_ENABLED(CONFIG_CFI_CLANG))
+ emit(hash, ctx);
+}
+
static void emit_atomic(u8 rd, u8 rs, s16 off, s32 imm, bool is64,
struct rv_jit_context *ctx)
{
@@ -519,32 +501,32 @@ static void emit_atomic(u8 rd, u8 rs, s16 off, s32 imm, bool is64,
emit(is64 ? rv_amoadd_d(rs, rs, rd, 0, 0) :
rv_amoadd_w(rs, rs, rd, 0, 0), ctx);
if (!is64)
- emit_zext_32(rs, ctx);
+ 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);
if (!is64)
- emit_zext_32(rs, ctx);
+ 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);
if (!is64)
- emit_zext_32(rs, ctx);
+ 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);
if (!is64)
- emit_zext_32(rs, ctx);
+ 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);
if (!is64)
- emit_zext_32(rs, ctx);
+ emit_zextw(rs, rs, ctx);
break;
/* r0 = atomic_cmpxchg(dst_reg + off16, r0, src_reg); */
case BPF_CMPXCHG:
@@ -894,6 +876,8 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
emit_sd(RV_REG_SP, stack_size - 16, RV_REG_FP, ctx);
emit_addi(RV_REG_FP, RV_REG_SP, stack_size, ctx);
} else {
+ /* emit kcfi hash */
+ emit_kcfi(cfi_get_func_hash(func_addr), ctx);
/* For the trampoline called directly, just handle
* the frame of trampoline.
*/
@@ -1091,7 +1075,7 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
case BPF_ALU64 | BPF_MOV | BPF_X:
if (imm == 1) {
/* Special mov32 for zext */
- emit_zext_32(rd, ctx);
+ emit_zextw(rd, rd, ctx);
break;
}
switch (insn->off) {
@@ -1099,16 +1083,17 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
emit_mv(rd, rs, ctx);
break;
case 8:
+ emit_sextb(rd, rs, ctx);
+ break;
case 16:
- emit_slli(RV_REG_T1, rs, 64 - insn->off, ctx);
- emit_srai(rd, RV_REG_T1, 64 - insn->off, ctx);
+ emit_sexth(rd, rs, ctx);
break;
case 32:
- emit_addiw(rd, rs, 0, ctx);
+ emit_sextw(rd, rs, ctx);
break;
}
if (!is64 && !aux->verifier_zext)
- emit_zext_32(rd, ctx);
+ emit_zextw(rd, rd, ctx);
break;
/* dst = dst OP src */
@@ -1116,7 +1101,7 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
case BPF_ALU64 | BPF_ADD | BPF_X:
emit_add(rd, rd, rs, ctx);
if (!is64 && !aux->verifier_zext)
- emit_zext_32(rd, ctx);
+ emit_zextw(rd, rd, ctx);
break;
case BPF_ALU | BPF_SUB | BPF_X:
case BPF_ALU64 | BPF_SUB | BPF_X:
@@ -1126,31 +1111,31 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
emit_subw(rd, rd, rs, ctx);
if (!is64 && !aux->verifier_zext)
- emit_zext_32(rd, ctx);
+ emit_zextw(rd, rd, ctx);
break;
case BPF_ALU | BPF_AND | BPF_X:
case BPF_ALU64 | BPF_AND | BPF_X:
emit_and(rd, rd, rs, ctx);
if (!is64 && !aux->verifier_zext)
- emit_zext_32(rd, ctx);
+ emit_zextw(rd, rd, ctx);
break;
case BPF_ALU | BPF_OR | BPF_X:
case BPF_ALU64 | BPF_OR | BPF_X:
emit_or(rd, rd, rs, ctx);
if (!is64 && !aux->verifier_zext)
- emit_zext_32(rd, ctx);
+ emit_zextw(rd, rd, ctx);
break;
case BPF_ALU | BPF_XOR | BPF_X:
case BPF_ALU64 | BPF_XOR | BPF_X:
emit_xor(rd, rd, rs, ctx);
if (!is64 && !aux->verifier_zext)
- emit_zext_32(rd, ctx);
+ emit_zextw(rd, rd, ctx);
break;
case BPF_ALU | BPF_MUL | BPF_X:
case BPF_ALU64 | BPF_MUL | BPF_X:
emit(is64 ? rv_mul(rd, rd, rs) : rv_mulw(rd, rd, rs), ctx);
if (!is64 && !aux->verifier_zext)
- emit_zext_32(rd, ctx);
+ emit_zextw(rd, rd, ctx);
break;
case BPF_ALU | BPF_DIV | BPF_X:
case BPF_ALU64 | BPF_DIV | BPF_X:
@@ -1159,7 +1144,7 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
else
emit(is64 ? rv_divu(rd, rd, rs) : rv_divuw(rd, rd, rs), ctx);
if (!is64 && !aux->verifier_zext)
- emit_zext_32(rd, ctx);
+ emit_zextw(rd, rd, ctx);
break;
case BPF_ALU | BPF_MOD | BPF_X:
case BPF_ALU64 | BPF_MOD | BPF_X:
@@ -1168,25 +1153,25 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
else
emit(is64 ? rv_remu(rd, rd, rs) : rv_remuw(rd, rd, rs), ctx);
if (!is64 && !aux->verifier_zext)
- emit_zext_32(rd, ctx);
+ emit_zextw(rd, rd, ctx);
break;
case BPF_ALU | BPF_LSH | BPF_X:
case BPF_ALU64 | BPF_LSH | BPF_X:
emit(is64 ? rv_sll(rd, rd, rs) : rv_sllw(rd, rd, rs), ctx);
if (!is64 && !aux->verifier_zext)
- emit_zext_32(rd, ctx);
+ emit_zextw(rd, rd, ctx);
break;
case BPF_ALU | BPF_RSH | BPF_X:
case BPF_ALU64 | BPF_RSH | BPF_X:
emit(is64 ? rv_srl(rd, rd, rs) : rv_srlw(rd, rd, rs), ctx);
if (!is64 && !aux->verifier_zext)
- emit_zext_32(rd, ctx);
+ emit_zextw(rd, rd, ctx);
break;
case BPF_ALU | BPF_ARSH | BPF_X:
case BPF_ALU64 | BPF_ARSH | BPF_X:
emit(is64 ? rv_sra(rd, rd, rs) : rv_sraw(rd, rd, rs), ctx);
if (!is64 && !aux->verifier_zext)
- emit_zext_32(rd, ctx);
+ emit_zextw(rd, rd, ctx);
break;
/* dst = -dst */
@@ -1194,73 +1179,27 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
case BPF_ALU64 | BPF_NEG:
emit_sub(rd, RV_REG_ZERO, rd, ctx);
if (!is64 && !aux->verifier_zext)
- emit_zext_32(rd, ctx);
+ emit_zextw(rd, rd, ctx);
break;
/* dst = BSWAP##imm(dst) */
case BPF_ALU | BPF_END | BPF_FROM_LE:
switch (imm) {
case 16:
- emit_slli(rd, rd, 48, ctx);
- emit_srli(rd, rd, 48, ctx);
+ emit_zexth(rd, rd, ctx);
break;
case 32:
if (!aux->verifier_zext)
- emit_zext_32(rd, ctx);
+ emit_zextw(rd, rd, ctx);
break;
case 64:
/* Do nothing */
break;
}
break;
-
case BPF_ALU | BPF_END | BPF_FROM_BE:
case BPF_ALU64 | BPF_END | BPF_FROM_LE:
- emit_li(RV_REG_T2, 0, ctx);
-
- emit_andi(RV_REG_T1, rd, 0xff, ctx);
- emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx);
- emit_slli(RV_REG_T2, RV_REG_T2, 8, ctx);
- emit_srli(rd, rd, 8, ctx);
- if (imm == 16)
- goto out_be;
-
- emit_andi(RV_REG_T1, rd, 0xff, ctx);
- emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx);
- emit_slli(RV_REG_T2, RV_REG_T2, 8, ctx);
- emit_srli(rd, rd, 8, ctx);
-
- emit_andi(RV_REG_T1, rd, 0xff, ctx);
- emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx);
- emit_slli(RV_REG_T2, RV_REG_T2, 8, ctx);
- emit_srli(rd, rd, 8, ctx);
- if (imm == 32)
- goto out_be;
-
- emit_andi(RV_REG_T1, rd, 0xff, ctx);
- emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx);
- emit_slli(RV_REG_T2, RV_REG_T2, 8, ctx);
- emit_srli(rd, rd, 8, ctx);
-
- emit_andi(RV_REG_T1, rd, 0xff, ctx);
- emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx);
- emit_slli(RV_REG_T2, RV_REG_T2, 8, ctx);
- emit_srli(rd, rd, 8, ctx);
-
- emit_andi(RV_REG_T1, rd, 0xff, ctx);
- emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx);
- emit_slli(RV_REG_T2, RV_REG_T2, 8, ctx);
- emit_srli(rd, rd, 8, ctx);
-
- emit_andi(RV_REG_T1, rd, 0xff, ctx);
- emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx);
- emit_slli(RV_REG_T2, RV_REG_T2, 8, ctx);
- emit_srli(rd, rd, 8, ctx);
-out_be:
- emit_andi(RV_REG_T1, rd, 0xff, ctx);
- emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx);
-
- emit_mv(rd, RV_REG_T2, ctx);
+ emit_bswap(rd, imm, ctx);
break;
/* dst = imm */
@@ -1268,7 +1207,7 @@ out_be:
case BPF_ALU64 | BPF_MOV | BPF_K:
emit_imm(rd, imm, ctx);
if (!is64 && !aux->verifier_zext)
- emit_zext_32(rd, ctx);
+ emit_zextw(rd, rd, ctx);
break;
/* dst = dst OP imm */
@@ -1281,7 +1220,7 @@ out_be:
emit_add(rd, rd, RV_REG_T1, ctx);
}
if (!is64 && !aux->verifier_zext)
- emit_zext_32(rd, ctx);
+ emit_zextw(rd, rd, ctx);
break;
case BPF_ALU | BPF_SUB | BPF_K:
case BPF_ALU64 | BPF_SUB | BPF_K:
@@ -1292,7 +1231,7 @@ out_be:
emit_sub(rd, rd, RV_REG_T1, ctx);
}
if (!is64 && !aux->verifier_zext)
- emit_zext_32(rd, ctx);
+ emit_zextw(rd, rd, ctx);
break;
case BPF_ALU | BPF_AND | BPF_K:
case BPF_ALU64 | BPF_AND | BPF_K:
@@ -1303,7 +1242,7 @@ out_be:
emit_and(rd, rd, RV_REG_T1, ctx);
}
if (!is64 && !aux->verifier_zext)
- emit_zext_32(rd, ctx);
+ emit_zextw(rd, rd, ctx);
break;
case BPF_ALU | BPF_OR | BPF_K:
case BPF_ALU64 | BPF_OR | BPF_K:
@@ -1314,7 +1253,7 @@ out_be:
emit_or(rd, rd, RV_REG_T1, ctx);
}
if (!is64 && !aux->verifier_zext)
- emit_zext_32(rd, ctx);
+ emit_zextw(rd, rd, ctx);
break;
case BPF_ALU | BPF_XOR | BPF_K:
case BPF_ALU64 | BPF_XOR | BPF_K:
@@ -1325,7 +1264,7 @@ out_be:
emit_xor(rd, rd, RV_REG_T1, ctx);
}
if (!is64 && !aux->verifier_zext)
- emit_zext_32(rd, ctx);
+ emit_zextw(rd, rd, ctx);
break;
case BPF_ALU | BPF_MUL | BPF_K:
case BPF_ALU64 | BPF_MUL | BPF_K:
@@ -1333,7 +1272,7 @@ out_be:
emit(is64 ? rv_mul(rd, rd, RV_REG_T1) :
rv_mulw(rd, rd, RV_REG_T1), ctx);
if (!is64 && !aux->verifier_zext)
- emit_zext_32(rd, ctx);
+ emit_zextw(rd, rd, ctx);
break;
case BPF_ALU | BPF_DIV | BPF_K:
case BPF_ALU64 | BPF_DIV | BPF_K:
@@ -1345,7 +1284,7 @@ out_be:
emit(is64 ? rv_divu(rd, rd, RV_REG_T1) :
rv_divuw(rd, rd, RV_REG_T1), ctx);
if (!is64 && !aux->verifier_zext)
- emit_zext_32(rd, ctx);
+ emit_zextw(rd, rd, ctx);
break;
case BPF_ALU | BPF_MOD | BPF_K:
case BPF_ALU64 | BPF_MOD | BPF_K:
@@ -1357,14 +1296,14 @@ out_be:
emit(is64 ? rv_remu(rd, rd, RV_REG_T1) :
rv_remuw(rd, rd, RV_REG_T1), ctx);
if (!is64 && !aux->verifier_zext)
- emit_zext_32(rd, ctx);
+ emit_zextw(rd, rd, ctx);
break;
case BPF_ALU | BPF_LSH | BPF_K:
case BPF_ALU64 | BPF_LSH | BPF_K:
emit_slli(rd, rd, imm, ctx);
if (!is64 && !aux->verifier_zext)
- emit_zext_32(rd, ctx);
+ emit_zextw(rd, rd, ctx);
break;
case BPF_ALU | BPF_RSH | BPF_K:
case BPF_ALU64 | BPF_RSH | BPF_K:
@@ -1374,7 +1313,7 @@ out_be:
emit(rv_srliw(rd, rd, imm), ctx);
if (!is64 && !aux->verifier_zext)
- emit_zext_32(rd, ctx);
+ emit_zextw(rd, rd, ctx);
break;
case BPF_ALU | BPF_ARSH | BPF_K:
case BPF_ALU64 | BPF_ARSH | BPF_K:
@@ -1384,7 +1323,7 @@ out_be:
emit(rv_sraiw(rd, rd, imm), ctx);
if (!is64 && !aux->verifier_zext)
- emit_zext_32(rd, ctx);
+ emit_zextw(rd, rd, ctx);
break;
/* JUMP off */
@@ -1425,10 +1364,13 @@ out_be:
rvoff = rv_offset(i, off, ctx);
if (!is64) {
s = ctx->ninsns;
- if (is_signed_bpf_cond(BPF_OP(code)))
- emit_sext_32_rd_rs(&rd, &rs, ctx);
- else
- emit_zext_32_rd_rs(&rd, &rs, ctx);
+ if (is_signed_bpf_cond(BPF_OP(code))) {
+ emit_sextw_alt(&rs, RV_REG_T1, ctx);
+ emit_sextw_alt(&rd, RV_REG_T2, ctx);
+ } else {
+ emit_zextw_alt(&rs, RV_REG_T1, ctx);
+ emit_zextw_alt(&rd, RV_REG_T2, ctx);
+ }
e = ctx->ninsns;
/* Adjust for extra insns */
@@ -1439,8 +1381,7 @@ out_be:
/* Adjust for and */
rvoff -= 4;
emit_and(RV_REG_T1, rd, rs, ctx);
- emit_branch(BPF_JNE, RV_REG_T1, RV_REG_ZERO, rvoff,
- ctx);
+ emit_branch(BPF_JNE, RV_REG_T1, RV_REG_ZERO, rvoff, ctx);
} else {
emit_branch(BPF_OP(code), rd, rs, rvoff, ctx);
}
@@ -1469,18 +1410,18 @@ out_be:
case BPF_JMP32 | BPF_JSLE | BPF_K:
rvoff = rv_offset(i, off, ctx);
s = ctx->ninsns;
- if (imm) {
+ if (imm)
emit_imm(RV_REG_T1, imm, ctx);
- rs = RV_REG_T1;
- } else {
- /* If imm is 0, simply use zero register. */
- rs = RV_REG_ZERO;
- }
+ rs = imm ? RV_REG_T1 : RV_REG_ZERO;
if (!is64) {
- if (is_signed_bpf_cond(BPF_OP(code)))
- emit_sext_32_rd(&rd, ctx);
- else
- emit_zext_32_rd_t1(&rd, ctx);
+ if (is_signed_bpf_cond(BPF_OP(code))) {
+ emit_sextw_alt(&rd, RV_REG_T2, ctx);
+ /* rs has been sign extended */
+ } else {
+ emit_zextw_alt(&rd, RV_REG_T2, ctx);
+ if (imm)
+ emit_zextw(rs, rs, ctx);
+ }
}
e = ctx->ninsns;
@@ -1504,7 +1445,7 @@ out_be:
* as t1 is used only in comparison against zero.
*/
if (!is64 && imm < 0)
- emit_addiw(RV_REG_T1, RV_REG_T1, 0, ctx);
+ emit_sextw(RV_REG_T1, RV_REG_T1, ctx);
e = ctx->ninsns;
rvoff -= ninsns_rvoff(e - s);
emit_branch(BPF_JNE, RV_REG_T1, RV_REG_ZERO, rvoff, ctx);
@@ -1522,6 +1463,22 @@ out_be:
if (ret < 0)
return ret;
+ if (insn->src_reg == BPF_PSEUDO_KFUNC_CALL) {
+ const struct btf_func_model *fm;
+ int idx;
+
+ fm = bpf_jit_find_kfunc_model(ctx->prog, insn);
+ if (!fm)
+ return -EINVAL;
+
+ for (idx = 0; idx < fm->nr_args; idx++) {
+ u8 reg = bpf_to_rv_reg(BPF_REG_1 + idx, ctx);
+
+ if (fm->arg_size[idx] == sizeof(int))
+ emit_sextw(reg, reg, ctx);
+ }
+ }
+
ret = emit_call(addr, fixed_addr, ctx);
if (ret)
return ret;
@@ -1779,7 +1736,7 @@ out_be:
return 0;
}
-void bpf_jit_build_prologue(struct rv_jit_context *ctx)
+void bpf_jit_build_prologue(struct rv_jit_context *ctx, bool is_subprog)
{
int i, stack_adjust = 0, store_offset, bpf_stack_adjust;
@@ -1808,6 +1765,9 @@ void bpf_jit_build_prologue(struct rv_jit_context *ctx)
store_offset = stack_adjust - 8;
+ /* emit kcfi type preamble immediately before the first insn */
+ emit_kcfi(is_subprog ? cfi_bpf_subprog_hash : cfi_bpf_hash, ctx);
+
/* nops reserved for auipc+jalr pair */
for (i = 0; i < RV_FENTRY_NINSNS; i++)
emit(rv_nop(), ctx);
@@ -1874,3 +1834,8 @@ bool bpf_jit_supports_kfunc_call(void)
{
return true;
}
+
+bool bpf_jit_supports_ptr_xchg(void)
+{
+ return true;
+}
diff --git a/arch/riscv/net/bpf_jit_core.c b/arch/riscv/net/bpf_jit_core.c
index 7b70ccb7fec3..6b3acac30c06 100644
--- a/arch/riscv/net/bpf_jit_core.c
+++ b/arch/riscv/net/bpf_jit_core.c
@@ -10,6 +10,7 @@
#include <linux/filter.h>
#include <linux/memory.h>
#include <asm/patch.h>
+#include <asm/cfi.h>
#include "bpf_jit.h"
/* Number of iterations to try until offsets converge. */
@@ -100,7 +101,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
pass++;
ctx->ninsns = 0;
- bpf_jit_build_prologue(ctx);
+ bpf_jit_build_prologue(ctx, bpf_is_subprog(prog));
ctx->prologue_len = ctx->ninsns;
if (build_body(ctx, extra_pass, ctx->offset)) {
@@ -160,7 +161,7 @@ skip_init_ctx:
ctx->ninsns = 0;
ctx->nexentries = 0;
- bpf_jit_build_prologue(ctx);
+ bpf_jit_build_prologue(ctx, bpf_is_subprog(prog));
if (build_body(ctx, extra_pass, NULL)) {
prog = orig_prog;
goto out_free_hdr;
@@ -170,9 +171,9 @@ skip_init_ctx:
if (bpf_jit_enable > 1)
bpf_jit_dump(prog->len, prog_size, pass, ctx->insns);
- prog->bpf_func = (void *)ctx->ro_insns;
+ prog->bpf_func = (void *)ctx->ro_insns + cfi_get_offset();
prog->jited = 1;
- prog->jited_len = prog_size;
+ 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,
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index fe565f3a3a91..8f01ada6845e 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -63,6 +63,7 @@ config S390
select ARCH_ENABLE_MEMORY_HOTREMOVE
select ARCH_ENABLE_SPLIT_PMD_PTLOCK if PGTABLE_LEVELS > 2
select ARCH_HAS_CURRENT_STACK_POINTER
+ select ARCH_HAS_DEBUG_VIRTUAL
select ARCH_HAS_DEBUG_VM_PGTABLE
select ARCH_HAS_DEBUG_WX
select ARCH_HAS_DEVMEM_IS_ALLOWED
@@ -82,7 +83,7 @@ config S390
select ARCH_HAS_STRICT_KERNEL_RWX
select ARCH_HAS_STRICT_MODULE_RWX
select ARCH_HAS_SYSCALL_WRAPPER
- select ARCH_HAS_UBSAN_SANITIZE_ALL
+ select ARCH_HAS_UBSAN
select ARCH_HAS_VDSO_DATA
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select ARCH_INLINE_READ_LOCK
@@ -113,6 +114,7 @@ config S390
select ARCH_INLINE_WRITE_UNLOCK_BH
select ARCH_INLINE_WRITE_UNLOCK_IRQ
select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE
+ select ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE
select ARCH_STACKWALK
select ARCH_SUPPORTS_ATOMIC_RMW
select ARCH_SUPPORTS_DEBUG_PAGEALLOC
@@ -127,6 +129,7 @@ config S390
select ARCH_WANT_DEFAULT_BPF_JIT
select ARCH_WANT_IPC_PARSE_VERSION
select ARCH_WANT_KERNEL_PMD_MKWRITE
+ select ARCH_WANT_LD_ORPHAN_WARN
select ARCH_WANT_OPTIMIZE_HUGETLB_VMEMMAP
select BUILDTIME_TABLE_SORT
select CLONE_BACKWARDS2
@@ -193,12 +196,12 @@ config S390
select HAVE_KPROBES
select HAVE_KPROBES_ON_FTRACE
select HAVE_KRETPROBES
- select HAVE_KVM
select HAVE_LIVEPATCH
select HAVE_MEMBLOCK_PHYS_MAP
select HAVE_MOD_ARCH_SPECIFIC
select HAVE_NMI
select HAVE_NOP_MCOUNT
+ select HAVE_PAGE_SIZE_4KB
select HAVE_PCI
select HAVE_PERF_EVENTS
select HAVE_PERF_REGS
@@ -448,7 +451,7 @@ config COMPAT
select COMPAT_OLD_SIGACTION
select HAVE_UID16
depends on MULTIUSER
- depends on !CC_IS_CLANG
+ depends on !CC_IS_CLANG && !LD_IS_LLD
help
Select this option if you want to enable your system kernel to
handle system-calls from ELF binaries for 31 bit ESA. This option
@@ -582,14 +585,23 @@ config RELOCATABLE
help
This builds a kernel image that retains relocation information
so it can be loaded at an arbitrary address.
- The kernel is linked as a position-independent executable (PIE)
- and contains dynamic relocations which are processed early in the
- bootup process.
The relocations make the kernel image about 15% larger (compressed
10%), but are discarded at runtime.
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
diff --git a/arch/s390/Makefile b/arch/s390/Makefile
index 73873e451686..2dbb2d2f22f9 100644
--- a/arch/s390/Makefile
+++ b/arch/s390/Makefile
@@ -14,8 +14,14 @@ KBUILD_AFLAGS_MODULE += -fPIC
KBUILD_CFLAGS_MODULE += -fPIC
KBUILD_AFLAGS += -m64
KBUILD_CFLAGS += -m64
+ifdef CONFIG_PIE_BUILD
KBUILD_CFLAGS += -fPIE
-LDFLAGS_vmlinux := -pie
+LDFLAGS_vmlinux := -pie -z notext
+else
+KBUILD_CFLAGS += $(call cc-option,-munaligned-symbols,)
+LDFLAGS_vmlinux := --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
@@ -23,6 +29,7 @@ KBUILD_AFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO),$(aflags_dwarf))
endif
KBUILD_CFLAGS_DECOMPRESSOR := $(CLANG_FLAGS) -m64 -O2 -mpacked-stack
KBUILD_CFLAGS_DECOMPRESSOR += -DDISABLE_BRANCH_PROFILING -D__NO_FORTIFY
+KBUILD_CFLAGS_DECOMPRESSOR += -D__DECOMPRESSOR
KBUILD_CFLAGS_DECOMPRESSOR += -fno-delete-null-pointer-checks -msoft-float -mbackchain
KBUILD_CFLAGS_DECOMPRESSOR += -fno-asynchronous-unwind-tables
KBUILD_CFLAGS_DECOMPRESSOR += -ffreestanding
@@ -143,7 +150,7 @@ archheaders:
archprepare:
$(Q)$(MAKE) $(build)=$(syscalls) kapi
- $(Q)$(MAKE) $(build)=$(tools) kapi
+ $(Q)$(MAKE) $(build)=$(tools) kapi $(extra_tools)
ifeq ($(KBUILD_EXTMOD),)
# We need to generate vdso-offsets.h before compiling certain files in kernel/.
# In order to do that, we should use the archprepare target, but we can't since
diff --git a/arch/s390/boot/.gitignore b/arch/s390/boot/.gitignore
index f56591bc0897..f5ef099e2fd3 100644
--- a/arch/s390/boot/.gitignore
+++ b/arch/s390/boot/.gitignore
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
image
bzImage
+relocs.S
section_cmp.*
vmlinux
vmlinux.lds
diff --git a/arch/s390/boot/Makefile b/arch/s390/boot/Makefile
index c7c81e5f9218..294f08a8811a 100644
--- a/arch/s390/boot/Makefile
+++ b/arch/s390/boot/Makefile
@@ -37,7 +37,8 @@ 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 machine_kexec_reloc.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-$(CONFIG_RANDOMIZE_BASE) += kaslr.o
obj-y += $(if $(CONFIG_KERNEL_UNCOMPRESSED),,decompressor.o) info.o
@@ -48,6 +49,9 @@ 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))
@@ -56,9 +60,9 @@ clean-files += vmlinux.map
quiet_cmd_section_cmp = SECTCMP $*
define cmd_section_cmp
- s1=`$(OBJDUMP) -t -j "$*" "$<" | sort | \
+ s1=`$(OBJDUMP) -t "$<" | grep "\s$*\s\+" | sort | \
sed -n "/0000000000000000/! s/.*\s$*\s\+//p" | sha256sum`; \
- s2=`$(OBJDUMP) -t -j "$*" "$(word 2,$^)" | sort | \
+ s2=`$(OBJDUMP) -t "$(word 2,$^)" | grep "\s$*\s\+" | sort | \
sed -n "/0000000000000000/! s/.*\s$*\s\+//p" | sha256sum`; \
if [ "$$s1" != "$$s2" ]; then \
echo "error: section $* differs between $< and $(word 2,$^)" >&2; \
@@ -73,11 +77,12 @@ $(obj)/bzImage: $(obj)/vmlinux $(obj)/section_cmp.boot.data $(obj)/section_cmp.b
$(obj)/section_cmp%: vmlinux $(obj)/vmlinux FORCE
$(call if_changed,section_cmp)
-LDFLAGS_vmlinux := --oformat $(LD_BFD) -e startup $(if $(CONFIG_VMLINUX_MAP),-Map=$(obj)/vmlinux.map) --build-id=sha1 -T
+LDFLAGS_vmlinux-$(CONFIG_LD_ORPHAN_WARN) := --orphan-handling=$(CONFIG_LD_ORPHAN_WARN_LEVEL)
+LDFLAGS_vmlinux := $(LDFLAGS_vmlinux-y) --oformat $(LD_BFD) -e startup $(if $(CONFIG_VMLINUX_MAP),-Map=$(obj)/vmlinux.map) --build-id=sha1 -T
$(obj)/vmlinux: $(obj)/vmlinux.lds $(OBJECTS_ALL) FORCE
$(call if_changed,ld)
-LDFLAGS_vmlinux.syms := --oformat $(LD_BFD) -e startup -T
+LDFLAGS_vmlinux.syms := $(LDFLAGS_vmlinux-y) --oformat $(LD_BFD) -e startup -T
$(obj)/vmlinux.syms: $(obj)/vmlinux.lds $(OBJECTS) FORCE
$(call if_changed,ld)
@@ -93,7 +98,7 @@ OBJCOPYFLAGS_syms.o := -I binary -O elf64-s390 -B s390:64-bit --rename-section .
$(obj)/syms.o: $(obj)/syms.bin FORCE
$(call if_changed,objcopy)
-OBJCOPYFLAGS_info.bin := -O binary --only-section=.vmlinux.info --set-section-flags .vmlinux.info=load
+OBJCOPYFLAGS_info.bin := -O binary --only-section=.vmlinux.info --set-section-flags .vmlinux.info=alloc,load
$(obj)/info.bin: vmlinux FORCE
$(call if_changed,objcopy)
@@ -105,6 +110,14 @@ 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 $@
+ cmd_relocs = $(CMD_RELOCS) $< > $@
+$(obj)/relocs.S: vmlinux FORCE
+ $(call if_changed,relocs)
+endif
+
suffix-$(CONFIG_KERNEL_GZIP) := .gz
suffix-$(CONFIG_KERNEL_BZIP2) := .bz2
suffix-$(CONFIG_KERNEL_LZ4) := .lz4
diff --git a/arch/s390/boot/boot.h b/arch/s390/boot/boot.h
index 222c6886acf6..567d60f78bbc 100644
--- a/arch/s390/boot/boot.h
+++ b/arch/s390/boot/boot.h
@@ -25,9 +25,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;
@@ -83,6 +88,7 @@ extern unsigned long vmalloc_size;
extern int vmalloc_size_set;
extern char __boot_data_start[], __boot_data_end[];
extern char __boot_data_preserved_start[], __boot_data_preserved_end[];
+extern char __vmlinux_relocs_64_start[], __vmlinux_relocs_64_end[];
extern char _decompressor_syms_start[], _decompressor_syms_end[];
extern char _stack_start[], _stack_end[];
extern char _end[], _decompressor_end[];
diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c
index 9cc76e631759..6cf89314209a 100644
--- a/arch/s390/boot/startup.c
+++ b/arch/s390/boot/startup.c
@@ -141,7 +141,8 @@ static void copy_bootdata(void)
memcpy((void *)vmlinux.bootdata_preserved_off, __boot_data_preserved_start, vmlinux.bootdata_preserved_size);
}
-static void handle_relocs(unsigned long offset)
+#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;
@@ -172,6 +173,54 @@ static void handle_relocs(unsigned long offset)
}
}
+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)
+{
+ 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;
+ if (loc < min_addr || loc > max_addr)
+ error("64-bit relocation outside of kernel!\n");
+ *(u64 *)loc += offset;
+ }
+}
+
+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.
+ */
+ for (entry = (u64 *)vmlinux.got_start; entry < (u64 *)vmlinux.got_end; entry++)
+ *entry += offset;
+}
+#endif
+
/*
* Merge information from several sources into a single ident_map_size value.
* "ident_map_size" represents the upper limit of physical memory we may ever
@@ -299,14 +348,19 @@ static void setup_vmalloc_size(void)
vmalloc_size = max(size, vmalloc_size);
}
-static void offset_vmlinux_info(unsigned long offset)
+static void kaslr_adjust_vmlinux_info(unsigned 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;
@@ -361,6 +415,7 @@ void startup_kernel(void)
detect_physmem_online_ranges(max_physmem_end);
save_ipl_cert_comp_list();
rescue_initrd(safe_addr, ident_map_size);
+ rescue_relocs();
if (kaslr_enabled()) {
vmlinux_lma = randomize_within_range(vmlinux.image_size + vmlinux.bss_size,
@@ -368,7 +423,7 @@ void startup_kernel(void)
ident_map_size);
if (vmlinux_lma) {
__kaslr_offset = vmlinux_lma - vmlinux.default_lma;
- offset_vmlinux_info(__kaslr_offset);
+ kaslr_adjust_vmlinux_info(__kaslr_offset);
}
}
vmlinux_lma = vmlinux_lma ?: vmlinux.default_lma;
@@ -393,18 +448,20 @@ void startup_kernel(void)
/*
* The order of the following operations is important:
*
- * - handle_relocs() must follow clear_bss_section() to establish static
- * memory references to data in .bss to be used by setup_vmem()
+ * - kaslr_adjust_relocs() must follow clear_bss_section() to establish
+ * static memory references to data in .bss to be used by setup_vmem()
* (i.e init_mm.pgd)
*
- * - setup_vmem() must follow handle_relocs() to be able using
+ * - setup_vmem() must follow kaslr_adjust_relocs() to be able using
* static memory references to data in .bss (i.e init_mm.pgd)
*
- * - copy_bootdata() must follow setup_vmem() to propagate changes to
- * bootdata made by setup_vmem()
+ * - copy_bootdata() must follow setup_vmem() to propagate changes
+ * to bootdata made by setup_vmem()
*/
clear_bss_section(vmlinux_lma);
- handle_relocs(__kaslr_offset);
+ kaslr_adjust_relocs(vmlinux_lma, vmlinux_lma + vmlinux.image_size, __kaslr_offset);
+ kaslr_adjust_got(__kaslr_offset);
+ free_relocs();
setup_vmem(asce_limit);
copy_bootdata();
diff --git a/arch/s390/boot/vmem.c b/arch/s390/boot/vmem.c
index e3a4500a5a75..09b10bb6e4d0 100644
--- a/arch/s390/boot/vmem.c
+++ b/arch/s390/boot/vmem.c
@@ -333,7 +333,7 @@ static void pgtable_pmd_populate(pud_t *pud, unsigned long addr, unsigned long e
}
pte = boot_pte_alloc();
pmd_populate(&init_mm, pmd, pte);
- } else if (pmd_large(*pmd)) {
+ } else if (pmd_leaf(*pmd)) {
continue;
}
pgtable_pte_populate(pmd, addr, next, mode);
@@ -366,7 +366,7 @@ static void pgtable_pud_populate(p4d_t *p4d, unsigned long addr, unsigned long e
}
pmd = boot_crst_alloc(_SEGMENT_ENTRY_EMPTY);
pud_populate(&init_mm, pud, pmd);
- } else if (pud_large(*pud)) {
+ } else if (pud_leaf(*pud)) {
continue;
}
pgtable_pmd_populate(pud, addr, next, mode);
diff --git a/arch/s390/boot/vmlinux.lds.S b/arch/s390/boot/vmlinux.lds.S
index 389df0e0d9e5..3d7ea585ab99 100644
--- a/arch/s390/boot/vmlinux.lds.S
+++ b/arch/s390/boot/vmlinux.lds.S
@@ -31,6 +31,7 @@ SECTIONS
_text = .; /* Text */
*(.text)
*(.text.*)
+ INIT_TEXT
_etext = . ;
}
.rodata : {
@@ -39,6 +40,9 @@ SECTIONS
*(.rodata.*)
_erodata = . ;
}
+ .got : {
+ *(.got)
+ }
NOTES
.data : {
_data = . ;
@@ -106,6 +110,24 @@ 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 */
@@ -118,8 +140,34 @@ SECTIONS
}
_end = .;
+ DWARF_DEBUG
+ ELF_DETAILS
+
+ /*
+ * Make sure that the .got.plt is either completely empty or it
+ * contains only the three reserved double words.
+ */
+ .got.plt : {
+ *(.got.plt)
+ }
+ ASSERT(SIZEOF(.got.plt) == 0 || SIZEOF(.got.plt) == 0x18, "Unexpected GOT/PLT entries detected!")
+
+ /*
+ * Sections that should stay zero sized, which is safer to
+ * explicitly check instead of blindly discarding.
+ */
+ .plt : {
+ *(.plt) *(.plt.*) *(.iplt) *(.igot .igot.plt)
+ }
+ ASSERT(SIZEOF(.plt) == 0, "Unexpected run-time procedure linkages detected!")
+ .rela.dyn : {
+ *(.rela.*) *(.rela_*)
+ }
+ ASSERT(SIZEOF(.rela.dyn) == 0, "Unexpected run-time relocations (.rela) detected!")
+
/* Sections to be discarded */
/DISCARD/ : {
+ COMMON_DISCARDS
*(.eh_frame)
*(__ex_table)
*(*__ksymtab*)
diff --git a/arch/s390/configs/debug_defconfig b/arch/s390/configs/debug_defconfig
index c924be0d7ed8..f1fb01cd5a25 100644
--- a/arch/s390/configs/debug_defconfig
+++ b/arch/s390/configs/debug_defconfig
@@ -810,6 +810,7 @@ CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y
CONFIG_DEBUG_STACK_USAGE=y
CONFIG_DEBUG_VM=y
CONFIG_DEBUG_VM_PGFLAGS=y
+CONFIG_DEBUG_VIRTUAL=y
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_MEMORY_NOTIFIER_ERROR_INJECT=m
CONFIG_DEBUG_PER_CPU_MAPS=y
@@ -824,6 +825,8 @@ CONFIG_TEST_LOCKUP=m
CONFIG_DEBUG_PREEMPT=y
CONFIG_PROVE_LOCKING=y
CONFIG_LOCK_STAT=y
+CONFIG_LOCKDEP_BITS=16
+CONFIG_LOCKDEP_CHAINS_BITS=17
CONFIG_DEBUG_ATOMIC_SLEEP=y
CONFIG_DEBUG_LOCKING_API_SELFTESTS=y
CONFIG_DEBUG_IRQFLAGS=y
@@ -880,4 +883,3 @@ CONFIG_ATOMIC64_SELFTEST=y
CONFIG_STRING_SELFTEST=y
CONFIG_TEST_BITOPS=m
CONFIG_TEST_BPF=m
-CONFIG_TEST_LIVEPATCH=m
diff --git a/arch/s390/configs/defconfig b/arch/s390/configs/defconfig
index c8f0c9fe40d7..d33f814f78b2 100644
--- a/arch/s390/configs/defconfig
+++ b/arch/s390/configs/defconfig
@@ -808,4 +808,3 @@ CONFIG_KPROBES_SANITY_TEST=m
CONFIG_PERCPU_TEST=m
CONFIG_ATOMIC64_SELFTEST=y
CONFIG_TEST_BPF=m
-CONFIG_TEST_LIVEPATCH=m
diff --git a/arch/s390/crypto/chacha-glue.c b/arch/s390/crypto/chacha-glue.c
index ed9959e6f714..f8b0c52e77a4 100644
--- a/arch/s390/crypto/chacha-glue.c
+++ b/arch/s390/crypto/chacha-glue.c
@@ -15,14 +15,14 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sizes.h>
-#include <asm/fpu/api.h>
+#include <asm/fpu.h>
#include "chacha-s390.h"
static void chacha20_crypt_s390(u32 *state, u8 *dst, const u8 *src,
unsigned int nbytes, const u32 *key,
u32 *counter)
{
- struct kernel_fpu vxstate;
+ DECLARE_KERNEL_FPU_ONSTACK32(vxstate);
kernel_fpu_begin(&vxstate, KERNEL_VXR);
chacha20_vx(dst, src, nbytes, key, counter);
diff --git a/arch/s390/crypto/chacha-s390.S b/arch/s390/crypto/chacha-s390.S
index 37cb63f25b17..63f3102678c0 100644
--- a/arch/s390/crypto/chacha-s390.S
+++ b/arch/s390/crypto/chacha-s390.S
@@ -8,7 +8,7 @@
#include <linux/linkage.h>
#include <asm/nospec-insn.h>
-#include <asm/vx-insn.h>
+#include <asm/fpu-insn.h>
#define SP %r15
#define FRAME (16 * 8 + 4 * 8)
diff --git a/arch/s390/crypto/crc32-vx.c b/arch/s390/crypto/crc32-vx.c
index 017143e9cef7..74f17c905d12 100644
--- a/arch/s390/crypto/crc32-vx.c
+++ b/arch/s390/crypto/crc32-vx.c
@@ -13,8 +13,8 @@
#include <linux/cpufeature.h>
#include <linux/crc32.h>
#include <crypto/internal/hash.h>
-#include <asm/fpu/api.h>
-
+#include <asm/fpu.h>
+#include "crc32-vx.h"
#define CRC32_BLOCK_SIZE 1
#define CRC32_DIGEST_SIZE 4
@@ -31,11 +31,6 @@ struct crc_desc_ctx {
u32 crc;
};
-/* Prototypes for functions in assembly files */
-u32 crc32_le_vgfm_16(u32 crc, unsigned char const *buf, size_t size);
-u32 crc32_be_vgfm_16(u32 crc, unsigned char const *buf, size_t size);
-u32 crc32c_le_vgfm_16(u32 crc, unsigned char const *buf, size_t size);
-
/*
* DEFINE_CRC32_VX() - Define a CRC-32 function using the vector extension
*
@@ -49,8 +44,8 @@ u32 crc32c_le_vgfm_16(u32 crc, unsigned char const *buf, size_t size);
static u32 __pure ___fname(u32 crc, \
unsigned char const *data, size_t datalen) \
{ \
- struct kernel_fpu vxstate; \
unsigned long prealign, aligned, remaining; \
+ DECLARE_KERNEL_FPU_ONSTACK16(vxstate); \
\
if (datalen < VX_MIN_LEN + VX_ALIGN_MASK) \
return ___crc32_sw(crc, data, datalen); \
diff --git a/arch/s390/crypto/crc32-vx.h b/arch/s390/crypto/crc32-vx.h
new file mode 100644
index 000000000000..652c96e1a822
--- /dev/null
+++ b/arch/s390/crypto/crc32-vx.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _CRC32_VX_S390_H
+#define _CRC32_VX_S390_H
+
+#include <linux/types.h>
+
+u32 crc32_be_vgfm_16(u32 crc, unsigned char const *buf, size_t size);
+u32 crc32_le_vgfm_16(u32 crc, unsigned char const *buf, size_t size);
+u32 crc32c_le_vgfm_16(u32 crc, unsigned char const *buf, size_t size);
+
+#endif /* _CRC32_VX_S390_H */
diff --git a/arch/s390/crypto/crc32be-vx.S b/arch/s390/crypto/crc32be-vx.c
index 34ee47926891..fed7c9c70d05 100644
--- a/arch/s390/crypto/crc32be-vx.S
+++ b/arch/s390/crypto/crc32be-vx.c
@@ -12,20 +12,17 @@
* Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
*/
-#include <linux/linkage.h>
-#include <asm/nospec-insn.h>
-#include <asm/vx-insn.h>
+#include <linux/types.h>
+#include <asm/fpu.h>
+#include "crc32-vx.h"
/* Vector register range containing CRC-32 constants */
-#define CONST_R1R2 %v9
-#define CONST_R3R4 %v10
-#define CONST_R5 %v11
-#define CONST_R6 %v12
-#define CONST_RU_POLY %v13
-#define CONST_CRC_POLY %v14
-
- .data
- .balign 8
+#define CONST_R1R2 9
+#define CONST_R3R4 10
+#define CONST_R5 11
+#define CONST_R6 12
+#define CONST_RU_POLY 13
+#define CONST_CRC_POLY 14
/*
* The CRC-32 constant block contains reduction constants to fold and
@@ -58,105 +55,74 @@
* P'(x) = 0xEDB88320
*/
-SYM_DATA_START_LOCAL(constants_CRC_32_BE)
- .quad 0x08833794c, 0x0e6228b11 # R1, R2
- .quad 0x0c5b9cd4c, 0x0e8a45605 # R3, R4
- .quad 0x0f200aa66, 1 << 32 # R5, x32
- .quad 0x0490d678d, 1 # R6, 1
- .quad 0x104d101df, 0 # u
- .quad 0x104C11DB7, 0 # P(x)
-SYM_DATA_END(constants_CRC_32_BE)
-
- .previous
-
- GEN_BR_THUNK %r14
-
- .text
-/*
- * The CRC-32 function(s) use these calling conventions:
- *
- * Parameters:
- *
- * %r2: Initial CRC value, typically ~0; and final CRC (return) value.
- * %r3: Input buffer pointer, performance might be improved if the
- * buffer is on a doubleword boundary.
- * %r4: Length of the buffer, must be 64 bytes or greater.
+static unsigned long constants_CRC_32_BE[] = {
+ 0x08833794c, 0x0e6228b11, /* R1, R2 */
+ 0x0c5b9cd4c, 0x0e8a45605, /* R3, R4 */
+ 0x0f200aa66, 1UL << 32, /* R5, x32 */
+ 0x0490d678d, 1, /* R6, 1 */
+ 0x104d101df, 0, /* u */
+ 0x104C11DB7, 0, /* P(x) */
+};
+
+/**
+ * crc32_be_vgfm_16 - Compute CRC-32 (BE variant) with vector registers
+ * @crc: Initial CRC value, typically ~0.
+ * @buf: Input buffer pointer, performance might be improved if the
+ * buffer is on a doubleword boundary.
+ * @size: Size of the buffer, must be 64 bytes or greater.
*
* Register usage:
- *
- * %r5: CRC-32 constant pool base pointer.
* V0: Initial CRC value and intermediate constants and results.
* V1..V4: Data for CRC computation.
* V5..V8: Next data chunks that are fetched from the input buffer.
- *
* V9..V14: CRC-32 constants.
*/
-SYM_FUNC_START(crc32_be_vgfm_16)
+u32 crc32_be_vgfm_16(u32 crc, unsigned char const *buf, size_t size)
+{
/* Load CRC-32 constants */
- larl %r5,constants_CRC_32_BE
- VLM CONST_R1R2,CONST_CRC_POLY,0,%r5
+ fpu_vlm(CONST_R1R2, CONST_CRC_POLY, &constants_CRC_32_BE);
+ fpu_vzero(0);
/* Load the initial CRC value into the leftmost word of V0. */
- VZERO %v0
- VLVGF %v0,%r2,0
+ fpu_vlvgf(0, crc, 0);
/* Load a 64-byte data chunk and XOR with CRC */
- VLM %v1,%v4,0,%r3 /* 64-bytes into V1..V4 */
- VX %v1,%v0,%v1 /* V1 ^= CRC */
- aghi %r3,64 /* BUF = BUF + 64 */
- aghi %r4,-64 /* LEN = LEN - 64 */
-
- /* Check remaining buffer size and jump to proper folding method */
- cghi %r4,64
- jl .Lless_than_64bytes
-
-.Lfold_64bytes_loop:
- /* Load the next 64-byte data chunk into V5 to V8 */
- VLM %v5,%v8,0,%r3
+ fpu_vlm(1, 4, buf);
+ fpu_vx(1, 0, 1);
+ buf += 64;
+ size -= 64;
+
+ while (size >= 64) {
+ /* Load the next 64-byte data chunk into V5 to V8 */
+ fpu_vlm(5, 8, buf);
+
+ /*
+ * Perform a GF(2) multiplication of the doublewords in V1 with
+ * the reduction constants in V0. The intermediate result is
+ * then folded (accumulated) with the next data chunk in V5 and
+ * stored in V1. Repeat this step for the register contents
+ * in V2, V3, and V4 respectively.
+ */
+ fpu_vgfmag(1, CONST_R1R2, 1, 5);
+ fpu_vgfmag(2, CONST_R1R2, 2, 6);
+ fpu_vgfmag(3, CONST_R1R2, 3, 7);
+ fpu_vgfmag(4, CONST_R1R2, 4, 8);
+ buf += 64;
+ size -= 64;
+ }
- /*
- * Perform a GF(2) multiplication of the doublewords in V1 with
- * the reduction constants in V0. The intermediate result is
- * then folded (accumulated) with the next data chunk in V5 and
- * stored in V1. Repeat this step for the register contents
- * in V2, V3, and V4 respectively.
- */
- VGFMAG %v1,CONST_R1R2,%v1,%v5
- VGFMAG %v2,CONST_R1R2,%v2,%v6
- VGFMAG %v3,CONST_R1R2,%v3,%v7
- VGFMAG %v4,CONST_R1R2,%v4,%v8
-
- /* Adjust buffer pointer and length for next loop */
- aghi %r3,64 /* BUF = BUF + 64 */
- aghi %r4,-64 /* LEN = LEN - 64 */
-
- cghi %r4,64
- jnl .Lfold_64bytes_loop
-
-.Lless_than_64bytes:
/* Fold V1 to V4 into a single 128-bit value in V1 */
- VGFMAG %v1,CONST_R3R4,%v1,%v2
- VGFMAG %v1,CONST_R3R4,%v1,%v3
- VGFMAG %v1,CONST_R3R4,%v1,%v4
-
- /* Check whether to continue with 64-bit folding */
- cghi %r4,16
- jl .Lfinal_fold
+ fpu_vgfmag(1, CONST_R3R4, 1, 2);
+ fpu_vgfmag(1, CONST_R3R4, 1, 3);
+ fpu_vgfmag(1, CONST_R3R4, 1, 4);
-.Lfold_16bytes_loop:
+ while (size >= 16) {
+ fpu_vl(2, buf);
+ fpu_vgfmag(1, CONST_R3R4, 1, 2);
+ buf += 16;
+ size -= 16;
+ }
- VL %v2,0,,%r3 /* Load next data chunk */
- VGFMAG %v1,CONST_R3R4,%v1,%v2 /* Fold next data chunk */
-
- /* Adjust buffer pointer and size for folding next data chunk */
- aghi %r3,16
- aghi %r4,-16
-
- /* Process remaining data chunks */
- cghi %r4,16
- jnl .Lfold_16bytes_loop
-
-.Lfinal_fold:
/*
* The R5 constant is used to fold a 128-bit value into an 96-bit value
* that is XORed with the next 96-bit input data chunk. To use a single
@@ -164,7 +130,7 @@ SYM_FUNC_START(crc32_be_vgfm_16)
* form an intermediate 96-bit value (with appended zeros) which is then
* XORed with the intermediate reduction result.
*/
- VGFMG %v1,CONST_R5,%v1
+ fpu_vgfmg(1, CONST_R5, 1);
/*
* Further reduce the remaining 96-bit value to a 64-bit value using a
@@ -173,7 +139,7 @@ SYM_FUNC_START(crc32_be_vgfm_16)
* doubleword with R6. The result is a 64-bit value and is subject to
* the Barret reduction.
*/
- VGFMG %v1,CONST_R6,%v1
+ fpu_vgfmg(1, CONST_R6, 1);
/*
* The input values to the Barret reduction are the degree-63 polynomial
@@ -194,20 +160,15 @@ SYM_FUNC_START(crc32_be_vgfm_16)
*/
/* T1(x) = floor( R(x) / x^32 ) GF2MUL u */
- VUPLLF %v2,%v1
- VGFMG %v2,CONST_RU_POLY,%v2
+ fpu_vupllf(2, 1);
+ fpu_vgfmg(2, CONST_RU_POLY, 2);
/*
* Compute the GF(2) product of the CRC polynomial in VO with T1(x) in
* V2 and XOR the intermediate result, T2(x), with the value in V1.
* The final result is in the rightmost word of V2.
*/
- VUPLLF %v2,%v2
- VGFMAG %v2,CONST_CRC_POLY,%v2,%v1
-
-.Ldone:
- VLGVF %r2,%v2,3
- BR_EX %r14
-SYM_FUNC_END(crc32_be_vgfm_16)
-
-.previous
+ fpu_vupllf(2, 2);
+ fpu_vgfmag(2, CONST_CRC_POLY, 2, 1);
+ return fpu_vlgvf(2, 3);
+}
diff --git a/arch/s390/crypto/crc32le-vx.S b/arch/s390/crypto/crc32le-vx.c
index 5a819ae09a0b..2f629f394df7 100644
--- a/arch/s390/crypto/crc32le-vx.S
+++ b/arch/s390/crypto/crc32le-vx.c
@@ -13,20 +13,17 @@
* Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
*/
-#include <linux/linkage.h>
-#include <asm/nospec-insn.h>
-#include <asm/vx-insn.h>
+#include <linux/types.h>
+#include <asm/fpu.h>
+#include "crc32-vx.h"
/* Vector register range containing CRC-32 constants */
-#define CONST_PERM_LE2BE %v9
-#define CONST_R2R1 %v10
-#define CONST_R4R3 %v11
-#define CONST_R5 %v12
-#define CONST_RU_POLY %v13
-#define CONST_CRC_POLY %v14
-
- .data
- .balign 8
+#define CONST_PERM_LE2BE 9
+#define CONST_R2R1 10
+#define CONST_R4R3 11
+#define CONST_R5 12
+#define CONST_RU_POLY 13
+#define CONST_CRC_POLY 14
/*
* The CRC-32 constant block contains reduction constants to fold and
@@ -59,64 +56,43 @@
* P'(x) = 0x82F63B78
*/
-SYM_DATA_START_LOCAL(constants_CRC_32_LE)
- .octa 0x0F0E0D0C0B0A09080706050403020100 # BE->LE mask
- .quad 0x1c6e41596, 0x154442bd4 # R2, R1
- .quad 0x0ccaa009e, 0x1751997d0 # R4, R3
- .octa 0x163cd6124 # R5
- .octa 0x1F7011641 # u'
- .octa 0x1DB710641 # P'(x) << 1
-SYM_DATA_END(constants_CRC_32_LE)
-
-SYM_DATA_START_LOCAL(constants_CRC_32C_LE)
- .octa 0x0F0E0D0C0B0A09080706050403020100 # BE->LE mask
- .quad 0x09e4addf8, 0x740eef02 # R2, R1
- .quad 0x14cd00bd6, 0xf20c0dfe # R4, R3
- .octa 0x0dd45aab8 # R5
- .octa 0x0dea713f1 # u'
- .octa 0x105ec76f0 # P'(x) << 1
-SYM_DATA_END(constants_CRC_32C_LE)
-
- .previous
-
- GEN_BR_THUNK %r14
-
- .text
-
-/*
- * The CRC-32 functions use these calling conventions:
- *
- * Parameters:
- *
- * %r2: Initial CRC value, typically ~0; and final CRC (return) value.
- * %r3: Input buffer pointer, performance might be improved if the
- * buffer is on a doubleword boundary.
- * %r4: Length of the buffer, must be 64 bytes or greater.
+static unsigned long constants_CRC_32_LE[] = {
+ 0x0f0e0d0c0b0a0908, 0x0706050403020100, /* BE->LE mask */
+ 0x1c6e41596, 0x154442bd4, /* R2, R1 */
+ 0x0ccaa009e, 0x1751997d0, /* R4, R3 */
+ 0x0, 0x163cd6124, /* R5 */
+ 0x0, 0x1f7011641, /* u' */
+ 0x0, 0x1db710641 /* P'(x) << 1 */
+};
+
+static unsigned long constants_CRC_32C_LE[] = {
+ 0x0f0e0d0c0b0a0908, 0x0706050403020100, /* BE->LE mask */
+ 0x09e4addf8, 0x740eef02, /* R2, R1 */
+ 0x14cd00bd6, 0xf20c0dfe, /* R4, R3 */
+ 0x0, 0x0dd45aab8, /* R5 */
+ 0x0, 0x0dea713f1, /* u' */
+ 0x0, 0x105ec76f0 /* P'(x) << 1 */
+};
+
+/**
+ * crc32_le_vgfm_generic - Compute CRC-32 (LE variant) with vector registers
+ * @crc: Initial CRC value, typically ~0.
+ * @buf: Input buffer pointer, performance might be improved if the
+ * buffer is on a doubleword boundary.
+ * @size: Size of the buffer, must be 64 bytes or greater.
+ * @constants: CRC-32 constant pool base pointer.
*
* Register usage:
- *
- * %r5: CRC-32 constant pool base pointer.
- * V0: Initial CRC value and intermediate constants and results.
- * V1..V4: Data for CRC computation.
- * V5..V8: Next data chunks that are fetched from the input buffer.
- * V9: Constant for BE->LE conversion and shift operations
- *
+ * V0: Initial CRC value and intermediate constants and results.
+ * V1..V4: Data for CRC computation.
+ * V5..V8: Next data chunks that are fetched from the input buffer.
+ * V9: Constant for BE->LE conversion and shift operations
* V10..V14: CRC-32 constants.
*/
-
-SYM_FUNC_START(crc32_le_vgfm_16)
- larl %r5,constants_CRC_32_LE
- j crc32_le_vgfm_generic
-SYM_FUNC_END(crc32_le_vgfm_16)
-
-SYM_FUNC_START(crc32c_le_vgfm_16)
- larl %r5,constants_CRC_32C_LE
- j crc32_le_vgfm_generic
-SYM_FUNC_END(crc32c_le_vgfm_16)
-
-SYM_FUNC_START(crc32_le_vgfm_generic)
+static u32 crc32_le_vgfm_generic(u32 crc, unsigned char const *buf, size_t size, unsigned long *constants)
+{
/* Load CRC-32 constants */
- VLM CONST_PERM_LE2BE,CONST_CRC_POLY,0,%r5
+ fpu_vlm(CONST_PERM_LE2BE, CONST_CRC_POLY, constants);
/*
* Load the initial CRC value.
@@ -125,90 +101,73 @@ SYM_FUNC_START(crc32_le_vgfm_generic)
* vector register and is later XORed with the LSB portion
* of the loaded input data.
*/
- VZERO %v0 /* Clear V0 */
- VLVGF %v0,%r2,3 /* Load CRC into rightmost word */
+ fpu_vzero(0); /* Clear V0 */
+ fpu_vlvgf(0, crc, 3); /* Load CRC into rightmost word */
/* Load a 64-byte data chunk and XOR with CRC */
- VLM %v1,%v4,0,%r3 /* 64-bytes into V1..V4 */
- VPERM %v1,%v1,%v1,CONST_PERM_LE2BE
- VPERM %v2,%v2,%v2,CONST_PERM_LE2BE
- VPERM %v3,%v3,%v3,CONST_PERM_LE2BE
- VPERM %v4,%v4,%v4,CONST_PERM_LE2BE
+ fpu_vlm(1, 4, buf);
+ fpu_vperm(1, 1, 1, CONST_PERM_LE2BE);
+ fpu_vperm(2, 2, 2, CONST_PERM_LE2BE);
+ fpu_vperm(3, 3, 3, CONST_PERM_LE2BE);
+ fpu_vperm(4, 4, 4, CONST_PERM_LE2BE);
+
+ fpu_vx(1, 0, 1); /* V1 ^= CRC */
+ buf += 64;
+ size -= 64;
+
+ while (size >= 64) {
+ fpu_vlm(5, 8, buf);
+ fpu_vperm(5, 5, 5, CONST_PERM_LE2BE);
+ fpu_vperm(6, 6, 6, CONST_PERM_LE2BE);
+ fpu_vperm(7, 7, 7, CONST_PERM_LE2BE);
+ fpu_vperm(8, 8, 8, CONST_PERM_LE2BE);
+ /*
+ * Perform a GF(2) multiplication of the doublewords in V1 with
+ * the R1 and R2 reduction constants in V0. The intermediate
+ * result is then folded (accumulated) with the next data chunk
+ * in V5 and stored in V1. Repeat this step for the register
+ * contents in V2, V3, and V4 respectively.
+ */
+ fpu_vgfmag(1, CONST_R2R1, 1, 5);
+ fpu_vgfmag(2, CONST_R2R1, 2, 6);
+ fpu_vgfmag(3, CONST_R2R1, 3, 7);
+ fpu_vgfmag(4, CONST_R2R1, 4, 8);
+ buf += 64;
+ size -= 64;
+ }
- VX %v1,%v0,%v1 /* V1 ^= CRC */
- aghi %r3,64 /* BUF = BUF + 64 */
- aghi %r4,-64 /* LEN = LEN - 64 */
-
- cghi %r4,64
- jl .Lless_than_64bytes
-
-.Lfold_64bytes_loop:
- /* Load the next 64-byte data chunk into V5 to V8 */
- VLM %v5,%v8,0,%r3
- VPERM %v5,%v5,%v5,CONST_PERM_LE2BE
- VPERM %v6,%v6,%v6,CONST_PERM_LE2BE
- VPERM %v7,%v7,%v7,CONST_PERM_LE2BE
- VPERM %v8,%v8,%v8,CONST_PERM_LE2BE
-
- /*
- * Perform a GF(2) multiplication of the doublewords in V1 with
- * the R1 and R2 reduction constants in V0. The intermediate result
- * is then folded (accumulated) with the next data chunk in V5 and
- * stored in V1. Repeat this step for the register contents
- * in V2, V3, and V4 respectively.
- */
- VGFMAG %v1,CONST_R2R1,%v1,%v5
- VGFMAG %v2,CONST_R2R1,%v2,%v6
- VGFMAG %v3,CONST_R2R1,%v3,%v7
- VGFMAG %v4,CONST_R2R1,%v4,%v8
-
- aghi %r3,64 /* BUF = BUF + 64 */
- aghi %r4,-64 /* LEN = LEN - 64 */
-
- cghi %r4,64
- jnl .Lfold_64bytes_loop
-
-.Lless_than_64bytes:
/*
* Fold V1 to V4 into a single 128-bit value in V1. Multiply V1 with R3
* and R4 and accumulating the next 128-bit chunk until a single 128-bit
* value remains.
*/
- VGFMAG %v1,CONST_R4R3,%v1,%v2
- VGFMAG %v1,CONST_R4R3,%v1,%v3
- VGFMAG %v1,CONST_R4R3,%v1,%v4
-
- cghi %r4,16
- jl .Lfinal_fold
-
-.Lfold_16bytes_loop:
-
- VL %v2,0,,%r3 /* Load next data chunk */
- VPERM %v2,%v2,%v2,CONST_PERM_LE2BE
- VGFMAG %v1,CONST_R4R3,%v1,%v2 /* Fold next data chunk */
+ fpu_vgfmag(1, CONST_R4R3, 1, 2);
+ fpu_vgfmag(1, CONST_R4R3, 1, 3);
+ fpu_vgfmag(1, CONST_R4R3, 1, 4);
+
+ while (size >= 16) {
+ fpu_vl(2, buf);
+ fpu_vperm(2, 2, 2, CONST_PERM_LE2BE);
+ fpu_vgfmag(1, CONST_R4R3, 1, 2);
+ buf += 16;
+ size -= 16;
+ }
- aghi %r3,16
- aghi %r4,-16
-
- cghi %r4,16
- jnl .Lfold_16bytes_loop
-
-.Lfinal_fold:
/*
* Set up a vector register for byte shifts. The shift value must
* be loaded in bits 1-4 in byte element 7 of a vector register.
* Shift by 8 bytes: 0x40
* Shift by 4 bytes: 0x20
*/
- VLEIB %v9,0x40,7
+ fpu_vleib(9, 0x40, 7);
/*
* Prepare V0 for the next GF(2) multiplication: shift V0 by 8 bytes
* to move R4 into the rightmost doubleword and set the leftmost
* doubleword to 0x1.
*/
- VSRLB %v0,CONST_R4R3,%v9
- VLEIG %v0,1,0
+ fpu_vsrlb(0, CONST_R4R3, 9);
+ fpu_vleig(0, 1, 0);
/*
* Compute GF(2) product of V1 and V0. The rightmost doubleword
@@ -216,7 +175,7 @@ SYM_FUNC_START(crc32_le_vgfm_generic)
* multiplied by 0x1 and is then XORed with rightmost product.
* Implicitly, the intermediate leftmost product becomes padded
*/
- VGFMG %v1,%v0,%v1
+ fpu_vgfmg(1, 0, 1);
/*
* Now do the final 32-bit fold by multiplying the rightmost word
@@ -231,10 +190,10 @@ SYM_FUNC_START(crc32_le_vgfm_generic)
* rightmost doubleword and the leftmost doubleword is zero to ignore
* the leftmost product of V1.
*/
- VLEIB %v9,0x20,7 /* Shift by words */
- VSRLB %v2,%v1,%v9 /* Store remaining bits in V2 */
- VUPLLF %v1,%v1 /* Split rightmost doubleword */
- VGFMAG %v1,CONST_R5,%v1,%v2 /* V1 = (V1 * R5) XOR V2 */
+ fpu_vleib(9, 0x20, 7); /* Shift by words */
+ fpu_vsrlb(2, 1, 9); /* Store remaining bits in V2 */
+ fpu_vupllf(1, 1); /* Split rightmost doubleword */
+ fpu_vgfmag(1, CONST_R5, 1, 2); /* V1 = (V1 * R5) XOR V2 */
/*
* Apply a Barret reduction to compute the final 32-bit CRC value.
@@ -256,20 +215,26 @@ SYM_FUNC_START(crc32_le_vgfm_generic)
*/
/* T1(x) = floor( R(x) / x^32 ) GF2MUL u */
- VUPLLF %v2,%v1
- VGFMG %v2,CONST_RU_POLY,%v2
+ fpu_vupllf(2, 1);
+ fpu_vgfmg(2, CONST_RU_POLY, 2);
/*
* Compute the GF(2) product of the CRC polynomial with T1(x) in
* V2 and XOR the intermediate result, T2(x), with the value in V1.
* The final result is stored in word element 2 of V2.
*/
- VUPLLF %v2,%v2
- VGFMAG %v2,CONST_CRC_POLY,%v2,%v1
+ fpu_vupllf(2, 2);
+ fpu_vgfmag(2, CONST_CRC_POLY, 2, 1);
+
+ return fpu_vlgvf(2, 2);
+}
-.Ldone:
- VLGVF %r2,%v2,2
- BR_EX %r14
-SYM_FUNC_END(crc32_le_vgfm_generic)
+u32 crc32_le_vgfm_16(u32 crc, unsigned char const *buf, size_t size)
+{
+ return crc32_le_vgfm_generic(crc, buf, size, &constants_CRC_32_LE[0]);
+}
-.previous
+u32 crc32c_le_vgfm_16(u32 crc, unsigned char const *buf, size_t size)
+{
+ return crc32_le_vgfm_generic(crc, buf, size, &constants_CRC_32C_LE[0]);
+}
diff --git a/arch/s390/crypto/paes_s390.c b/arch/s390/crypto/paes_s390.c
index 55ee5567a5ea..99f7e1f2b70a 100644
--- a/arch/s390/crypto/paes_s390.c
+++ b/arch/s390/crypto/paes_s390.c
@@ -125,20 +125,8 @@ struct s390_pxts_ctx {
static inline int __paes_keyblob2pkey(struct key_blob *kb,
struct pkey_protkey *pk)
{
- int i, ret;
-
- /* try three times in case of failure */
- for (i = 0; i < 3; i++) {
- if (i > 0 && ret == -EAGAIN && in_task())
- if (msleep_interruptible(1000))
- return -EINTR;
- ret = pkey_keyblob2pkey(kb->key, kb->keylen,
- pk->protkey, &pk->len, &pk->type);
- if (ret == 0)
- break;
- }
-
- return ret;
+ return pkey_keyblob2pkey(kb->key, kb->keylen,
+ pk->protkey, &pk->len, &pk->type);
}
static inline int __paes_convert_key(struct s390_paes_ctx *ctx)
diff --git a/arch/s390/hypfs/hypfs_diag0c.c b/arch/s390/hypfs/hypfs_diag0c.c
index 9a2786079e3a..4131f0daa5ea 100644
--- a/arch/s390/hypfs/hypfs_diag0c.c
+++ b/arch/s390/hypfs/hypfs_diag0c.c
@@ -20,8 +20,7 @@
*/
static void diag0c_fn(void *data)
{
- diag_stat_inc(DIAG_STAT_X00C);
- diag_amode31_ops.diag0c(((void **)data)[smp_processor_id()]);
+ diag0c(((void **)data)[smp_processor_id()]);
}
/*
diff --git a/arch/s390/hypfs/hypfs_sprp.c b/arch/s390/hypfs/hypfs_sprp.c
index f5f7e78ddc0c..9fc3f0dae8f0 100644
--- a/arch/s390/hypfs/hypfs_sprp.c
+++ b/arch/s390/hypfs/hypfs_sprp.c
@@ -25,7 +25,7 @@
static inline unsigned long __hypfs_sprp_diag304(void *data, unsigned long cmd)
{
- union register_pair r1 = { .even = (unsigned long)data, };
+ union register_pair r1 = { .even = virt_to_phys(data), };
asm volatile("diag %[r1],%[r3],0x304\n"
: [r1] "+&d" (r1.pair)
@@ -74,7 +74,7 @@ static int __hypfs_sprp_ioctl(void __user *user_area)
int rc;
rc = -ENOMEM;
- data = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
+ data = (void *)get_zeroed_page(GFP_KERNEL);
diag304 = kzalloc(sizeof(*diag304), GFP_KERNEL);
if (!data || !diag304)
goto out;
diff --git a/arch/s390/include/asm/access-regs.h b/arch/s390/include/asm/access-regs.h
new file mode 100644
index 000000000000..1a6412d9f5ad
--- /dev/null
+++ b/arch/s390/include/asm/access-regs.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright IBM Corp. 1999, 2024
+ */
+
+#ifndef __ASM_S390_ACCESS_REGS_H
+#define __ASM_S390_ACCESS_REGS_H
+
+#include <linux/instrumented.h>
+#include <asm/sigcontext.h>
+
+struct access_regs {
+ unsigned int regs[NUM_ACRS];
+};
+
+static inline void save_access_regs(unsigned int *acrs)
+{
+ struct access_regs *regs = (struct access_regs *)acrs;
+
+ instrument_write(regs, sizeof(*regs));
+ asm volatile("stamy 0,15,%[regs]"
+ : [regs] "=QS" (*regs)
+ :
+ : "memory");
+}
+
+static inline void restore_access_regs(unsigned int *acrs)
+{
+ struct access_regs *regs = (struct access_regs *)acrs;
+
+ instrument_read(regs, sizeof(*regs));
+ asm volatile("lamy 0,15,%[regs]"
+ :
+ : [regs] "QS" (*regs)
+ : "memory");
+}
+
+#endif /* __ASM_S390_ACCESS_REGS_H */
diff --git a/arch/s390/include/asm/appldata.h b/arch/s390/include/asm/appldata.h
index f2240392c708..a92ebbc7aa7a 100644
--- a/arch/s390/include/asm/appldata.h
+++ b/arch/s390/include/asm/appldata.h
@@ -54,13 +54,13 @@ static inline int appldata_asm(struct appldata_parameter_list *parm_list,
parm_list->function = fn;
parm_list->parlist_length = sizeof(*parm_list);
parm_list->buffer_length = length;
- parm_list->product_id_addr = (unsigned long) id;
+ parm_list->product_id_addr = virt_to_phys(id);
parm_list->buffer_addr = virt_to_phys(buffer);
diag_stat_inc(DIAG_STAT_X0DC);
asm volatile(
" diag %1,%0,0xdc"
: "=d" (ry)
- : "d" (parm_list), "m" (*parm_list), "m" (*id)
+ : "d" (virt_to_phys(parm_list)), "m" (*parm_list), "m" (*id)
: "cc");
return ry;
}
diff --git a/arch/s390/include/asm/asm-prototypes.h b/arch/s390/include/asm/asm-prototypes.h
index a873e873e1ee..56096ae26f29 100644
--- a/arch/s390/include/asm/asm-prototypes.h
+++ b/arch/s390/include/asm/asm-prototypes.h
@@ -3,7 +3,7 @@
#include <linux/kvm_host.h>
#include <linux/ftrace.h>
-#include <asm/fpu/api.h>
+#include <asm/fpu.h>
#include <asm-generic/asm-prototypes.h>
__int128_t __ashlti3(__int128_t a, int b);
diff --git a/arch/s390/include/asm/atomic.h b/arch/s390/include/asm/atomic.h
index 7138d189cc42..0c4cad7d5a5b 100644
--- a/arch/s390/include/asm/atomic.h
+++ b/arch/s390/include/asm/atomic.h
@@ -15,31 +15,31 @@
#include <asm/barrier.h>
#include <asm/cmpxchg.h>
-static inline int arch_atomic_read(const atomic_t *v)
+static __always_inline int arch_atomic_read(const atomic_t *v)
{
return __atomic_read(v);
}
#define arch_atomic_read arch_atomic_read
-static inline void arch_atomic_set(atomic_t *v, int i)
+static __always_inline void arch_atomic_set(atomic_t *v, int i)
{
__atomic_set(v, i);
}
#define arch_atomic_set arch_atomic_set
-static inline int arch_atomic_add_return(int i, atomic_t *v)
+static __always_inline int arch_atomic_add_return(int i, atomic_t *v)
{
return __atomic_add_barrier(i, &v->counter) + i;
}
#define arch_atomic_add_return arch_atomic_add_return
-static inline int arch_atomic_fetch_add(int i, atomic_t *v)
+static __always_inline int arch_atomic_fetch_add(int i, atomic_t *v)
{
return __atomic_add_barrier(i, &v->counter);
}
#define arch_atomic_fetch_add arch_atomic_fetch_add
-static inline void arch_atomic_add(int i, atomic_t *v)
+static __always_inline void arch_atomic_add(int i, atomic_t *v)
{
__atomic_add(i, &v->counter);
}
@@ -50,11 +50,11 @@ static inline void arch_atomic_add(int i, atomic_t *v)
#define arch_atomic_fetch_sub(_i, _v) arch_atomic_fetch_add(-(int)(_i), _v)
#define ATOMIC_OPS(op) \
-static inline void arch_atomic_##op(int i, atomic_t *v) \
+static __always_inline void arch_atomic_##op(int i, atomic_t *v) \
{ \
__atomic_##op(i, &v->counter); \
} \
-static inline int arch_atomic_fetch_##op(int i, atomic_t *v) \
+static __always_inline int arch_atomic_fetch_##op(int i, atomic_t *v) \
{ \
return __atomic_##op##_barrier(i, &v->counter); \
}
@@ -74,7 +74,7 @@ ATOMIC_OPS(xor)
#define arch_atomic_xchg(v, new) (arch_xchg(&((v)->counter), new))
-static inline int arch_atomic_cmpxchg(atomic_t *v, int old, int new)
+static __always_inline int arch_atomic_cmpxchg(atomic_t *v, int old, int new)
{
return __atomic_cmpxchg(&v->counter, old, new);
}
@@ -82,31 +82,31 @@ static inline int arch_atomic_cmpxchg(atomic_t *v, int old, int new)
#define ATOMIC64_INIT(i) { (i) }
-static inline s64 arch_atomic64_read(const atomic64_t *v)
+static __always_inline s64 arch_atomic64_read(const atomic64_t *v)
{
return __atomic64_read(v);
}
#define arch_atomic64_read arch_atomic64_read
-static inline void arch_atomic64_set(atomic64_t *v, s64 i)
+static __always_inline void arch_atomic64_set(atomic64_t *v, s64 i)
{
__atomic64_set(v, i);
}
#define arch_atomic64_set arch_atomic64_set
-static inline s64 arch_atomic64_add_return(s64 i, atomic64_t *v)
+static __always_inline s64 arch_atomic64_add_return(s64 i, atomic64_t *v)
{
return __atomic64_add_barrier(i, (long *)&v->counter) + i;
}
#define arch_atomic64_add_return arch_atomic64_add_return
-static inline s64 arch_atomic64_fetch_add(s64 i, atomic64_t *v)
+static __always_inline s64 arch_atomic64_fetch_add(s64 i, atomic64_t *v)
{
return __atomic64_add_barrier(i, (long *)&v->counter);
}
#define arch_atomic64_fetch_add arch_atomic64_fetch_add
-static inline void arch_atomic64_add(s64 i, atomic64_t *v)
+static __always_inline void arch_atomic64_add(s64 i, atomic64_t *v)
{
__atomic64_add(i, (long *)&v->counter);
}
@@ -114,20 +114,20 @@ static inline void arch_atomic64_add(s64 i, atomic64_t *v)
#define arch_atomic64_xchg(v, new) (arch_xchg(&((v)->counter), new))
-static inline s64 arch_atomic64_cmpxchg(atomic64_t *v, s64 old, s64 new)
+static __always_inline s64 arch_atomic64_cmpxchg(atomic64_t *v, s64 old, s64 new)
{
return __atomic64_cmpxchg((long *)&v->counter, old, new);
}
#define arch_atomic64_cmpxchg arch_atomic64_cmpxchg
-#define ATOMIC64_OPS(op) \
-static inline void arch_atomic64_##op(s64 i, atomic64_t *v) \
-{ \
- __atomic64_##op(i, (long *)&v->counter); \
-} \
-static inline long arch_atomic64_fetch_##op(s64 i, atomic64_t *v) \
-{ \
- return __atomic64_##op##_barrier(i, (long *)&v->counter); \
+#define ATOMIC64_OPS(op) \
+static __always_inline void arch_atomic64_##op(s64 i, atomic64_t *v) \
+{ \
+ __atomic64_##op(i, (long *)&v->counter); \
+} \
+static __always_inline long arch_atomic64_fetch_##op(s64 i, atomic64_t *v) \
+{ \
+ return __atomic64_##op##_barrier(i, (long *)&v->counter); \
}
ATOMIC64_OPS(and)
diff --git a/arch/s390/include/asm/atomic_ops.h b/arch/s390/include/asm/atomic_ops.h
index 50510e08b893..7fa5f96a553a 100644
--- a/arch/s390/include/asm/atomic_ops.h
+++ b/arch/s390/include/asm/atomic_ops.h
@@ -8,7 +8,7 @@
#ifndef __ARCH_S390_ATOMIC_OPS__
#define __ARCH_S390_ATOMIC_OPS__
-static inline int __atomic_read(const atomic_t *v)
+static __always_inline int __atomic_read(const atomic_t *v)
{
int c;
@@ -18,14 +18,14 @@ static inline int __atomic_read(const atomic_t *v)
return c;
}
-static inline void __atomic_set(atomic_t *v, int i)
+static __always_inline void __atomic_set(atomic_t *v, int i)
{
asm volatile(
" st %1,%0\n"
: "=R" (v->counter) : "d" (i));
}
-static inline s64 __atomic64_read(const atomic64_t *v)
+static __always_inline s64 __atomic64_read(const atomic64_t *v)
{
s64 c;
@@ -35,7 +35,7 @@ static inline s64 __atomic64_read(const atomic64_t *v)
return c;
}
-static inline void __atomic64_set(atomic64_t *v, s64 i)
+static __always_inline void __atomic64_set(atomic64_t *v, s64 i)
{
asm volatile(
" stg %1,%0\n"
@@ -45,7 +45,7 @@ static inline void __atomic64_set(atomic64_t *v, s64 i)
#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES
#define __ATOMIC_OP(op_name, op_type, op_string, op_barrier) \
-static inline op_type op_name(op_type val, op_type *ptr) \
+static __always_inline op_type op_name(op_type val, op_type *ptr) \
{ \
op_type old; \
\
@@ -96,7 +96,7 @@ __ATOMIC_CONST_OPS(__atomic64_add_const, long, "agsi")
#else /* CONFIG_HAVE_MARCH_Z196_FEATURES */
#define __ATOMIC_OP(op_name, op_string) \
-static inline int op_name(int val, int *ptr) \
+static __always_inline int op_name(int val, int *ptr) \
{ \
int old, new; \
\
@@ -122,7 +122,7 @@ __ATOMIC_OPS(__atomic_xor, "xr")
#undef __ATOMIC_OPS
#define __ATOMIC64_OP(op_name, op_string) \
-static inline long op_name(long val, long *ptr) \
+static __always_inline long op_name(long val, long *ptr) \
{ \
long old, new; \
\
@@ -154,7 +154,7 @@ __ATOMIC64_OPS(__atomic64_xor, "xgr")
#endif /* CONFIG_HAVE_MARCH_Z196_FEATURES */
-static inline int __atomic_cmpxchg(int *ptr, int old, int new)
+static __always_inline int __atomic_cmpxchg(int *ptr, int old, int new)
{
asm volatile(
" cs %[old],%[new],%[ptr]"
@@ -164,7 +164,7 @@ static inline int __atomic_cmpxchg(int *ptr, int old, int new)
return old;
}
-static inline bool __atomic_cmpxchg_bool(int *ptr, int old, int new)
+static __always_inline bool __atomic_cmpxchg_bool(int *ptr, int old, int new)
{
int old_expected = old;
@@ -176,7 +176,7 @@ static inline bool __atomic_cmpxchg_bool(int *ptr, int old, int new)
return old == old_expected;
}
-static inline long __atomic64_cmpxchg(long *ptr, long old, long new)
+static __always_inline long __atomic64_cmpxchg(long *ptr, long old, long new)
{
asm volatile(
" csg %[old],%[new],%[ptr]"
@@ -186,7 +186,7 @@ static inline long __atomic64_cmpxchg(long *ptr, long old, long new)
return old;
}
-static inline bool __atomic64_cmpxchg_bool(long *ptr, long old, long new)
+static __always_inline bool __atomic64_cmpxchg_bool(long *ptr, long old, long new)
{
long old_expected = old;
diff --git a/arch/s390/include/asm/bug.h b/arch/s390/include/asm/bug.h
index aebe1e22c7be..c500d45fb465 100644
--- a/arch/s390/include/asm/bug.h
+++ b/arch/s390/include/asm/bug.h
@@ -14,7 +14,7 @@
".section .rodata.str,\"aMS\",@progbits,1\n" \
"1: .asciz \""__FILE__"\"\n" \
".previous\n" \
- ".section __bug_table,\"awM\",@progbits,%2\n" \
+ ".section __bug_table,\"aw\"\n" \
"2: .long 0b-.\n" \
" .long 1b-.\n" \
" .short %0,%1\n" \
@@ -30,7 +30,7 @@
#define __EMIT_BUG(x) do { \
asm_inline volatile( \
"0: mc 0,0\n" \
- ".section __bug_table,\"awM\",@progbits,%1\n" \
+ ".section __bug_table,\"aw\"\n" \
"1: .long 0b-.\n" \
" .short %0\n" \
" .org 1b+%1\n" \
diff --git a/arch/s390/include/asm/ccwdev.h b/arch/s390/include/asm/ccwdev.h
index 91d261751d25..436365ff6c19 100644
--- a/arch/s390/include/asm/ccwdev.h
+++ b/arch/s390/include/asm/ccwdev.h
@@ -217,7 +217,8 @@ extern void ccw_device_destroy_console(struct ccw_device *);
extern int ccw_device_enable_console(struct ccw_device *);
extern void ccw_device_wait_idle(struct ccw_device *);
-extern void *ccw_device_dma_zalloc(struct ccw_device *cdev, size_t size);
+extern void *ccw_device_dma_zalloc(struct ccw_device *cdev, size_t size,
+ dma32_t *dma_handle);
extern void ccw_device_dma_free(struct ccw_device *cdev,
void *cpu_addr, size_t size);
diff --git a/arch/s390/include/asm/checksum.h b/arch/s390/include/asm/checksum.h
index 69837eec2ff5..b89159591ca0 100644
--- a/arch/s390/include/asm/checksum.h
+++ b/arch/s390/include/asm/checksum.h
@@ -12,36 +12,29 @@
#ifndef _S390_CHECKSUM_H
#define _S390_CHECKSUM_H
-#include <linux/kasan-checks.h>
+#include <linux/instrumented.h>
#include <linux/in6.h>
-/*
- * Computes the checksum of a memory block at buff, length len,
- * and adds in "sum" (32-bit).
- *
- * Returns a 32-bit number suitable for feeding into itself
- * or csum_tcpudp_magic.
- *
- * This function must be called with even lengths, except
- * for the last fragment, which may be odd.
- *
- * It's best to have buff aligned on a 32-bit boundary.
- */
-static inline __wsum csum_partial(const void *buff, int len, __wsum sum)
+static inline __wsum cksm(const void *buff, int len, __wsum sum)
{
union register_pair rp = {
- .even = (unsigned long) buff,
- .odd = (unsigned long) len,
+ .even = (unsigned long)buff,
+ .odd = (unsigned long)len,
};
- kasan_check_read(buff, len);
- asm volatile(
+ instrument_read(buff, len);
+ asm volatile("\n"
"0: cksm %[sum],%[rp]\n"
" jo 0b\n"
: [sum] "+&d" (sum), [rp] "+&d" (rp.pair) : : "cc", "memory");
return sum;
}
+__wsum csum_partial(const void *buff, int len, __wsum sum);
+
+#define _HAVE_ARCH_CSUM_AND_COPY
+__wsum csum_partial_copy_nocheck(const void *src, void *dst, int len);
+
/*
* Fold a partial checksum without adding pseudo headers.
*/
diff --git a/arch/s390/include/asm/cio.h b/arch/s390/include/asm/cio.h
index 1c4f585dd39b..b6b619f340a5 100644
--- a/arch/s390/include/asm/cio.h
+++ b/arch/s390/include/asm/cio.h
@@ -7,6 +7,7 @@
#include <linux/bitops.h>
#include <linux/genalloc.h>
+#include <asm/dma-types.h>
#include <asm/types.h>
#include <asm/tpi.h>
@@ -32,7 +33,7 @@ struct ccw1 {
__u8 cmd_code;
__u8 flags;
__u16 count;
- __u32 cda;
+ dma32_t cda;
} __attribute__ ((packed,aligned(8)));
/**
@@ -152,8 +153,8 @@ struct sublog {
struct esw0 {
struct sublog sublog;
struct erw erw;
- __u32 faddr[2];
- __u32 saddr;
+ dma32_t faddr[2];
+ dma32_t saddr;
} __attribute__ ((packed));
/**
@@ -364,6 +365,8 @@ extern struct device *cio_get_dma_css_dev(void);
void *cio_gp_dma_zalloc(struct gen_pool *gp_dma, struct device *dma_dev,
size_t size);
+void *__cio_gp_dma_zalloc(struct gen_pool *gp_dma, struct device *dma_dev,
+ size_t size, dma32_t *dma_handle);
void cio_gp_dma_free(struct gen_pool *gp_dma, void *cpu_addr, size_t size);
void cio_gp_dma_destroy(struct gen_pool *gp_dma, struct device *dma_dev);
struct gen_pool *cio_gp_dma_create(struct device *dma_dev, int nr_pages);
diff --git a/arch/s390/include/asm/diag.h b/arch/s390/include/asm/diag.h
index bed804137537..20b94220113b 100644
--- a/arch/s390/include/asm/diag.h
+++ b/arch/s390/include/asm/diag.h
@@ -44,6 +44,13 @@ enum diag_stat_enum {
void diag_stat_inc(enum diag_stat_enum nr);
void diag_stat_inc_norecursion(enum diag_stat_enum nr);
+struct hypfs_diag0c_entry;
+
+/*
+ * Diagnose 0c: Pseudo Timer
+ */
+void diag0c(struct hypfs_diag0c_entry *data);
+
/*
* Diagnose 10: Release page range
*/
@@ -331,10 +338,10 @@ struct hypfs_diag0c_entry;
*/
struct diag_ops {
int (*diag210)(struct diag210 *addr);
- int (*diag26c)(void *req, void *resp, enum diag26c_sc subcode);
+ int (*diag26c)(unsigned long rx, unsigned long rx1, enum diag26c_sc subcode);
int (*diag14)(unsigned long rx, unsigned long ry1, unsigned long subcode);
int (*diag8c)(struct diag8c *addr, struct ccw_dev_id *devno, size_t len);
- void (*diag0c)(struct hypfs_diag0c_entry *entry);
+ void (*diag0c)(unsigned long rx);
void (*diag308_reset)(void);
};
@@ -342,9 +349,9 @@ extern struct diag_ops diag_amode31_ops;
extern struct diag210 *__diag210_tmp_amode31;
int _diag210_amode31(struct diag210 *addr);
-int _diag26c_amode31(void *req, void *resp, enum diag26c_sc subcode);
+int _diag26c_amode31(unsigned long rx, unsigned long rx1, enum diag26c_sc subcode);
int _diag14_amode31(unsigned long rx, unsigned long ry1, unsigned long subcode);
-void _diag0c_amode31(struct hypfs_diag0c_entry *entry);
+void _diag0c_amode31(unsigned long rx);
void _diag308_reset_amode31(void);
int _diag8c_amode31(struct diag8c *addr, struct ccw_dev_id *devno, size_t len);
diff --git a/arch/s390/include/asm/dma-types.h b/arch/s390/include/asm/dma-types.h
new file mode 100644
index 000000000000..5c5734e6946c
--- /dev/null
+++ b/arch/s390/include/asm/dma-types.h
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _ASM_S390_DMA_TYPES_H_
+#define _ASM_S390_DMA_TYPES_H_
+
+#include <linux/types.h>
+#include <linux/io.h>
+
+/*
+ * typedef dma32_t
+ * Contains a 31 bit absolute address to a DMA capable piece of storage.
+ *
+ * For CIO, DMA addresses are always absolute addresses. These addresses tend
+ * to be used in architectured memory blocks (like ORB, IDAW, MIDAW). Under
+ * certain circumstances 31 bit wide addresses must be used because the
+ * address must fit in 31 bits.
+ *
+ * This type is to be used when such fields can be modelled as 32 bit wide.
+ */
+typedef u32 __bitwise dma32_t;
+
+/*
+ * typedef dma64_t
+ * Contains a 64 bit absolute address to a DMA capable piece of storage.
+ *
+ * For CIO, DMA addresses are always absolute addresses. These addresses tend
+ * to be used in architectured memory blocks (like ORB, IDAW, MIDAW).
+ *
+ * This type is to be used to model such 64 bit wide fields.
+ */
+typedef u64 __bitwise dma64_t;
+
+/*
+ * Although DMA addresses should be obtained using the DMA API, in cases when
+ * it is known that the first argument holds a virtual address that points to
+ * DMA-able 31 bit addressable storage, then this function can be safely used.
+ */
+static inline dma32_t virt_to_dma32(void *ptr)
+{
+ return (__force dma32_t)__pa32(ptr);
+}
+
+static inline void *dma32_to_virt(dma32_t addr)
+{
+ return __va((__force unsigned long)addr);
+}
+
+static inline dma32_t u32_to_dma32(u32 addr)
+{
+ return (__force dma32_t)addr;
+}
+
+static inline u32 dma32_to_u32(dma32_t addr)
+{
+ return (__force u32)addr;
+}
+
+static inline dma32_t dma32_add(dma32_t a, u32 b)
+{
+ return (__force dma32_t)((__force u32)a + b);
+}
+
+static inline dma32_t dma32_and(dma32_t a, u32 b)
+{
+ return (__force dma32_t)((__force u32)a & b);
+}
+
+/*
+ * Although DMA addresses should be obtained using the DMA API, in cases when
+ * it is known that the first argument holds a virtual address that points to
+ * DMA-able storage, then this function can be safely used.
+ */
+static inline dma64_t virt_to_dma64(void *ptr)
+{
+ return (__force dma64_t)__pa(ptr);
+}
+
+static inline void *dma64_to_virt(dma64_t addr)
+{
+ return __va((__force unsigned long)addr);
+}
+
+static inline dma64_t u64_to_dma64(u64 addr)
+{
+ return (__force dma64_t)addr;
+}
+
+static inline u64 dma64_to_u64(dma64_t addr)
+{
+ return (__force u64)addr;
+}
+
+static inline dma64_t dma64_add(dma64_t a, u64 b)
+{
+ return (__force dma64_t)((__force u64)a + b);
+}
+
+static inline dma64_t dma64_and(dma64_t a, u64 b)
+{
+ return (__force dma64_t)((__force u64)a & b);
+}
+
+#endif /* _ASM_S390_DMA_TYPES_H_ */
diff --git a/arch/s390/include/asm/eadm.h b/arch/s390/include/asm/eadm.h
index 06f795855af7..c4589ec4505e 100644
--- a/arch/s390/include/asm/eadm.h
+++ b/arch/s390/include/asm/eadm.h
@@ -5,6 +5,7 @@
#include <linux/types.h>
#include <linux/device.h>
#include <linux/blk_types.h>
+#include <asm/dma-types.h>
struct arqb {
u64 data;
@@ -45,7 +46,7 @@ struct msb {
u16:12;
u16 bs:4;
u32 blk_count;
- u64 data_addr;
+ dma64_t data_addr;
u64 scm_addr;
u64:64;
} __packed;
@@ -54,7 +55,7 @@ struct aidaw {
u8 flags;
u32 :24;
u32 :32;
- u64 data_addr;
+ dma64_t data_addr;
} __packed;
#define MSB_OC_CLEAR 0
diff --git a/arch/s390/include/asm/entry-common.h b/arch/s390/include/asm/entry-common.h
index fdd319a622b0..7f5004065e8a 100644
--- a/arch/s390/include/asm/entry-common.h
+++ b/arch/s390/include/asm/entry-common.h
@@ -8,7 +8,7 @@
#include <linux/processor.h>
#include <linux/uaccess.h>
#include <asm/timex.h>
-#include <asm/fpu/api.h>
+#include <asm/fpu.h>
#include <asm/pai.h>
#define ARCH_EXIT_TO_USER_MODE_WORK (_TIF_GUARDED_STORAGE | _TIF_PER_TRAP)
@@ -41,8 +41,7 @@ static __always_inline void arch_exit_to_user_mode_work(struct pt_regs *regs,
static __always_inline void arch_exit_to_user_mode(void)
{
- if (test_cpu_flag(CIF_FPU))
- __load_fpu_regs();
+ load_user_fpu_regs();
if (IS_ENABLED(CONFIG_DEBUG_ENTRY))
debug_user_asce(1);
diff --git a/arch/s390/include/asm/fcx.h b/arch/s390/include/asm/fcx.h
index 29784b4b44f6..80f82a739b45 100644
--- a/arch/s390/include/asm/fcx.h
+++ b/arch/s390/include/asm/fcx.h
@@ -10,6 +10,7 @@
#define _ASM_S390_FCX_H
#include <linux/types.h>
+#include <asm/dma-types.h>
#define TCW_FORMAT_DEFAULT 0
#define TCW_TIDAW_FORMAT_DEFAULT 0
@@ -43,16 +44,16 @@ struct tcw {
u32 r:1;
u32 w:1;
u32 :16;
- u64 output;
- u64 input;
- u64 tsb;
- u64 tccb;
+ dma64_t output;
+ dma64_t input;
+ dma64_t tsb;
+ dma64_t tccb;
u32 output_count;
u32 input_count;
u32 :32;
u32 :32;
u32 :32;
- u32 intrg;
+ dma32_t intrg;
} __attribute__ ((packed, aligned(64)));
#define TIDAW_FLAGS_LAST (1 << (7 - 0))
@@ -73,7 +74,7 @@ struct tidaw {
u32 flags:8;
u32 :24;
u32 count;
- u64 addr;
+ dma64_t addr;
} __attribute__ ((packed, aligned(16)));
/**
diff --git a/arch/s390/include/asm/vx-insn-asm.h b/arch/s390/include/asm/fpu-insn-asm.h
index 360f8b36d962..02ccfe46050a 100644
--- a/arch/s390/include/asm/vx-insn-asm.h
+++ b/arch/s390/include/asm/fpu-insn-asm.h
@@ -9,11 +9,11 @@
* Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
*/
-#ifndef __ASM_S390_VX_INSN_INTERNAL_H
-#define __ASM_S390_VX_INSN_INTERNAL_H
+#ifndef __ASM_S390_FPU_INSN_ASM_H
+#define __ASM_S390_FPU_INSN_ASM_H
-#ifndef __ASM_S390_VX_INSN_H
-#error only <asm/vx-insn.h> can be included directly
+#ifndef __ASM_S390_FPU_INSN_H
+#error only <asm/fpu-insn.h> can be included directly
#endif
#ifdef __ASSEMBLY__
@@ -195,10 +195,26 @@
/* RXB - Compute most significant bit used vector registers
*
* @rxb: Operand to store computed RXB value
- * @v1: First vector register designated operand
- * @v2: Second vector register designated operand
- * @v3: Third vector register designated operand
- * @v4: Fourth vector register designated operand
+ * @v1: Vector register designated operand whose MSB is stored in
+ * RXB bit 0 (instruction bit 36) and whose remaining bits
+ * are stored in instruction bits 8-11.
+ * @v2: Vector register designated operand whose MSB is stored in
+ * RXB bit 1 (instruction bit 37) and whose remaining bits
+ * are stored in instruction bits 12-15.
+ * @v3: Vector register designated operand whose MSB is stored in
+ * RXB bit 2 (instruction bit 38) and whose remaining bits
+ * are stored in instruction bits 16-19.
+ * @v4: Vector register designated operand whose MSB is stored in
+ * RXB bit 3 (instruction bit 39) and whose remaining bits
+ * are stored in instruction bits 32-35.
+ *
+ * Note: In most vector instruction formats [1] V1, V2, V3, and V4 directly
+ * correspond to @v1, @v2, @v3, and @v4. But there are exceptions, such as but
+ * not limited to the vector instruction formats VRR-g, VRR-h, VRS-a, VRS-d,
+ * and VSI.
+ *
+ * [1] IBM z/Architecture Principles of Operation, chapter "Program
+ * Execution, section "Instructions", subsection "Instruction Formats".
*/
.macro RXB rxb v1 v2=0 v3=0 v4=0
\rxb = 0
@@ -223,6 +239,9 @@
* @v2: Second vector register designated operand (for RXB)
* @v3: Third vector register designated operand (for RXB)
* @v4: Fourth vector register designated operand (for RXB)
+ *
+ * Note: For @v1, @v2, @v3, and @v4 also refer to the RXB macro
+ * description for further details.
*/
.macro MRXB m v1 v2=0 v3=0 v4=0
rxb = 0
@@ -238,6 +257,9 @@
* @v2: Second vector register designated operand (for RXB)
* @v3: Third vector register designated operand (for RXB)
* @v4: Fourth vector register designated operand (for RXB)
+ *
+ * Note: For @v1, @v2, @v3, and @v4 also refer to the RXB macro
+ * description for further details.
*/
.macro MRXBOPC m opc v1 v2=0 v3=0 v4=0
MRXB \m, \v1, \v2, \v3, \v4
@@ -350,7 +372,7 @@
VX_NUM v3, \vr
.word 0xE700 | (r1 << 4) | (v3&15)
.word (b2 << 12) | (\disp)
- MRXBOPC \m, 0x21, v3
+ MRXBOPC \m, 0x21, 0, v3
.endm
.macro VLGVB gr, vr, disp, base="%r0"
VLGV \gr, \vr, \disp, \base, 0
@@ -499,6 +521,25 @@
VMRL \vr1, \vr2, \vr3, 3
.endm
+/* VECTOR LOAD WITH LENGTH */
+.macro VLL v, gr, disp, base
+ VX_NUM v1, \v
+ GR_NUM b2, \base
+ GR_NUM r3, \gr
+ .word 0xE700 | ((v1&15) << 4) | r3
+ .word (b2 << 12) | (\disp)
+ MRXBOPC 0, 0x37, v1
+.endm
+
+/* VECTOR STORE WITH LENGTH */
+.macro VSTL v, gr, disp, base
+ VX_NUM v1, \v
+ GR_NUM b2, \base
+ GR_NUM r3, \gr
+ .word 0xE700 | ((v1&15) << 4) | r3
+ .word (b2 << 12) | (\disp)
+ MRXBOPC 0, 0x3f, v1
+.endm
/* Vector integer instructions */
@@ -512,6 +553,16 @@
MRXBOPC 0, 0x68, v1, v2, v3
.endm
+/* VECTOR CHECKSUM */
+.macro VCKSM vr1, vr2, vr3
+ VX_NUM v1, \vr1
+ VX_NUM v2, \vr2
+ VX_NUM v3, \vr3
+ .word 0xE700 | ((v1&15) << 4) | (v2&15)
+ .word ((v3&15) << 12)
+ MRXBOPC 0, 0x66, v1, v2, v3
+.endm
+
/* VECTOR EXCLUSIVE OR */
.macro VX vr1, vr2, vr3
VX_NUM v1, \vr1
@@ -678,4 +729,4 @@
.endm
#endif /* __ASSEMBLY__ */
-#endif /* __ASM_S390_VX_INSN_INTERNAL_H */
+#endif /* __ASM_S390_FPU_INSN_ASM_H */
diff --git a/arch/s390/include/asm/fpu-insn.h b/arch/s390/include/asm/fpu-insn.h
new file mode 100644
index 000000000000..c1e2e521d9af
--- /dev/null
+++ b/arch/s390/include/asm/fpu-insn.h
@@ -0,0 +1,486 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Support for Floating Point and Vector Instructions
+ *
+ */
+
+#ifndef __ASM_S390_FPU_INSN_H
+#define __ASM_S390_FPU_INSN_H
+
+#include <asm/fpu-insn-asm.h>
+
+#ifndef __ASSEMBLY__
+
+#include <linux/instrumented.h>
+#include <asm/asm-extable.h>
+
+asm(".include \"asm/fpu-insn-asm.h\"\n");
+
+/*
+ * Various small helper functions, which can and should be used within
+ * kernel fpu code sections. Each function represents only one floating
+ * point or vector instruction (except for helper functions which require
+ * exception handling).
+ *
+ * This allows to use floating point and vector instructions like C
+ * functions, which has the advantage that all supporting code, like
+ * e.g. loops, can be written in easy to read C code.
+ *
+ * Each of the helper functions provides support for code instrumentation,
+ * like e.g. KASAN. Therefore instrumentation is also covered automatically
+ * when using these functions.
+ *
+ * In order to ensure that code generated with the helper functions stays
+ * within kernel fpu sections, which are guarded with kernel_fpu_begin()
+ * and kernel_fpu_end() calls, each function has a mandatory "memory"
+ * barrier.
+ */
+
+static __always_inline void fpu_cefbr(u8 f1, s32 val)
+{
+ asm volatile("cefbr %[f1],%[val]\n"
+ :
+ : [f1] "I" (f1), [val] "d" (val)
+ : "memory");
+}
+
+static __always_inline unsigned long fpu_cgebr(u8 f2, u8 mode)
+{
+ unsigned long val;
+
+ asm volatile("cgebr %[val],%[mode],%[f2]\n"
+ : [val] "=d" (val)
+ : [f2] "I" (f2), [mode] "I" (mode)
+ : "memory");
+ return val;
+}
+
+static __always_inline void fpu_debr(u8 f1, u8 f2)
+{
+ asm volatile("debr %[f1],%[f2]\n"
+ :
+ : [f1] "I" (f1), [f2] "I" (f2)
+ : "memory");
+}
+
+static __always_inline void fpu_ld(unsigned short fpr, freg_t *reg)
+{
+ instrument_read(reg, sizeof(*reg));
+ asm volatile("ld %[fpr],%[reg]\n"
+ :
+ : [fpr] "I" (fpr), [reg] "Q" (reg->ui)
+ : "memory");
+}
+
+static __always_inline void fpu_ldgr(u8 f1, u32 val)
+{
+ asm volatile("ldgr %[f1],%[val]\n"
+ :
+ : [f1] "I" (f1), [val] "d" (val)
+ : "memory");
+}
+
+static __always_inline void fpu_lfpc(unsigned int *fpc)
+{
+ instrument_read(fpc, sizeof(*fpc));
+ asm volatile("lfpc %[fpc]"
+ :
+ : [fpc] "Q" (*fpc)
+ : "memory");
+}
+
+/**
+ * fpu_lfpc_safe - Load floating point control register safely.
+ * @fpc: new value for floating point control register
+ *
+ * Load floating point control register. This may lead to an exception,
+ * since a saved value may have been modified by user space (ptrace,
+ * signal return, kvm registers) to an invalid value. In such a case
+ * set the floating point control register to zero.
+ */
+static inline void fpu_lfpc_safe(unsigned int *fpc)
+{
+ u32 tmp;
+
+ instrument_read(fpc, sizeof(*fpc));
+ asm volatile("\n"
+ "0: lfpc %[fpc]\n"
+ "1: nopr %%r7\n"
+ ".pushsection .fixup, \"ax\"\n"
+ "2: lghi %[tmp],0\n"
+ " sfpc %[tmp]\n"
+ " jg 1b\n"
+ ".popsection\n"
+ EX_TABLE(1b, 2b)
+ : [tmp] "=d" (tmp)
+ : [fpc] "Q" (*fpc)
+ : "memory");
+}
+
+static __always_inline void fpu_std(unsigned short fpr, freg_t *reg)
+{
+ instrument_write(reg, sizeof(*reg));
+ asm volatile("std %[fpr],%[reg]\n"
+ : [reg] "=Q" (reg->ui)
+ : [fpr] "I" (fpr)
+ : "memory");
+}
+
+static __always_inline void fpu_sfpc(unsigned int fpc)
+{
+ asm volatile("sfpc %[fpc]"
+ :
+ : [fpc] "d" (fpc)
+ : "memory");
+}
+
+static __always_inline void fpu_stfpc(unsigned int *fpc)
+{
+ instrument_write(fpc, sizeof(*fpc));
+ asm volatile("stfpc %[fpc]"
+ : [fpc] "=Q" (*fpc)
+ :
+ : "memory");
+}
+
+static __always_inline void fpu_vab(u8 v1, u8 v2, u8 v3)
+{
+ asm volatile("VAB %[v1],%[v2],%[v3]"
+ :
+ : [v1] "I" (v1), [v2] "I" (v2), [v3] "I" (v3)
+ : "memory");
+}
+
+static __always_inline void fpu_vcksm(u8 v1, u8 v2, u8 v3)
+{
+ asm volatile("VCKSM %[v1],%[v2],%[v3]"
+ :
+ : [v1] "I" (v1), [v2] "I" (v2), [v3] "I" (v3)
+ : "memory");
+}
+
+static __always_inline void fpu_vesravb(u8 v1, u8 v2, u8 v3)
+{
+ asm volatile("VESRAVB %[v1],%[v2],%[v3]"
+ :
+ : [v1] "I" (v1), [v2] "I" (v2), [v3] "I" (v3)
+ : "memory");
+}
+
+static __always_inline void fpu_vgfmag(u8 v1, u8 v2, u8 v3, u8 v4)
+{
+ asm volatile("VGFMAG %[v1],%[v2],%[v3],%[v4]"
+ :
+ : [v1] "I" (v1), [v2] "I" (v2), [v3] "I" (v3), [v4] "I" (v4)
+ : "memory");
+}
+
+static __always_inline void fpu_vgfmg(u8 v1, u8 v2, u8 v3)
+{
+ asm volatile("VGFMG %[v1],%[v2],%[v3]"
+ :
+ : [v1] "I" (v1), [v2] "I" (v2), [v3] "I" (v3)
+ : "memory");
+}
+
+#ifdef CONFIG_CC_IS_CLANG
+
+static __always_inline void fpu_vl(u8 v1, const void *vxr)
+{
+ instrument_read(vxr, sizeof(__vector128));
+ asm volatile("\n"
+ " la 1,%[vxr]\n"
+ " VL %[v1],0,,1\n"
+ :
+ : [vxr] "R" (*(__vector128 *)vxr),
+ [v1] "I" (v1)
+ : "memory", "1");
+}
+
+#else /* CONFIG_CC_IS_CLANG */
+
+static __always_inline void fpu_vl(u8 v1, const void *vxr)
+{
+ instrument_read(vxr, sizeof(__vector128));
+ asm volatile("VL %[v1],%O[vxr],,%R[vxr]\n"
+ :
+ : [vxr] "Q" (*(__vector128 *)vxr),
+ [v1] "I" (v1)
+ : "memory");
+}
+
+#endif /* CONFIG_CC_IS_CLANG */
+
+static __always_inline void fpu_vleib(u8 v, s16 val, u8 index)
+{
+ asm volatile("VLEIB %[v],%[val],%[index]"
+ :
+ : [v] "I" (v), [val] "K" (val), [index] "I" (index)
+ : "memory");
+}
+
+static __always_inline void fpu_vleig(u8 v, s16 val, u8 index)
+{
+ asm volatile("VLEIG %[v],%[val],%[index]"
+ :
+ : [v] "I" (v), [val] "K" (val), [index] "I" (index)
+ : "memory");
+}
+
+static __always_inline u64 fpu_vlgvf(u8 v, u16 index)
+{
+ u64 val;
+
+ asm volatile("VLGVF %[val],%[v],%[index]"
+ : [val] "=d" (val)
+ : [v] "I" (v), [index] "L" (index)
+ : "memory");
+ return val;
+}
+
+#ifdef CONFIG_CC_IS_CLANG
+
+static __always_inline void fpu_vll(u8 v1, u32 index, const void *vxr)
+{
+ unsigned int size;
+
+ size = min(index + 1, sizeof(__vector128));
+ instrument_read(vxr, size);
+ asm volatile("\n"
+ " la 1,%[vxr]\n"
+ " VLL %[v1],%[index],0,1\n"
+ :
+ : [vxr] "R" (*(u8 *)vxr),
+ [index] "d" (index),
+ [v1] "I" (v1)
+ : "memory", "1");
+}
+
+#else /* CONFIG_CC_IS_CLANG */
+
+static __always_inline void fpu_vll(u8 v1, u32 index, const void *vxr)
+{
+ unsigned int size;
+
+ size = min(index + 1, sizeof(__vector128));
+ instrument_read(vxr, size);
+ asm volatile("VLL %[v1],%[index],%O[vxr],%R[vxr]\n"
+ :
+ : [vxr] "Q" (*(u8 *)vxr),
+ [index] "d" (index),
+ [v1] "I" (v1)
+ : "memory");
+}
+
+#endif /* CONFIG_CC_IS_CLANG */
+
+#ifdef CONFIG_CC_IS_CLANG
+
+#define fpu_vlm(_v1, _v3, _vxrs) \
+({ \
+ unsigned int size = ((_v3) - (_v1) + 1) * sizeof(__vector128); \
+ struct { \
+ __vector128 _v[(_v3) - (_v1) + 1]; \
+ } *_v = (void *)(_vxrs); \
+ \
+ instrument_read(_v, size); \
+ asm volatile("\n" \
+ " la 1,%[vxrs]\n" \
+ " VLM %[v1],%[v3],0,1\n" \
+ : \
+ : [vxrs] "R" (*_v), \
+ [v1] "I" (_v1), [v3] "I" (_v3) \
+ : "memory", "1"); \
+ (_v3) - (_v1) + 1; \
+})
+
+#else /* CONFIG_CC_IS_CLANG */
+
+#define fpu_vlm(_v1, _v3, _vxrs) \
+({ \
+ unsigned int size = ((_v3) - (_v1) + 1) * sizeof(__vector128); \
+ struct { \
+ __vector128 _v[(_v3) - (_v1) + 1]; \
+ } *_v = (void *)(_vxrs); \
+ \
+ instrument_read(_v, size); \
+ asm volatile("VLM %[v1],%[v3],%O[vxrs],%R[vxrs]\n" \
+ : \
+ : [vxrs] "Q" (*_v), \
+ [v1] "I" (_v1), [v3] "I" (_v3) \
+ : "memory"); \
+ (_v3) - (_v1) + 1; \
+})
+
+#endif /* CONFIG_CC_IS_CLANG */
+
+static __always_inline void fpu_vlr(u8 v1, u8 v2)
+{
+ asm volatile("VLR %[v1],%[v2]"
+ :
+ : [v1] "I" (v1), [v2] "I" (v2)
+ : "memory");
+}
+
+static __always_inline void fpu_vlvgf(u8 v, u32 val, u16 index)
+{
+ asm volatile("VLVGF %[v],%[val],%[index]"
+ :
+ : [v] "I" (v), [val] "d" (val), [index] "L" (index)
+ : "memory");
+}
+
+static __always_inline void fpu_vn(u8 v1, u8 v2, u8 v3)
+{
+ asm volatile("VN %[v1],%[v2],%[v3]"
+ :
+ : [v1] "I" (v1), [v2] "I" (v2), [v3] "I" (v3)
+ : "memory");
+}
+
+static __always_inline void fpu_vperm(u8 v1, u8 v2, u8 v3, u8 v4)
+{
+ asm volatile("VPERM %[v1],%[v2],%[v3],%[v4]"
+ :
+ : [v1] "I" (v1), [v2] "I" (v2), [v3] "I" (v3), [v4] "I" (v4)
+ : "memory");
+}
+
+static __always_inline void fpu_vrepib(u8 v1, s16 i2)
+{
+ asm volatile("VREPIB %[v1],%[i2]"
+ :
+ : [v1] "I" (v1), [i2] "K" (i2)
+ : "memory");
+}
+
+static __always_inline void fpu_vsrlb(u8 v1, u8 v2, u8 v3)
+{
+ asm volatile("VSRLB %[v1],%[v2],%[v3]"
+ :
+ : [v1] "I" (v1), [v2] "I" (v2), [v3] "I" (v3)
+ : "memory");
+}
+
+#ifdef CONFIG_CC_IS_CLANG
+
+static __always_inline void fpu_vst(u8 v1, const void *vxr)
+{
+ instrument_write(vxr, sizeof(__vector128));
+ asm volatile("\n"
+ " la 1,%[vxr]\n"
+ " VST %[v1],0,,1\n"
+ : [vxr] "=R" (*(__vector128 *)vxr)
+ : [v1] "I" (v1)
+ : "memory", "1");
+}
+
+#else /* CONFIG_CC_IS_CLANG */
+
+static __always_inline void fpu_vst(u8 v1, const void *vxr)
+{
+ instrument_write(vxr, sizeof(__vector128));
+ asm volatile("VST %[v1],%O[vxr],,%R[vxr]\n"
+ : [vxr] "=Q" (*(__vector128 *)vxr)
+ : [v1] "I" (v1)
+ : "memory");
+}
+
+#endif /* CONFIG_CC_IS_CLANG */
+
+#ifdef CONFIG_CC_IS_CLANG
+
+static __always_inline void fpu_vstl(u8 v1, u32 index, const void *vxr)
+{
+ unsigned int size;
+
+ size = min(index + 1, sizeof(__vector128));
+ instrument_write(vxr, size);
+ asm volatile("\n"
+ " la 1,%[vxr]\n"
+ " VSTL %[v1],%[index],0,1\n"
+ : [vxr] "=R" (*(u8 *)vxr)
+ : [index] "d" (index), [v1] "I" (v1)
+ : "memory", "1");
+}
+
+#else /* CONFIG_CC_IS_CLANG */
+
+static __always_inline void fpu_vstl(u8 v1, u32 index, const void *vxr)
+{
+ unsigned int size;
+
+ size = min(index + 1, sizeof(__vector128));
+ instrument_write(vxr, size);
+ asm volatile("VSTL %[v1],%[index],%O[vxr],%R[vxr]\n"
+ : [vxr] "=Q" (*(u8 *)vxr)
+ : [index] "d" (index), [v1] "I" (v1)
+ : "memory");
+}
+
+#endif /* CONFIG_CC_IS_CLANG */
+
+#ifdef CONFIG_CC_IS_CLANG
+
+#define fpu_vstm(_v1, _v3, _vxrs) \
+({ \
+ unsigned int size = ((_v3) - (_v1) + 1) * sizeof(__vector128); \
+ struct { \
+ __vector128 _v[(_v3) - (_v1) + 1]; \
+ } *_v = (void *)(_vxrs); \
+ \
+ instrument_write(_v, size); \
+ asm volatile("\n" \
+ " la 1,%[vxrs]\n" \
+ " VSTM %[v1],%[v3],0,1\n" \
+ : [vxrs] "=R" (*_v) \
+ : [v1] "I" (_v1), [v3] "I" (_v3) \
+ : "memory", "1"); \
+ (_v3) - (_v1) + 1; \
+})
+
+#else /* CONFIG_CC_IS_CLANG */
+
+#define fpu_vstm(_v1, _v3, _vxrs) \
+({ \
+ unsigned int size = ((_v3) - (_v1) + 1) * sizeof(__vector128); \
+ struct { \
+ __vector128 _v[(_v3) - (_v1) + 1]; \
+ } *_v = (void *)(_vxrs); \
+ \
+ instrument_write(_v, size); \
+ asm volatile("VSTM %[v1],%[v3],%O[vxrs],%R[vxrs]\n" \
+ : [vxrs] "=Q" (*_v) \
+ : [v1] "I" (_v1), [v3] "I" (_v3) \
+ : "memory"); \
+ (_v3) - (_v1) + 1; \
+})
+
+#endif /* CONFIG_CC_IS_CLANG */
+
+static __always_inline void fpu_vupllf(u8 v1, u8 v2)
+{
+ asm volatile("VUPLLF %[v1],%[v2]"
+ :
+ : [v1] "I" (v1), [v2] "I" (v2)
+ : "memory");
+}
+
+static __always_inline void fpu_vx(u8 v1, u8 v2, u8 v3)
+{
+ asm volatile("VX %[v1],%[v2],%[v3]"
+ :
+ : [v1] "I" (v1), [v2] "I" (v2), [v3] "I" (v3)
+ : "memory");
+}
+
+static __always_inline void fpu_vzero(u8 v)
+{
+ asm volatile("VZERO %[v]"
+ :
+ : [v] "I" (v)
+ : "memory");
+}
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ASM_S390_FPU_INSN_H */
diff --git a/arch/s390/include/asm/fpu-types.h b/arch/s390/include/asm/fpu-types.h
new file mode 100644
index 000000000000..8d58d5a95399
--- /dev/null
+++ b/arch/s390/include/asm/fpu-types.h
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * FPU data structures
+ *
+ * Copyright IBM Corp. 2015
+ * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
+ */
+
+#ifndef _ASM_S390_FPU_TYPES_H
+#define _ASM_S390_FPU_TYPES_H
+
+#include <asm/sigcontext.h>
+
+struct fpu {
+ u32 fpc;
+ __vector128 vxrs[__NUM_VXRS] __aligned(8);
+};
+
+struct kernel_fpu_hdr {
+ int mask;
+ u32 fpc;
+};
+
+struct kernel_fpu {
+ struct kernel_fpu_hdr hdr;
+ __vector128 vxrs[] __aligned(8);
+};
+
+#define KERNEL_FPU_STRUCT(vxr_size) \
+struct kernel_fpu_##vxr_size { \
+ struct kernel_fpu_hdr hdr; \
+ __vector128 vxrs[vxr_size] __aligned(8); \
+}
+
+KERNEL_FPU_STRUCT(8);
+KERNEL_FPU_STRUCT(16);
+KERNEL_FPU_STRUCT(32);
+
+#define DECLARE_KERNEL_FPU_ONSTACK(vxr_size, name) \
+ struct kernel_fpu_##vxr_size name __uninitialized
+
+#define DECLARE_KERNEL_FPU_ONSTACK8(name) \
+ DECLARE_KERNEL_FPU_ONSTACK(8, name)
+
+#define DECLARE_KERNEL_FPU_ONSTACK16(name) \
+ DECLARE_KERNEL_FPU_ONSTACK(16, name)
+
+#define DECLARE_KERNEL_FPU_ONSTACK32(name) \
+ DECLARE_KERNEL_FPU_ONSTACK(32, name)
+
+#endif /* _ASM_S390_FPU_TYPES_H */
diff --git a/arch/s390/include/asm/fpu.h b/arch/s390/include/asm/fpu.h
new file mode 100644
index 000000000000..c84cb33913e2
--- /dev/null
+++ b/arch/s390/include/asm/fpu.h
@@ -0,0 +1,295 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * In-kernel FPU support functions
+ *
+ *
+ * Consider these guidelines before using in-kernel FPU functions:
+ *
+ * 1. Use kernel_fpu_begin() and kernel_fpu_end() to enclose all in-kernel
+ * use of floating-point or vector registers and instructions.
+ *
+ * 2. For kernel_fpu_begin(), specify the vector register range you want to
+ * use with the KERNEL_VXR_* constants. Consider these usage guidelines:
+ *
+ * a) If your function typically runs in process-context, use the lower
+ * half of the vector registers, for example, specify KERNEL_VXR_LOW.
+ * b) If your function typically runs in soft-irq or hard-irq context,
+ * prefer using the upper half of the vector registers, for example,
+ * specify KERNEL_VXR_HIGH.
+ *
+ * If you adhere to these guidelines, an interrupted process context
+ * does not require to save and restore vector registers because of
+ * disjoint register ranges.
+ *
+ * Also note that the __kernel_fpu_begin()/__kernel_fpu_end() functions
+ * includes logic to save and restore up to 16 vector registers at once.
+ *
+ * 3. You can nest kernel_fpu_begin()/kernel_fpu_end() by using different
+ * struct kernel_fpu states. Vector registers that are in use by outer
+ * levels are saved and restored. You can minimize the save and restore
+ * effort by choosing disjoint vector register ranges.
+ *
+ * 5. To use vector floating-point instructions, specify the KERNEL_FPC
+ * flag to save and restore floating-point controls in addition to any
+ * vector register range.
+ *
+ * 6. To use floating-point registers and instructions only, specify the
+ * KERNEL_FPR flag. This flag triggers a save and restore of vector
+ * registers V0 to V15 and floating-point controls.
+ *
+ * Copyright IBM Corp. 2015
+ * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
+ */
+
+#ifndef _ASM_S390_FPU_H
+#define _ASM_S390_FPU_H
+
+#include <linux/processor.h>
+#include <linux/preempt.h>
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <asm/sigcontext.h>
+#include <asm/fpu-types.h>
+#include <asm/fpu-insn.h>
+#include <asm/facility.h>
+
+static inline bool cpu_has_vx(void)
+{
+ return likely(test_facility(129));
+}
+
+enum {
+ KERNEL_FPC_BIT = 0,
+ KERNEL_VXR_V0V7_BIT,
+ KERNEL_VXR_V8V15_BIT,
+ KERNEL_VXR_V16V23_BIT,
+ KERNEL_VXR_V24V31_BIT,
+};
+
+#define KERNEL_FPC BIT(KERNEL_FPC_BIT)
+#define KERNEL_VXR_V0V7 BIT(KERNEL_VXR_V0V7_BIT)
+#define KERNEL_VXR_V8V15 BIT(KERNEL_VXR_V8V15_BIT)
+#define KERNEL_VXR_V16V23 BIT(KERNEL_VXR_V16V23_BIT)
+#define KERNEL_VXR_V24V31 BIT(KERNEL_VXR_V24V31_BIT)
+
+#define KERNEL_VXR_LOW (KERNEL_VXR_V0V7 | KERNEL_VXR_V8V15)
+#define KERNEL_VXR_MID (KERNEL_VXR_V8V15 | KERNEL_VXR_V16V23)
+#define KERNEL_VXR_HIGH (KERNEL_VXR_V16V23 | KERNEL_VXR_V24V31)
+
+#define KERNEL_VXR (KERNEL_VXR_LOW | KERNEL_VXR_HIGH)
+#define KERNEL_FPR (KERNEL_FPC | KERNEL_VXR_LOW)
+
+void load_fpu_state(struct fpu *state, int flags);
+void save_fpu_state(struct fpu *state, int flags);
+void __kernel_fpu_begin(struct kernel_fpu *state, int flags);
+void __kernel_fpu_end(struct kernel_fpu *state, int flags);
+
+static __always_inline void save_vx_regs(__vector128 *vxrs)
+{
+ fpu_vstm(0, 15, &vxrs[0]);
+ fpu_vstm(16, 31, &vxrs[16]);
+}
+
+static __always_inline void load_vx_regs(__vector128 *vxrs)
+{
+ fpu_vlm(0, 15, &vxrs[0]);
+ fpu_vlm(16, 31, &vxrs[16]);
+}
+
+static __always_inline void __save_fp_regs(freg_t *fprs, unsigned int offset)
+{
+ fpu_std(0, &fprs[0 * offset]);
+ fpu_std(1, &fprs[1 * offset]);
+ fpu_std(2, &fprs[2 * offset]);
+ fpu_std(3, &fprs[3 * offset]);
+ fpu_std(4, &fprs[4 * offset]);
+ fpu_std(5, &fprs[5 * offset]);
+ fpu_std(6, &fprs[6 * offset]);
+ fpu_std(7, &fprs[7 * offset]);
+ fpu_std(8, &fprs[8 * offset]);
+ fpu_std(9, &fprs[9 * offset]);
+ fpu_std(10, &fprs[10 * offset]);
+ fpu_std(11, &fprs[11 * offset]);
+ fpu_std(12, &fprs[12 * offset]);
+ fpu_std(13, &fprs[13 * offset]);
+ fpu_std(14, &fprs[14 * offset]);
+ fpu_std(15, &fprs[15 * offset]);
+}
+
+static __always_inline void __load_fp_regs(freg_t *fprs, unsigned int offset)
+{
+ fpu_ld(0, &fprs[0 * offset]);
+ fpu_ld(1, &fprs[1 * offset]);
+ fpu_ld(2, &fprs[2 * offset]);
+ fpu_ld(3, &fprs[3 * offset]);
+ fpu_ld(4, &fprs[4 * offset]);
+ fpu_ld(5, &fprs[5 * offset]);
+ fpu_ld(6, &fprs[6 * offset]);
+ fpu_ld(7, &fprs[7 * offset]);
+ fpu_ld(8, &fprs[8 * offset]);
+ fpu_ld(9, &fprs[9 * offset]);
+ fpu_ld(10, &fprs[10 * offset]);
+ fpu_ld(11, &fprs[11 * offset]);
+ fpu_ld(12, &fprs[12 * offset]);
+ fpu_ld(13, &fprs[13 * offset]);
+ fpu_ld(14, &fprs[14 * offset]);
+ fpu_ld(15, &fprs[15 * offset]);
+}
+
+static __always_inline void save_fp_regs(freg_t *fprs)
+{
+ __save_fp_regs(fprs, sizeof(freg_t) / sizeof(freg_t));
+}
+
+static __always_inline void load_fp_regs(freg_t *fprs)
+{
+ __load_fp_regs(fprs, sizeof(freg_t) / sizeof(freg_t));
+}
+
+static __always_inline void save_fp_regs_vx(__vector128 *vxrs)
+{
+ freg_t *fprs = (freg_t *)&vxrs[0].high;
+
+ __save_fp_regs(fprs, sizeof(__vector128) / sizeof(freg_t));
+}
+
+static __always_inline void load_fp_regs_vx(__vector128 *vxrs)
+{
+ freg_t *fprs = (freg_t *)&vxrs[0].high;
+
+ __load_fp_regs(fprs, sizeof(__vector128) / sizeof(freg_t));
+}
+
+static inline void load_user_fpu_regs(void)
+{
+ struct thread_struct *thread = &current->thread;
+
+ if (!thread->ufpu_flags)
+ return;
+ load_fpu_state(&thread->ufpu, thread->ufpu_flags);
+ thread->ufpu_flags = 0;
+}
+
+static __always_inline void __save_user_fpu_regs(struct thread_struct *thread, int flags)
+{
+ save_fpu_state(&thread->ufpu, flags);
+ __atomic_or(flags, &thread->ufpu_flags);
+}
+
+static inline void save_user_fpu_regs(void)
+{
+ struct thread_struct *thread = &current->thread;
+ int mask, flags;
+
+ mask = __atomic_or(KERNEL_FPC | KERNEL_VXR, &thread->kfpu_flags);
+ flags = ~READ_ONCE(thread->ufpu_flags) & (KERNEL_FPC | KERNEL_VXR);
+ if (flags)
+ __save_user_fpu_regs(thread, flags);
+ barrier();
+ WRITE_ONCE(thread->kfpu_flags, mask);
+}
+
+static __always_inline void _kernel_fpu_begin(struct kernel_fpu *state, int flags)
+{
+ struct thread_struct *thread = &current->thread;
+ int mask, uflags;
+
+ mask = __atomic_or(flags, &thread->kfpu_flags);
+ state->hdr.mask = mask;
+ uflags = READ_ONCE(thread->ufpu_flags);
+ if ((uflags & flags) != flags)
+ __save_user_fpu_regs(thread, ~uflags & flags);
+ if (mask & flags)
+ __kernel_fpu_begin(state, flags);
+}
+
+static __always_inline void _kernel_fpu_end(struct kernel_fpu *state, int flags)
+{
+ int mask = state->hdr.mask;
+
+ if (mask & flags)
+ __kernel_fpu_end(state, flags);
+ barrier();
+ WRITE_ONCE(current->thread.kfpu_flags, mask);
+}
+
+void __kernel_fpu_invalid_size(void);
+
+static __always_inline void kernel_fpu_check_size(int flags, unsigned int size)
+{
+ unsigned int cnt = 0;
+
+ if (flags & KERNEL_VXR_V0V7)
+ cnt += 8;
+ if (flags & KERNEL_VXR_V8V15)
+ cnt += 8;
+ if (flags & KERNEL_VXR_V16V23)
+ cnt += 8;
+ if (flags & KERNEL_VXR_V24V31)
+ cnt += 8;
+ if (cnt != size)
+ __kernel_fpu_invalid_size();
+}
+
+#define kernel_fpu_begin(state, flags) \
+{ \
+ typeof(state) s = (state); \
+ int _flags = (flags); \
+ \
+ kernel_fpu_check_size(_flags, ARRAY_SIZE(s->vxrs)); \
+ _kernel_fpu_begin((struct kernel_fpu *)s, _flags); \
+}
+
+#define kernel_fpu_end(state, flags) \
+{ \
+ typeof(state) s = (state); \
+ int _flags = (flags); \
+ \
+ kernel_fpu_check_size(_flags, ARRAY_SIZE(s->vxrs)); \
+ _kernel_fpu_end((struct kernel_fpu *)s, _flags); \
+}
+
+static inline void save_kernel_fpu_regs(struct thread_struct *thread)
+{
+ if (!thread->kfpu_flags)
+ return;
+ save_fpu_state(&thread->kfpu, thread->kfpu_flags);
+}
+
+static inline void restore_kernel_fpu_regs(struct thread_struct *thread)
+{
+ if (!thread->kfpu_flags)
+ return;
+ load_fpu_state(&thread->kfpu, thread->kfpu_flags);
+}
+
+static inline void convert_vx_to_fp(freg_t *fprs, __vector128 *vxrs)
+{
+ int i;
+
+ for (i = 0; i < __NUM_FPRS; i++)
+ fprs[i].ui = vxrs[i].high;
+}
+
+static inline void convert_fp_to_vx(__vector128 *vxrs, freg_t *fprs)
+{
+ int i;
+
+ for (i = 0; i < __NUM_FPRS; i++)
+ vxrs[i].high = fprs[i].ui;
+}
+
+static inline void fpregs_store(_s390_fp_regs *fpregs, struct fpu *fpu)
+{
+ fpregs->pad = 0;
+ fpregs->fpc = fpu->fpc;
+ convert_vx_to_fp((freg_t *)&fpregs->fprs, fpu->vxrs);
+}
+
+static inline void fpregs_load(_s390_fp_regs *fpregs, struct fpu *fpu)
+{
+ fpu->fpc = fpregs->fpc;
+ convert_fp_to_vx(fpu->vxrs, (freg_t *)&fpregs->fprs);
+}
+
+#endif /* _ASM_S390_FPU_H */
diff --git a/arch/s390/include/asm/fpu/api.h b/arch/s390/include/asm/fpu/api.h
deleted file mode 100644
index d6ca8bc6ca68..000000000000
--- a/arch/s390/include/asm/fpu/api.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * In-kernel FPU support functions
- *
- *
- * Consider these guidelines before using in-kernel FPU functions:
- *
- * 1. Use kernel_fpu_begin() and kernel_fpu_end() to enclose all in-kernel
- * use of floating-point or vector registers and instructions.
- *
- * 2. For kernel_fpu_begin(), specify the vector register range you want to
- * use with the KERNEL_VXR_* constants. Consider these usage guidelines:
- *
- * a) If your function typically runs in process-context, use the lower
- * half of the vector registers, for example, specify KERNEL_VXR_LOW.
- * b) If your function typically runs in soft-irq or hard-irq context,
- * prefer using the upper half of the vector registers, for example,
- * specify KERNEL_VXR_HIGH.
- *
- * If you adhere to these guidelines, an interrupted process context
- * does not require to save and restore vector registers because of
- * disjoint register ranges.
- *
- * Also note that the __kernel_fpu_begin()/__kernel_fpu_end() functions
- * includes logic to save and restore up to 16 vector registers at once.
- *
- * 3. You can nest kernel_fpu_begin()/kernel_fpu_end() by using different
- * struct kernel_fpu states. Vector registers that are in use by outer
- * levels are saved and restored. You can minimize the save and restore
- * effort by choosing disjoint vector register ranges.
- *
- * 5. To use vector floating-point instructions, specify the KERNEL_FPC
- * flag to save and restore floating-point controls in addition to any
- * vector register range.
- *
- * 6. To use floating-point registers and instructions only, specify the
- * KERNEL_FPR flag. This flag triggers a save and restore of vector
- * registers V0 to V15 and floating-point controls.
- *
- * Copyright IBM Corp. 2015
- * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
- */
-
-#ifndef _ASM_S390_FPU_API_H
-#define _ASM_S390_FPU_API_H
-
-#include <linux/preempt.h>
-#include <asm/asm-extable.h>
-#include <asm/fpu/internal.h>
-
-void save_fpu_regs(void);
-void load_fpu_regs(void);
-void __load_fpu_regs(void);
-
-/**
- * sfpc_safe - Set floating point control register safely.
- * @fpc: new value for floating point control register
- *
- * Set floating point control register. This may lead to an exception,
- * since a saved value may have been modified by user space (ptrace,
- * signal return, kvm registers) to an invalid value. In such a case
- * set the floating point control register to zero.
- */
-static inline void sfpc_safe(u32 fpc)
-{
- asm volatile("\n"
- "0: sfpc %[fpc]\n"
- "1: nopr %%r7\n"
- ".pushsection .fixup, \"ax\"\n"
- "2: lghi %[fpc],0\n"
- " jg 0b\n"
- ".popsection\n"
- EX_TABLE(1b, 2b)
- : [fpc] "+d" (fpc)
- : : "memory");
-}
-
-#define KERNEL_FPC 1
-#define KERNEL_VXR_V0V7 2
-#define KERNEL_VXR_V8V15 4
-#define KERNEL_VXR_V16V23 8
-#define KERNEL_VXR_V24V31 16
-
-#define KERNEL_VXR_LOW (KERNEL_VXR_V0V7|KERNEL_VXR_V8V15)
-#define KERNEL_VXR_MID (KERNEL_VXR_V8V15|KERNEL_VXR_V16V23)
-#define KERNEL_VXR_HIGH (KERNEL_VXR_V16V23|KERNEL_VXR_V24V31)
-
-#define KERNEL_VXR (KERNEL_VXR_LOW|KERNEL_VXR_HIGH)
-#define KERNEL_FPR (KERNEL_FPC|KERNEL_VXR_LOW)
-
-struct kernel_fpu;
-
-/*
- * Note the functions below must be called with preemption disabled.
- * Do not enable preemption before calling __kernel_fpu_end() to prevent
- * an corruption of an existing kernel FPU state.
- *
- * Prefer using the kernel_fpu_begin()/kernel_fpu_end() pair of functions.
- */
-void __kernel_fpu_begin(struct kernel_fpu *state, u32 flags);
-void __kernel_fpu_end(struct kernel_fpu *state, u32 flags);
-
-
-static inline void kernel_fpu_begin(struct kernel_fpu *state, u32 flags)
-{
- preempt_disable();
- state->mask = S390_lowcore.fpu_flags;
- if (!test_cpu_flag(CIF_FPU))
- /* Save user space FPU state and register contents */
- save_fpu_regs();
- else if (state->mask & flags)
- /* Save FPU/vector register in-use by the kernel */
- __kernel_fpu_begin(state, flags);
- S390_lowcore.fpu_flags |= flags;
-}
-
-static inline void kernel_fpu_end(struct kernel_fpu *state, u32 flags)
-{
- S390_lowcore.fpu_flags = state->mask;
- if (state->mask & flags)
- /* Restore FPU/vector register in-use by the kernel */
- __kernel_fpu_end(state, flags);
- preempt_enable();
-}
-
-#endif /* _ASM_S390_FPU_API_H */
diff --git a/arch/s390/include/asm/fpu/internal.h b/arch/s390/include/asm/fpu/internal.h
deleted file mode 100644
index d511c4cf5afb..000000000000
--- a/arch/s390/include/asm/fpu/internal.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * FPU state and register content conversion primitives
- *
- * Copyright IBM Corp. 2015
- * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
- */
-
-#ifndef _ASM_S390_FPU_INTERNAL_H
-#define _ASM_S390_FPU_INTERNAL_H
-
-#include <linux/string.h>
-#include <asm/facility.h>
-#include <asm/fpu/types.h>
-
-static inline bool cpu_has_vx(void)
-{
- return likely(test_facility(129));
-}
-
-static inline void save_vx_regs(__vector128 *vxrs)
-{
- asm volatile(
- " la 1,%0\n"
- " .word 0xe70f,0x1000,0x003e\n" /* vstm 0,15,0(1) */
- " .word 0xe70f,0x1100,0x0c3e\n" /* vstm 16,31,256(1) */
- : "=Q" (*(struct vx_array *) vxrs) : : "1");
-}
-
-static inline void convert_vx_to_fp(freg_t *fprs, __vector128 *vxrs)
-{
- int i;
-
- for (i = 0; i < __NUM_FPRS; i++)
- fprs[i].ui = vxrs[i].high;
-}
-
-static inline void convert_fp_to_vx(__vector128 *vxrs, freg_t *fprs)
-{
- int i;
-
- for (i = 0; i < __NUM_FPRS; i++)
- vxrs[i].high = fprs[i].ui;
-}
-
-static inline void fpregs_store(_s390_fp_regs *fpregs, struct fpu *fpu)
-{
- fpregs->pad = 0;
- fpregs->fpc = fpu->fpc;
- if (cpu_has_vx())
- convert_vx_to_fp((freg_t *)&fpregs->fprs, fpu->vxrs);
- else
- memcpy((freg_t *)&fpregs->fprs, fpu->fprs,
- sizeof(fpregs->fprs));
-}
-
-static inline void fpregs_load(_s390_fp_regs *fpregs, struct fpu *fpu)
-{
- fpu->fpc = fpregs->fpc;
- if (cpu_has_vx())
- convert_fp_to_vx(fpu->vxrs, (freg_t *)&fpregs->fprs);
- else
- memcpy(fpu->fprs, (freg_t *)&fpregs->fprs,
- sizeof(fpregs->fprs));
-}
-
-#endif /* _ASM_S390_FPU_INTERNAL_H */
diff --git a/arch/s390/include/asm/fpu/types.h b/arch/s390/include/asm/fpu/types.h
deleted file mode 100644
index d889e9436865..000000000000
--- a/arch/s390/include/asm/fpu/types.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * FPU data structures
- *
- * Copyright IBM Corp. 2015
- * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
- */
-
-#ifndef _ASM_S390_FPU_TYPES_H
-#define _ASM_S390_FPU_TYPES_H
-
-#include <asm/sigcontext.h>
-
-struct fpu {
- __u32 fpc; /* Floating-point control */
- void *regs; /* Pointer to the current save area */
- union {
- /* Floating-point register save area */
- freg_t fprs[__NUM_FPRS];
- /* Vector register save area */
- __vector128 vxrs[__NUM_VXRS];
- };
-};
-
-/* VX array structure for address operand constraints in inline assemblies */
-struct vx_array { __vector128 _[__NUM_VXRS]; };
-
-/* In-kernel FPU state structure */
-struct kernel_fpu {
- u32 mask;
- u32 fpc;
- union {
- freg_t fprs[__NUM_FPRS];
- __vector128 vxrs[__NUM_VXRS];
- };
-};
-
-#endif /* _ASM_S390_FPU_TYPES_H */
diff --git a/arch/s390/include/asm/ftrace.h b/arch/s390/include/asm/ftrace.h
index 5a82b08f03cd..621f23d5ae30 100644
--- a/arch/s390/include/asm/ftrace.h
+++ b/arch/s390/include/asm/ftrace.h
@@ -9,7 +9,7 @@
#ifndef __ASSEMBLY__
#ifdef CONFIG_CC_IS_CLANG
-/* https://bugs.llvm.org/show_bug.cgi?id=41424 */
+/* https://llvm.org/pr41424 */
#define ftrace_return_address(n) 0UL
#else
#define ftrace_return_address(n) __builtin_return_address(n)
diff --git a/arch/s390/include/asm/idals.h b/arch/s390/include/asm/idals.h
index 59fcc3c72edf..ac68c657b28c 100644
--- a/arch/s390/include/asm/idals.h
+++ b/arch/s390/include/asm/idals.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
+/*
* Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
* Martin Schwidefsky <schwidefsky@de.ibm.com>
* Bugreports.to..: <Linux390@de.ibm.com>
@@ -17,32 +17,37 @@
#include <linux/err.h>
#include <linux/types.h>
#include <linux/slab.h>
-#include <asm/cio.h>
#include <linux/uaccess.h>
+#include <asm/dma-types.h>
+#include <asm/cio.h>
-#define IDA_SIZE_LOG 12 /* 11 for 2k , 12 for 4k */
-#define IDA_BLOCK_SIZE (1L<<IDA_SIZE_LOG)
+#define IDA_SIZE_SHIFT 12
+#define IDA_BLOCK_SIZE (1UL << IDA_SIZE_SHIFT)
-#define IDA_2K_SIZE_LOG 11
-#define IDA_2K_BLOCK_SIZE (1L << IDA_2K_SIZE_LOG)
+#define IDA_2K_SIZE_SHIFT 11
+#define IDA_2K_BLOCK_SIZE (1UL << IDA_2K_SIZE_SHIFT)
/*
* Test if an address/length pair needs an idal list.
*/
-static inline int
-idal_is_needed(void *vaddr, unsigned int length)
+static inline bool idal_is_needed(void *vaddr, unsigned int length)
{
- return ((__pa(vaddr) + length - 1) >> 31) != 0;
-}
+ dma64_t paddr = virt_to_dma64(vaddr);
+ return (((__force unsigned long)(paddr) + length - 1) >> 31) != 0;
+}
/*
* Return the number of idal words needed for an address/length pair.
*/
static inline unsigned int idal_nr_words(void *vaddr, unsigned int length)
{
- return ((__pa(vaddr) & (IDA_BLOCK_SIZE-1)) + length +
- (IDA_BLOCK_SIZE-1)) >> IDA_SIZE_LOG;
+ unsigned int cidaw;
+
+ cidaw = (unsigned long)vaddr & (IDA_BLOCK_SIZE - 1);
+ cidaw += length + IDA_BLOCK_SIZE - 1;
+ cidaw >>= IDA_SIZE_SHIFT;
+ return cidaw;
}
/*
@@ -50,26 +55,27 @@ static inline unsigned int idal_nr_words(void *vaddr, unsigned int length)
*/
static inline unsigned int idal_2k_nr_words(void *vaddr, unsigned int length)
{
- return ((__pa(vaddr) & (IDA_2K_BLOCK_SIZE - 1)) + length +
- (IDA_2K_BLOCK_SIZE - 1)) >> IDA_2K_SIZE_LOG;
+ unsigned int cidaw;
+
+ cidaw = (unsigned long)vaddr & (IDA_2K_BLOCK_SIZE - 1);
+ cidaw += length + IDA_2K_BLOCK_SIZE - 1;
+ cidaw >>= IDA_2K_SIZE_SHIFT;
+ return cidaw;
}
/*
* Create the list of idal words for an address/length pair.
*/
-static inline unsigned long *idal_create_words(unsigned long *idaws,
- void *vaddr, unsigned int length)
+static inline dma64_t *idal_create_words(dma64_t *idaws, void *vaddr, unsigned int length)
{
- unsigned long paddr;
+ dma64_t paddr = virt_to_dma64(vaddr);
unsigned int cidaw;
- paddr = __pa(vaddr);
- cidaw = ((paddr & (IDA_BLOCK_SIZE-1)) + length +
- (IDA_BLOCK_SIZE-1)) >> IDA_SIZE_LOG;
*idaws++ = paddr;
- paddr &= -IDA_BLOCK_SIZE;
+ cidaw = idal_nr_words(vaddr, length);
+ paddr = dma64_and(paddr, -IDA_BLOCK_SIZE);
while (--cidaw > 0) {
- paddr += IDA_BLOCK_SIZE;
+ paddr = dma64_add(paddr, IDA_BLOCK_SIZE);
*idaws++ = paddr;
}
return idaws;
@@ -79,36 +85,33 @@ static inline unsigned long *idal_create_words(unsigned long *idaws,
* Sets the address of the data in CCW.
* If necessary it allocates an IDAL and sets the appropriate flags.
*/
-static inline int
-set_normalized_cda(struct ccw1 * ccw, void *vaddr)
+static inline int set_normalized_cda(struct ccw1 *ccw, void *vaddr)
{
unsigned int nridaws;
- unsigned long *idal;
+ dma64_t *idal;
if (ccw->flags & CCW_FLAG_IDA)
return -EINVAL;
nridaws = idal_nr_words(vaddr, ccw->count);
if (nridaws > 0) {
- idal = kmalloc(nridaws * sizeof(unsigned long),
- GFP_ATOMIC | GFP_DMA );
- if (idal == NULL)
+ idal = kcalloc(nridaws, sizeof(*idal), GFP_ATOMIC | GFP_DMA);
+ if (!idal)
return -ENOMEM;
idal_create_words(idal, vaddr, ccw->count);
ccw->flags |= CCW_FLAG_IDA;
vaddr = idal;
}
- ccw->cda = (__u32)(unsigned long) vaddr;
+ ccw->cda = virt_to_dma32(vaddr);
return 0;
}
/*
* Releases any allocated IDAL related to the CCW.
*/
-static inline void
-clear_normalized_cda(struct ccw1 * ccw)
+static inline void clear_normalized_cda(struct ccw1 *ccw)
{
if (ccw->flags & CCW_FLAG_IDA) {
- kfree((void *)(unsigned long) ccw->cda);
+ kfree(dma32_to_virt(ccw->cda));
ccw->flags &= ~CCW_FLAG_IDA;
}
ccw->cda = 0;
@@ -120,125 +123,138 @@ clear_normalized_cda(struct ccw1 * ccw)
struct idal_buffer {
size_t size;
size_t page_order;
- void *data[];
+ dma64_t data[];
};
/*
* Allocate an idal buffer
*/
-static inline struct idal_buffer *
-idal_buffer_alloc(size_t size, int page_order)
+static inline struct idal_buffer *idal_buffer_alloc(size_t size, int page_order)
{
- struct idal_buffer *ib;
int nr_chunks, nr_ptrs, i;
+ struct idal_buffer *ib;
+ void *vaddr;
- nr_ptrs = (size + IDA_BLOCK_SIZE - 1) >> IDA_SIZE_LOG;
- nr_chunks = (4096 << page_order) >> IDA_SIZE_LOG;
+ nr_ptrs = (size + IDA_BLOCK_SIZE - 1) >> IDA_SIZE_SHIFT;
+ nr_chunks = (PAGE_SIZE << page_order) >> IDA_SIZE_SHIFT;
ib = kmalloc(struct_size(ib, data, nr_ptrs), GFP_DMA | GFP_KERNEL);
- if (ib == NULL)
+ if (!ib)
return ERR_PTR(-ENOMEM);
ib->size = size;
ib->page_order = page_order;
for (i = 0; i < nr_ptrs; i++) {
- if ((i & (nr_chunks - 1)) != 0) {
- ib->data[i] = ib->data[i-1] + IDA_BLOCK_SIZE;
- continue;
- }
- ib->data[i] = (void *)
- __get_free_pages(GFP_KERNEL, page_order);
- if (ib->data[i] != NULL)
+ if (i & (nr_chunks - 1)) {
+ ib->data[i] = dma64_add(ib->data[i - 1], IDA_BLOCK_SIZE);
continue;
- // Not enough memory
- while (i >= nr_chunks) {
- i -= nr_chunks;
- free_pages((unsigned long) ib->data[i],
- ib->page_order);
}
- kfree(ib);
- return ERR_PTR(-ENOMEM);
+ vaddr = (void *)__get_free_pages(GFP_KERNEL, page_order);
+ if (!vaddr)
+ goto error;
+ ib->data[i] = virt_to_dma64(vaddr);
}
return ib;
+error:
+ while (i >= nr_chunks) {
+ i -= nr_chunks;
+ vaddr = dma64_to_virt(ib->data[i]);
+ free_pages((unsigned long)vaddr, ib->page_order);
+ }
+ kfree(ib);
+ return ERR_PTR(-ENOMEM);
}
/*
* Free an idal buffer.
*/
-static inline void
-idal_buffer_free(struct idal_buffer *ib)
+static inline void idal_buffer_free(struct idal_buffer *ib)
{
int nr_chunks, nr_ptrs, i;
+ void *vaddr;
- nr_ptrs = (ib->size + IDA_BLOCK_SIZE - 1) >> IDA_SIZE_LOG;
- nr_chunks = (4096 << ib->page_order) >> IDA_SIZE_LOG;
- for (i = 0; i < nr_ptrs; i += nr_chunks)
- free_pages((unsigned long) ib->data[i], ib->page_order);
+ nr_ptrs = (ib->size + IDA_BLOCK_SIZE - 1) >> IDA_SIZE_SHIFT;
+ nr_chunks = (PAGE_SIZE << ib->page_order) >> IDA_SIZE_SHIFT;
+ for (i = 0; i < nr_ptrs; i += nr_chunks) {
+ vaddr = dma64_to_virt(ib->data[i]);
+ free_pages((unsigned long)vaddr, ib->page_order);
+ }
kfree(ib);
}
/*
* Test if a idal list is really needed.
*/
-static inline int
-__idal_buffer_is_needed(struct idal_buffer *ib)
+static inline bool __idal_buffer_is_needed(struct idal_buffer *ib)
{
- return ib->size > (4096ul << ib->page_order) ||
- idal_is_needed(ib->data[0], ib->size);
+ if (ib->size > (PAGE_SIZE << ib->page_order))
+ return true;
+ return idal_is_needed(dma64_to_virt(ib->data[0]), ib->size);
}
/*
* Set channel data address to idal buffer.
*/
-static inline void
-idal_buffer_set_cda(struct idal_buffer *ib, struct ccw1 *ccw)
+static inline void idal_buffer_set_cda(struct idal_buffer *ib, struct ccw1 *ccw)
{
+ void *vaddr;
+
if (__idal_buffer_is_needed(ib)) {
- // setup idals;
- ccw->cda = (u32)(addr_t) ib->data;
+ /* Setup idals */
+ ccw->cda = virt_to_dma32(ib->data);
ccw->flags |= CCW_FLAG_IDA;
- } else
- // we do not need idals - use direct addressing
- ccw->cda = (u32)(addr_t) ib->data[0];
+ } else {
+ /*
+ * No idals needed - use direct addressing. Convert from
+ * dma64_t to virt and then to dma32_t only because of type
+ * checking. The physical address is known to be below 2GB.
+ */
+ vaddr = dma64_to_virt(ib->data[0]);
+ ccw->cda = virt_to_dma32(vaddr);
+ }
ccw->count = ib->size;
}
/*
* Copy count bytes from an idal buffer to user memory
*/
-static inline size_t
-idal_buffer_to_user(struct idal_buffer *ib, void __user *to, size_t count)
+static inline size_t idal_buffer_to_user(struct idal_buffer *ib, void __user *to, size_t count)
{
size_t left;
+ void *vaddr;
int i;
BUG_ON(count > ib->size);
for (i = 0; count > IDA_BLOCK_SIZE; i++) {
- left = copy_to_user(to, ib->data[i], IDA_BLOCK_SIZE);
+ vaddr = dma64_to_virt(ib->data[i]);
+ left = copy_to_user(to, vaddr, IDA_BLOCK_SIZE);
if (left)
return left + count - IDA_BLOCK_SIZE;
- to = (void __user *) to + IDA_BLOCK_SIZE;
+ to = (void __user *)to + IDA_BLOCK_SIZE;
count -= IDA_BLOCK_SIZE;
}
- return copy_to_user(to, ib->data[i], count);
+ vaddr = dma64_to_virt(ib->data[i]);
+ return copy_to_user(to, vaddr, count);
}
/*
* Copy count bytes from user memory to an idal buffer
*/
-static inline size_t
-idal_buffer_from_user(struct idal_buffer *ib, const void __user *from, size_t count)
+static inline size_t idal_buffer_from_user(struct idal_buffer *ib, const void __user *from, size_t count)
{
size_t left;
+ void *vaddr;
int i;
BUG_ON(count > ib->size);
for (i = 0; count > IDA_BLOCK_SIZE; i++) {
- left = copy_from_user(ib->data[i], from, IDA_BLOCK_SIZE);
+ vaddr = dma64_to_virt(ib->data[i]);
+ left = copy_from_user(vaddr, from, IDA_BLOCK_SIZE);
if (left)
return left + count - IDA_BLOCK_SIZE;
- from = (void __user *) from + IDA_BLOCK_SIZE;
+ from = (void __user *)from + IDA_BLOCK_SIZE;
count -= IDA_BLOCK_SIZE;
}
- return copy_from_user(ib->data[i], from, count);
+ vaddr = dma64_to_virt(ib->data[i]);
+ return copy_from_user(vaddr, from, count);
}
#endif
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index 52664105a473..95990461888f 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -23,7 +23,7 @@
#include <linux/mmu_notifier.h>
#include <asm/debug.h>
#include <asm/cpu.h>
-#include <asm/fpu/api.h>
+#include <asm/fpu.h>
#include <asm/isc.h>
#include <asm/guarded_storage.h>
@@ -743,7 +743,6 @@ struct kvm_vcpu_arch {
struct kvm_s390_sie_block *vsie_block;
unsigned int host_acrs[NUM_ACRS];
struct gs_cb *host_gscb;
- struct fpu host_fpregs;
struct kvm_s390_local_interrupt local_int;
struct hrtimer ckc_timer;
struct kvm_s390_pgm_info pgm;
@@ -765,6 +764,8 @@ struct kvm_vcpu_arch {
__u64 cputm_start;
bool gs_enabled;
bool skey_enabled;
+ /* Indicator if the access registers have been loaded from guest */
+ bool acrs_loaded;
struct kvm_s390_pv_vcpu pv;
union diag318_info diag318_info;
};
diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h
index 5dc1b6345006..8c5f16857539 100644
--- a/arch/s390/include/asm/lowcore.h
+++ b/arch/s390/include/asm/lowcore.h
@@ -157,7 +157,7 @@ struct lowcore {
__s32 preempt_count; /* 0x03a8 */
__u32 spinlock_lockval; /* 0x03ac */
__u32 spinlock_index; /* 0x03b0 */
- __u32 fpu_flags; /* 0x03b4 */
+ __u8 pad_0x03b4[0x03b8-0x03b4]; /* 0x03b4 */
__u64 percpu_offset; /* 0x03b8 */
__u8 pad_0x03c0[0x03c8-0x03c0]; /* 0x03c0 */
__u64 machine_flags; /* 0x03c8 */
diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h
index 73b9c3bf377f..9381879f7ecf 100644
--- a/arch/s390/include/asm/page.h
+++ b/arch/s390/include/asm/page.h
@@ -11,7 +11,7 @@
#include <linux/const.h>
#include <asm/types.h>
-#define _PAGE_SHIFT 12
+#define _PAGE_SHIFT CONFIG_PAGE_SHIFT
#define _PAGE_SIZE (_AC(1, UL) << _PAGE_SHIFT)
#define _PAGE_MASK (~(_PAGE_SIZE - 1))
@@ -181,9 +181,35 @@ int arch_make_page_accessible(struct page *page);
#define __PAGE_OFFSET 0x0UL
#define PAGE_OFFSET 0x0UL
-#define __pa(x) ((unsigned long)(x))
+#define __pa_nodebug(x) ((unsigned long)(x))
+
+#ifdef __DECOMPRESSOR
+
+#define __pa(x) __pa_nodebug(x)
+#define __pa32(x) __pa(x)
#define __va(x) ((void *)(unsigned long)(x))
+#else /* __DECOMPRESSOR */
+
+#ifdef CONFIG_DEBUG_VIRTUAL
+
+unsigned long __phys_addr(unsigned long x, bool is_31bit);
+
+#else /* CONFIG_DEBUG_VIRTUAL */
+
+static inline unsigned long __phys_addr(unsigned long x, bool is_31bit)
+{
+ return __pa_nodebug(x);
+}
+
+#endif /* CONFIG_DEBUG_VIRTUAL */
+
+#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))
+
+#endif /* __DECOMPRESSOR */
+
#define phys_to_pfn(phys) ((phys) >> PAGE_SHIFT)
#define pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT)
@@ -205,7 +231,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(virt_to_pfn(kaddr))
+#define virt_addr_valid(kaddr) pfn_valid(phys_to_pfn(__pa_nodebug(kaddr)))
#define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_NON_EXEC
diff --git a/arch/s390/include/asm/pai.h b/arch/s390/include/asm/pai.h
index 7d1888e3dee6..3f609565734b 100644
--- a/arch/s390/include/asm/pai.h
+++ b/arch/s390/include/asm/pai.h
@@ -16,7 +16,7 @@ struct qpaci_info_block {
u64 header;
struct {
u64 : 8;
- u64 num_cc : 8; /* # of supported crypto counters */
+ u64 num_cc : 8; /* # of supported crypto counters */
u64 : 9;
u64 num_nnpa : 7; /* # of supported NNPA counters */
u64 : 32;
@@ -81,4 +81,5 @@ enum paievt_mode {
PAI_MODE_COUNTING,
};
+#define PAI_SAVE_AREA(x) ((x)->hw.event_base)
#endif
diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h
index e91cd6bbc330..30820a649e6e 100644
--- a/arch/s390/include/asm/pci.h
+++ b/arch/s390/include/asm/pci.h
@@ -122,6 +122,7 @@ struct zpci_dev {
struct rcu_head rcu;
struct hotplug_slot hotplug_slot;
+ struct mutex state_lock; /* protect state changes */
enum zpci_state state;
u32 fid; /* function ID, used by sclp */
u32 fh; /* function handle, used by insn's */
@@ -142,7 +143,6 @@ struct zpci_dev {
u8 reserved : 2;
unsigned int devfn; /* DEVFN part of the RID*/
- struct mutex lock;
u8 pfip[CLP_PFIP_NR_SEGMENTS]; /* pci function internal path */
u32 uid; /* user defined id */
u8 util_str[CLP_UTIL_STR_LEN]; /* utility string */
@@ -170,6 +170,7 @@ struct zpci_dev {
u64 dma_mask; /* DMA address space mask */
/* Function measurement block */
+ struct mutex fmb_lock;
struct zpci_fmb *fmb;
u16 fmb_update; /* update interval */
u16 fmb_length;
diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h
index 502d655fe6ae..7b84ef6dc4b6 100644
--- a/arch/s390/include/asm/pgalloc.h
+++ b/arch/s390/include/asm/pgalloc.h
@@ -23,9 +23,9 @@ unsigned long *crst_table_alloc(struct mm_struct *);
void crst_table_free(struct mm_struct *, unsigned long *);
unsigned long *page_table_alloc(struct mm_struct *);
-struct page *page_table_alloc_pgste(struct mm_struct *mm);
+struct ptdesc *page_table_alloc_pgste(struct mm_struct *mm);
void page_table_free(struct mm_struct *, unsigned long *);
-void page_table_free_pgste(struct page *page);
+void page_table_free_pgste(struct ptdesc *ptdesc);
extern int page_table_allocate_pgste;
static inline void crst_table_init(unsigned long *crst, unsigned long entry)
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index 1299b56e43f6..60950e7a25f5 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -705,23 +705,23 @@ static inline int pud_none(pud_t pud)
return pud_val(pud) == _REGION3_ENTRY_EMPTY;
}
-#define pud_leaf pud_large
-static inline int pud_large(pud_t pud)
+#define pud_leaf pud_leaf
+static inline bool pud_leaf(pud_t pud)
{
if ((pud_val(pud) & _REGION_ENTRY_TYPE_MASK) != _REGION_ENTRY_TYPE_R3)
return 0;
return !!(pud_val(pud) & _REGION3_ENTRY_LARGE);
}
-#define pmd_leaf pmd_large
-static inline int pmd_large(pmd_t pmd)
+#define pmd_leaf pmd_leaf
+static inline bool pmd_leaf(pmd_t pmd)
{
return (pmd_val(pmd) & _SEGMENT_ENTRY_LARGE) != 0;
}
static inline int pmd_bad(pmd_t pmd)
{
- if ((pmd_val(pmd) & _SEGMENT_ENTRY_TYPE_MASK) > 0 || pmd_large(pmd))
+ if ((pmd_val(pmd) & _SEGMENT_ENTRY_TYPE_MASK) > 0 || pmd_leaf(pmd))
return 1;
return (pmd_val(pmd) & ~_SEGMENT_ENTRY_BITS) != 0;
}
@@ -730,7 +730,7 @@ static inline int pud_bad(pud_t pud)
{
unsigned long type = pud_val(pud) & _REGION_ENTRY_TYPE_MASK;
- if (type > _REGION_ENTRY_TYPE_R3 || pud_large(pud))
+ if (type > _REGION_ENTRY_TYPE_R3 || pud_leaf(pud))
return 1;
if (type < _REGION_ENTRY_TYPE_R3)
return 0;
@@ -820,8 +820,8 @@ static inline int pte_protnone(pte_t pte)
static inline int pmd_protnone(pmd_t pmd)
{
- /* pmd_large(pmd) implies pmd_present(pmd) */
- return pmd_large(pmd) && !(pmd_val(pmd) & _SEGMENT_ENTRY_READ);
+ /* pmd_leaf(pmd) implies pmd_present(pmd) */
+ return pmd_leaf(pmd) && !(pmd_val(pmd) & _SEGMENT_ENTRY_READ);
}
#endif
@@ -1316,6 +1316,8 @@ pgprot_t pgprot_writecombine(pgprot_t prot);
#define pgprot_writethrough pgprot_writethrough
pgprot_t pgprot_writethrough(pgprot_t prot);
+#define PFN_PTE_SHIFT PAGE_SHIFT
+
/*
* Set multiple PTEs to consecutive pages with a single call. All PTEs
* are within the same folio, PMD and VMA.
@@ -1383,7 +1385,7 @@ static inline unsigned long pmd_deref(pmd_t pmd)
unsigned long origin_mask;
origin_mask = _SEGMENT_ENTRY_ORIGIN;
- if (pmd_large(pmd))
+ if (pmd_leaf(pmd))
origin_mask = _SEGMENT_ENTRY_ORIGIN_LARGE;
return (unsigned long)__va(pmd_val(pmd) & origin_mask);
}
@@ -1398,7 +1400,7 @@ static inline unsigned long pud_deref(pud_t pud)
unsigned long origin_mask;
origin_mask = _REGION_ENTRY_ORIGIN;
- if (pud_large(pud))
+ if (pud_leaf(pud))
origin_mask = _REGION3_ENTRY_ORIGIN_LARGE;
return (unsigned long)__va(pud_val(pud) & origin_mask);
}
diff --git a/arch/s390/include/asm/physmem_info.h b/arch/s390/include/asm/physmem_info.h
index 9e41a74fce9a..e747b067f8db 100644
--- a/arch/s390/include/asm/physmem_info.h
+++ b/arch/s390/include/asm/physmem_info.h
@@ -22,6 +22,7 @@ enum reserved_range_type {
RR_DECOMPRESSOR,
RR_INITRD,
RR_VMLINUX,
+ RR_RELOC,
RR_AMODE31,
RR_IPLREPORT,
RR_CERT_COMP_LIST,
diff --git a/arch/s390/include/asm/preempt.h b/arch/s390/include/asm/preempt.h
index bf15da0fedbc..0e3da500e98c 100644
--- a/arch/s390/include/asm/preempt.h
+++ b/arch/s390/include/asm/preempt.h
@@ -12,12 +12,12 @@
#define PREEMPT_NEED_RESCHED 0x80000000
#define PREEMPT_ENABLED (0 + PREEMPT_NEED_RESCHED)
-static inline int preempt_count(void)
+static __always_inline int preempt_count(void)
{
return READ_ONCE(S390_lowcore.preempt_count) & ~PREEMPT_NEED_RESCHED;
}
-static inline void preempt_count_set(int pc)
+static __always_inline void preempt_count_set(int pc)
{
int old, new;
@@ -29,22 +29,22 @@ static inline void preempt_count_set(int pc)
old, new) != old);
}
-static inline void set_preempt_need_resched(void)
+static __always_inline void set_preempt_need_resched(void)
{
__atomic_and(~PREEMPT_NEED_RESCHED, &S390_lowcore.preempt_count);
}
-static inline void clear_preempt_need_resched(void)
+static __always_inline void clear_preempt_need_resched(void)
{
__atomic_or(PREEMPT_NEED_RESCHED, &S390_lowcore.preempt_count);
}
-static inline bool test_preempt_need_resched(void)
+static __always_inline bool test_preempt_need_resched(void)
{
return !(READ_ONCE(S390_lowcore.preempt_count) & PREEMPT_NEED_RESCHED);
}
-static inline void __preempt_count_add(int val)
+static __always_inline void __preempt_count_add(int val)
{
/*
* With some obscure config options and CONFIG_PROFILE_ALL_BRANCHES
@@ -59,17 +59,17 @@ static inline void __preempt_count_add(int val)
__atomic_add(val, &S390_lowcore.preempt_count);
}
-static inline void __preempt_count_sub(int val)
+static __always_inline void __preempt_count_sub(int val)
{
__preempt_count_add(-val);
}
-static inline bool __preempt_count_dec_and_test(void)
+static __always_inline bool __preempt_count_dec_and_test(void)
{
return __atomic_add(-1, &S390_lowcore.preempt_count) == 1;
}
-static inline bool should_resched(int preempt_offset)
+static __always_inline bool should_resched(int preempt_offset)
{
return unlikely(READ_ONCE(S390_lowcore.preempt_count) ==
preempt_offset);
@@ -79,45 +79,45 @@ static inline bool should_resched(int preempt_offset)
#define PREEMPT_ENABLED (0)
-static inline int preempt_count(void)
+static __always_inline int preempt_count(void)
{
return READ_ONCE(S390_lowcore.preempt_count);
}
-static inline void preempt_count_set(int pc)
+static __always_inline void preempt_count_set(int pc)
{
S390_lowcore.preempt_count = pc;
}
-static inline void set_preempt_need_resched(void)
+static __always_inline void set_preempt_need_resched(void)
{
}
-static inline void clear_preempt_need_resched(void)
+static __always_inline void clear_preempt_need_resched(void)
{
}
-static inline bool test_preempt_need_resched(void)
+static __always_inline bool test_preempt_need_resched(void)
{
return false;
}
-static inline void __preempt_count_add(int val)
+static __always_inline void __preempt_count_add(int val)
{
S390_lowcore.preempt_count += val;
}
-static inline void __preempt_count_sub(int val)
+static __always_inline void __preempt_count_sub(int val)
{
S390_lowcore.preempt_count -= val;
}
-static inline bool __preempt_count_dec_and_test(void)
+static __always_inline bool __preempt_count_dec_and_test(void)
{
return !--S390_lowcore.preempt_count && tif_need_resched();
}
-static inline bool should_resched(int preempt_offset)
+static __always_inline bool should_resched(int preempt_offset)
{
return unlikely(preempt_count() == preempt_offset &&
tif_need_resched());
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h
index c0b6e74d899a..db9982f0e8cd 100644
--- a/arch/s390/include/asm/processor.h
+++ b/arch/s390/include/asm/processor.h
@@ -14,14 +14,14 @@
#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_FPU 3 /* restore FPU registers */
#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_FPU BIT(CIF_FPU)
#define _CIF_ENABLED_WAIT BIT(CIF_ENABLED_WAIT)
#define _CIF_MCCK_GUEST BIT(CIF_MCCK_GUEST)
#define _CIF_DEDICATED_CPU BIT(CIF_DEDICATED_CPU)
@@ -33,13 +33,12 @@
#include <linux/cpumask.h>
#include <linux/linkage.h>
#include <linux/irqflags.h>
+#include <asm/fpu-types.h>
#include <asm/cpu.h>
#include <asm/page.h>
#include <asm/ptrace.h>
#include <asm/setup.h>
#include <asm/runtime_instr.h>
-#include <asm/fpu/types.h>
-#include <asm/fpu/internal.h>
#include <asm/irqflags.h>
typedef long (*sys_call_ptr_t)(struct pt_regs *regs);
@@ -169,6 +168,8 @@ struct thread_struct {
unsigned int gmap_write_flag; /* gmap fault write indication */
unsigned int gmap_int_code; /* int code of last gmap fault */
unsigned int gmap_pfault; /* signal of a pending guest pfault */
+ int ufpu_flags; /* user fpu flags */
+ int kfpu_flags; /* kernel fpu flags */
/* Per-thread information related to debugging */
struct per_regs per_user; /* User specified PER registers */
@@ -184,7 +185,8 @@ struct thread_struct {
struct gs_cb *gs_cb; /* Current guarded storage cb */
struct gs_cb *gs_bc_cb; /* Broadcast guarded storage cb */
struct pgm_tdb trap_tdb; /* Transaction abort diagnose block */
- struct fpu fpu; /* FP and VX register save area */
+ struct fpu ufpu; /* User FP and VX register save area */
+ struct fpu kfpu; /* Kernel FP and VX register save area */
};
/* Flag to disable transactions. */
@@ -203,7 +205,6 @@ typedef struct thread_struct thread_struct;
#define INIT_THREAD { \
.ksp = sizeof(init_stack) + (unsigned long) &init_stack, \
- .fpu.regs = (void *) init_task.thread.fpu.fprs, \
.last_break = 1, \
}
diff --git a/arch/s390/include/asm/ptdump.h b/arch/s390/include/asm/ptdump.h
deleted file mode 100644
index f960b2896606..000000000000
--- a/arch/s390/include/asm/ptdump.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-#ifndef _ASM_S390_PTDUMP_H
-#define _ASM_S390_PTDUMP_H
-
-void ptdump_check_wx(void);
-
-static inline void debug_checkwx(void)
-{
- if (IS_ENABLED(CONFIG_DEBUG_WX))
- ptdump_check_wx();
-}
-
-#endif /* _ASM_S390_PTDUMP_H */
diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h
index d28bf8fb2799..2ad9324f6338 100644
--- a/arch/s390/include/asm/ptrace.h
+++ b/arch/s390/include/asm/ptrace.h
@@ -14,13 +14,11 @@
#define PIF_SYSCALL 0 /* inside a system call */
#define PIF_EXECVE_PGSTE_RESTART 1 /* restart execve for PGSTE binaries */
#define PIF_SYSCALL_RET_SET 2 /* return value was set via ptrace */
-#define PIF_GUEST_FAULT 3 /* indicates program check in sie64a */
#define PIF_FTRACE_FULL_REGS 4 /* all register contents valid (ftrace) */
#define _PIF_SYSCALL BIT(PIF_SYSCALL)
#define _PIF_EXECVE_PGSTE_RESTART BIT(PIF_EXECVE_PGSTE_RESTART)
#define _PIF_SYSCALL_RET_SET BIT(PIF_SYSCALL_RET_SET)
-#define _PIF_GUEST_FAULT BIT(PIF_GUEST_FAULT)
#define _PIF_FTRACE_FULL_REGS BIT(PIF_FTRACE_FULL_REGS)
#define PSW32_MASK_PER _AC(0x40000000, UL)
@@ -203,6 +201,10 @@ static inline int test_and_clear_pt_regs_flag(struct pt_regs *regs, int flag)
return ret;
}
+struct task_struct;
+
+void update_cr_regs(struct task_struct *task);
+
/*
* These are defined as per linux/ptrace.h, which see.
*/
diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h
index 2f983e0b95e0..69c4ead0c332 100644
--- a/arch/s390/include/asm/qdio.h
+++ b/arch/s390/include/asm/qdio.h
@@ -9,8 +9,9 @@
#define __QDIO_H__
#include <linux/interrupt.h>
-#include <asm/cio.h>
+#include <asm/dma-types.h>
#include <asm/ccwdev.h>
+#include <asm/cio.h>
/* only use 4 queues to save some cachelines */
#define QDIO_MAX_QUEUES_PER_IRQ 4
@@ -34,9 +35,9 @@
* @dkey: access key for SLSB
*/
struct qdesfmt0 {
- u64 sliba;
- u64 sla;
- u64 slsba;
+ dma64_t sliba;
+ dma64_t sla;
+ dma64_t slsba;
u32 : 32;
u32 akey : 4;
u32 bkey : 4;
@@ -74,7 +75,7 @@ struct qdr {
/* private: */
u32 res[9];
/* public: */
- u64 qiba;
+ dma64_t qiba;
u32 : 32;
u32 qkey : 4;
u32 : 28;
@@ -146,7 +147,7 @@ struct qaob {
u8 flags;
u16 cbtbs;
u8 sb_count;
- u64 sba[QDIO_MAX_ELEMENTS_PER_BUFFER];
+ dma64_t sba[QDIO_MAX_ELEMENTS_PER_BUFFER];
u16 dcount[QDIO_MAX_ELEMENTS_PER_BUFFER];
u64 user0;
u64 res4[2];
@@ -208,7 +209,7 @@ struct qdio_buffer_element {
u8 scount;
u8 sflags;
u32 length;
- u64 addr;
+ dma64_t addr;
} __attribute__ ((packed, aligned(16)));
/**
@@ -224,7 +225,7 @@ struct qdio_buffer {
* @sbal: absolute SBAL address
*/
struct sl_element {
- u64 sbal;
+ dma64_t sbal;
} __attribute__ ((packed));
/**
diff --git a/arch/s390/include/asm/scsw.h b/arch/s390/include/asm/scsw.h
index 322bdcd4b616..56003e26cdbf 100644
--- a/arch/s390/include/asm/scsw.h
+++ b/arch/s390/include/asm/scsw.h
@@ -11,6 +11,7 @@
#include <linux/types.h>
#include <asm/css_chars.h>
+#include <asm/dma-types.h>
#include <asm/cio.h>
/**
@@ -53,7 +54,7 @@ struct cmd_scsw {
__u32 fctl : 3;
__u32 actl : 7;
__u32 stctl : 5;
- __u32 cpa;
+ dma32_t cpa;
__u32 dstat : 8;
__u32 cstat : 8;
__u32 count : 16;
@@ -93,7 +94,7 @@ struct tm_scsw {
u32 fctl:3;
u32 actl:7;
u32 stctl:5;
- u32 tcw;
+ dma32_t tcw;
u32 dstat:8;
u32 cstat:8;
u32 fcxs:8;
@@ -125,7 +126,7 @@ struct eadm_scsw {
u32 fctl:3;
u32 actl:7;
u32 stctl:5;
- u32 aob;
+ dma32_t aob;
u32 dstat:8;
u32 cstat:8;
u32:16;
diff --git a/arch/s390/include/asm/stacktrace.h b/arch/s390/include/asm/stacktrace.h
index 31ec4f545e03..433fde85b14e 100644
--- a/arch/s390/include/asm/stacktrace.h
+++ b/arch/s390/include/asm/stacktrace.h
@@ -4,7 +4,6 @@
#include <linux/uaccess.h>
#include <linux/ptrace.h>
-#include <asm/switch_to.h>
struct stack_frame_user {
unsigned long back_chain;
diff --git a/arch/s390/include/asm/switch_to.h b/arch/s390/include/asm/switch_to.h
deleted file mode 100644
index c61b2cc1a8a8..000000000000
--- a/arch/s390/include/asm/switch_to.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright IBM Corp. 1999, 2009
- *
- * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
- */
-
-#ifndef __ASM_SWITCH_TO_H
-#define __ASM_SWITCH_TO_H
-
-#include <linux/thread_info.h>
-#include <asm/fpu/api.h>
-#include <asm/ptrace.h>
-#include <asm/guarded_storage.h>
-
-extern struct task_struct *__switch_to(void *, void *);
-extern void update_cr_regs(struct task_struct *task);
-
-static inline void save_access_regs(unsigned int *acrs)
-{
- typedef struct { int _[NUM_ACRS]; } acrstype;
-
- asm volatile("stam 0,15,%0" : "=Q" (*(acrstype *)acrs));
-}
-
-static inline void restore_access_regs(unsigned int *acrs)
-{
- typedef struct { int _[NUM_ACRS]; } acrstype;
-
- asm volatile("lam 0,15,%0" : : "Q" (*(acrstype *)acrs));
-}
-
-#define switch_to(prev, next, last) do { \
- /* save_fpu_regs() sets the CIF_FPU flag, which enforces \
- * a restore of the floating point / vector registers as \
- * soon as the next task returns to user space \
- */ \
- save_fpu_regs(); \
- save_access_regs(&prev->thread.acrs[0]); \
- save_ri_cb(prev->thread.ri_cb); \
- save_gs_cb(prev->thread.gs_cb); \
- update_cr_regs(next); \
- restore_access_regs(&next->thread.acrs[0]); \
- restore_ri_cb(next->thread.ri_cb, prev->thread.ri_cb); \
- restore_gs_cb(next->thread.gs_cb); \
- prev = __switch_to(prev, next); \
-} while (0)
-
-#endif /* __ASM_SWITCH_TO_H */
diff --git a/arch/s390/include/asm/tlb.h b/arch/s390/include/asm/tlb.h
index d1455a601adc..e95b2c8081eb 100644
--- a/arch/s390/include/asm/tlb.h
+++ b/arch/s390/include/asm/tlb.h
@@ -25,8 +25,9 @@
void __tlb_remove_table(void *_table);
static inline void tlb_flush(struct mmu_gather *tlb);
static inline bool __tlb_remove_page_size(struct mmu_gather *tlb,
- struct encoded_page *page,
- int page_size);
+ struct page *page, bool delay_rmap, int page_size);
+static inline bool __tlb_remove_folio_pages(struct mmu_gather *tlb,
+ struct page *page, unsigned int nr_pages, bool delay_rmap);
#define tlb_flush tlb_flush
#define pte_free_tlb pte_free_tlb
@@ -42,14 +43,29 @@ static inline bool __tlb_remove_page_size(struct mmu_gather *tlb,
* tlb_ptep_clear_flush. In both flush modes the tlb for a page cache page
* has already been freed, so just do free_page_and_swap_cache.
*
- * s390 doesn't delay rmap removal, so there is nothing encoded in
- * the page pointer.
+ * s390 doesn't delay rmap removal.
*/
static inline bool __tlb_remove_page_size(struct mmu_gather *tlb,
- struct encoded_page *page,
- int page_size)
+ struct page *page, bool delay_rmap, int page_size)
{
- free_page_and_swap_cache(encoded_page_ptr(page));
+ VM_WARN_ON_ONCE(delay_rmap);
+
+ free_page_and_swap_cache(page);
+ return false;
+}
+
+static inline bool __tlb_remove_folio_pages(struct mmu_gather *tlb,
+ struct page *page, unsigned int nr_pages, bool delay_rmap)
+{
+ struct encoded_page *encoded_pages[] = {
+ encode_page(page, ENCODED_PAGE_BIT_NR_PAGES_NEXT),
+ encode_nr_pages(nr_pages),
+ };
+
+ VM_WARN_ON_ONCE(delay_rmap);
+ VM_WARN_ON_ONCE(page_folio(page) != page_folio(page + nr_pages - 1));
+
+ free_pages_and_swap_cache(encoded_pages, ARRAY_SIZE(encoded_pages));
return false;
}
diff --git a/arch/s390/include/asm/vdso/data.h b/arch/s390/include/asm/vdso/data.h
index 73ee89142666..0e2b40ef69b0 100644
--- a/arch/s390/include/asm/vdso/data.h
+++ b/arch/s390/include/asm/vdso/data.h
@@ -3,7 +3,6 @@
#define __S390_ASM_VDSO_DATA_H
#include <linux/types.h>
-#include <vdso/datapage.h>
struct arch_vdso_data {
__s64 tod_steering_delta;
diff --git a/arch/s390/include/asm/vx-insn.h b/arch/s390/include/asm/vx-insn.h
deleted file mode 100644
index 8c188f1c6d27..000000000000
--- a/arch/s390/include/asm/vx-insn.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Support for Vector Instructions
- *
- * This wrapper header file allows to use the vector instruction macros in
- * both assembler files as well as in inline assemblies in C files.
- */
-
-#ifndef __ASM_S390_VX_INSN_H
-#define __ASM_S390_VX_INSN_H
-
-#include <asm/vx-insn-asm.h>
-
-#ifndef __ASSEMBLY__
-
-asm(".include \"asm/vx-insn-asm.h\"\n");
-
-#endif /* __ASSEMBLY__ */
-#endif /* __ASM_S390_VX_INSN_H */
diff --git a/arch/s390/include/asm/word-at-a-time.h b/arch/s390/include/asm/word-at-a-time.h
index 2579f1694b82..203acd6e431b 100644
--- a/arch/s390/include/asm/word-at-a-time.h
+++ b/arch/s390/include/asm/word-at-a-time.h
@@ -2,7 +2,8 @@
#ifndef _ASM_WORD_AT_A_TIME_H
#define _ASM_WORD_AT_A_TIME_H
-#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/wordpart.h>
#include <asm/asm-extable.h>
#include <asm/bitsperlong.h>
diff --git a/arch/s390/include/uapi/asm/kvm.h b/arch/s390/include/uapi/asm/kvm.h
index abe926d43cbe..05eaf6db3ad4 100644
--- a/arch/s390/include/uapi/asm/kvm.h
+++ b/arch/s390/include/uapi/asm/kvm.h
@@ -12,7 +12,320 @@
#include <linux/types.h>
#define __KVM_S390
-#define __KVM_HAVE_GUEST_DEBUG
+
+struct kvm_s390_skeys {
+ __u64 start_gfn;
+ __u64 count;
+ __u64 skeydata_addr;
+ __u32 flags;
+ __u32 reserved[9];
+};
+
+#define KVM_S390_CMMA_PEEK (1 << 0)
+
+/**
+ * kvm_s390_cmma_log - Used for CMMA migration.
+ *
+ * Used both for input and output.
+ *
+ * @start_gfn: Guest page number to start from.
+ * @count: Size of the result buffer.
+ * @flags: Control operation mode via KVM_S390_CMMA_* flags
+ * @remaining: Used with KVM_S390_GET_CMMA_BITS. Indicates how many dirty
+ * pages are still remaining.
+ * @mask: Used with KVM_S390_SET_CMMA_BITS. Bitmap of bits to actually set
+ * in the PGSTE.
+ * @values: Pointer to the values buffer.
+ *
+ * Used in KVM_S390_{G,S}ET_CMMA_BITS ioctls.
+ */
+struct kvm_s390_cmma_log {
+ __u64 start_gfn;
+ __u32 count;
+ __u32 flags;
+ union {
+ __u64 remaining;
+ __u64 mask;
+ };
+ __u64 values;
+};
+
+#define KVM_S390_RESET_POR 1
+#define KVM_S390_RESET_CLEAR 2
+#define KVM_S390_RESET_SUBSYSTEM 4
+#define KVM_S390_RESET_CPU_INIT 8
+#define KVM_S390_RESET_IPL 16
+
+/* for KVM_S390_MEM_OP */
+struct kvm_s390_mem_op {
+ /* in */
+ __u64 gaddr; /* the guest address */
+ __u64 flags; /* flags */
+ __u32 size; /* amount of bytes */
+ __u32 op; /* type of operation */
+ __u64 buf; /* buffer in userspace */
+ union {
+ struct {
+ __u8 ar; /* the access register number */
+ __u8 key; /* access key, ignored if flag unset */
+ __u8 pad1[6]; /* ignored */
+ __u64 old_addr; /* ignored if cmpxchg flag unset */
+ };
+ __u32 sida_offset; /* offset into the sida */
+ __u8 reserved[32]; /* ignored */
+ };
+};
+/* types for kvm_s390_mem_op->op */
+#define KVM_S390_MEMOP_LOGICAL_READ 0
+#define KVM_S390_MEMOP_LOGICAL_WRITE 1
+#define KVM_S390_MEMOP_SIDA_READ 2
+#define KVM_S390_MEMOP_SIDA_WRITE 3
+#define KVM_S390_MEMOP_ABSOLUTE_READ 4
+#define KVM_S390_MEMOP_ABSOLUTE_WRITE 5
+#define KVM_S390_MEMOP_ABSOLUTE_CMPXCHG 6
+
+/* flags for kvm_s390_mem_op->flags */
+#define KVM_S390_MEMOP_F_CHECK_ONLY (1ULL << 0)
+#define KVM_S390_MEMOP_F_INJECT_EXCEPTION (1ULL << 1)
+#define KVM_S390_MEMOP_F_SKEY_PROTECTION (1ULL << 2)
+
+/* flags specifying extension support via KVM_CAP_S390_MEM_OP_EXTENSION */
+#define KVM_S390_MEMOP_EXTENSION_CAP_BASE (1 << 0)
+#define KVM_S390_MEMOP_EXTENSION_CAP_CMPXCHG (1 << 1)
+
+struct kvm_s390_psw {
+ __u64 mask;
+ __u64 addr;
+};
+
+/* valid values for type in kvm_s390_interrupt */
+#define KVM_S390_SIGP_STOP 0xfffe0000u
+#define KVM_S390_PROGRAM_INT 0xfffe0001u
+#define KVM_S390_SIGP_SET_PREFIX 0xfffe0002u
+#define KVM_S390_RESTART 0xfffe0003u
+#define KVM_S390_INT_PFAULT_INIT 0xfffe0004u
+#define KVM_S390_INT_PFAULT_DONE 0xfffe0005u
+#define KVM_S390_MCHK 0xfffe1000u
+#define KVM_S390_INT_CLOCK_COMP 0xffff1004u
+#define KVM_S390_INT_CPU_TIMER 0xffff1005u
+#define KVM_S390_INT_VIRTIO 0xffff2603u
+#define KVM_S390_INT_SERVICE 0xffff2401u
+#define KVM_S390_INT_EMERGENCY 0xffff1201u
+#define KVM_S390_INT_EXTERNAL_CALL 0xffff1202u
+/* Anything below 0xfffe0000u is taken by INT_IO */
+#define KVM_S390_INT_IO(ai,cssid,ssid,schid) \
+ (((schid)) | \
+ ((ssid) << 16) | \
+ ((cssid) << 18) | \
+ ((ai) << 26))
+#define KVM_S390_INT_IO_MIN 0x00000000u
+#define KVM_S390_INT_IO_MAX 0xfffdffffu
+#define KVM_S390_INT_IO_AI_MASK 0x04000000u
+
+
+struct kvm_s390_interrupt {
+ __u32 type;
+ __u32 parm;
+ __u64 parm64;
+};
+
+struct kvm_s390_io_info {
+ __u16 subchannel_id;
+ __u16 subchannel_nr;
+ __u32 io_int_parm;
+ __u32 io_int_word;
+};
+
+struct kvm_s390_ext_info {
+ __u32 ext_params;
+ __u32 pad;
+ __u64 ext_params2;
+};
+
+struct kvm_s390_pgm_info {
+ __u64 trans_exc_code;
+ __u64 mon_code;
+ __u64 per_address;
+ __u32 data_exc_code;
+ __u16 code;
+ __u16 mon_class_nr;
+ __u8 per_code;
+ __u8 per_atmid;
+ __u8 exc_access_id;
+ __u8 per_access_id;
+ __u8 op_access_id;
+#define KVM_S390_PGM_FLAGS_ILC_VALID 0x01
+#define KVM_S390_PGM_FLAGS_ILC_0 0x02
+#define KVM_S390_PGM_FLAGS_ILC_1 0x04
+#define KVM_S390_PGM_FLAGS_ILC_MASK 0x06
+#define KVM_S390_PGM_FLAGS_NO_REWIND 0x08
+ __u8 flags;
+ __u8 pad[2];
+};
+
+struct kvm_s390_prefix_info {
+ __u32 address;
+};
+
+struct kvm_s390_extcall_info {
+ __u16 code;
+};
+
+struct kvm_s390_emerg_info {
+ __u16 code;
+};
+
+#define KVM_S390_STOP_FLAG_STORE_STATUS 0x01
+struct kvm_s390_stop_info {
+ __u32 flags;
+};
+
+struct kvm_s390_mchk_info {
+ __u64 cr14;
+ __u64 mcic;
+ __u64 failing_storage_address;
+ __u32 ext_damage_code;
+ __u32 pad;
+ __u8 fixed_logout[16];
+};
+
+struct kvm_s390_irq {
+ __u64 type;
+ union {
+ struct kvm_s390_io_info io;
+ struct kvm_s390_ext_info ext;
+ struct kvm_s390_pgm_info pgm;
+ struct kvm_s390_emerg_info emerg;
+ struct kvm_s390_extcall_info extcall;
+ struct kvm_s390_prefix_info prefix;
+ struct kvm_s390_stop_info stop;
+ struct kvm_s390_mchk_info mchk;
+ char reserved[64];
+ } u;
+};
+
+struct kvm_s390_irq_state {
+ __u64 buf;
+ __u32 flags; /* will stay unused for compatibility reasons */
+ __u32 len;
+ __u32 reserved[4]; /* will stay unused for compatibility reasons */
+};
+
+struct kvm_s390_ucas_mapping {
+ __u64 user_addr;
+ __u64 vcpu_addr;
+ __u64 length;
+};
+
+struct kvm_s390_pv_sec_parm {
+ __u64 origin;
+ __u64 length;
+};
+
+struct kvm_s390_pv_unp {
+ __u64 addr;
+ __u64 size;
+ __u64 tweak;
+};
+
+enum pv_cmd_dmp_id {
+ KVM_PV_DUMP_INIT,
+ KVM_PV_DUMP_CONFIG_STOR_STATE,
+ KVM_PV_DUMP_COMPLETE,
+ KVM_PV_DUMP_CPU,
+};
+
+struct kvm_s390_pv_dmp {
+ __u64 subcmd;
+ __u64 buff_addr;
+ __u64 buff_len;
+ __u64 gaddr; /* For dump storage state */
+ __u64 reserved[4];
+};
+
+enum pv_cmd_info_id {
+ KVM_PV_INFO_VM,
+ KVM_PV_INFO_DUMP,
+};
+
+struct kvm_s390_pv_info_dump {
+ __u64 dump_cpu_buffer_len;
+ __u64 dump_config_mem_buffer_per_1m;
+ __u64 dump_config_finalize_len;
+};
+
+struct kvm_s390_pv_info_vm {
+ __u64 inst_calls_list[4];
+ __u64 max_cpus;
+ __u64 max_guests;
+ __u64 max_guest_addr;
+ __u64 feature_indication;
+};
+
+struct kvm_s390_pv_info_header {
+ __u32 id;
+ __u32 len_max;
+ __u32 len_written;
+ __u32 reserved;
+};
+
+struct kvm_s390_pv_info {
+ struct kvm_s390_pv_info_header header;
+ union {
+ struct kvm_s390_pv_info_dump dump;
+ struct kvm_s390_pv_info_vm vm;
+ };
+};
+
+enum pv_cmd_id {
+ KVM_PV_ENABLE,
+ KVM_PV_DISABLE,
+ KVM_PV_SET_SEC_PARMS,
+ KVM_PV_UNPACK,
+ KVM_PV_VERIFY,
+ KVM_PV_PREP_RESET,
+ KVM_PV_UNSHARE_ALL,
+ KVM_PV_INFO,
+ KVM_PV_DUMP,
+ KVM_PV_ASYNC_CLEANUP_PREPARE,
+ KVM_PV_ASYNC_CLEANUP_PERFORM,
+};
+
+struct kvm_pv_cmd {
+ __u32 cmd; /* Command to be executed */
+ __u16 rc; /* Ultravisor return code */
+ __u16 rrc; /* Ultravisor return reason code */
+ __u64 data; /* Data or address */
+ __u32 flags; /* flags for future extensions. Must be 0 for now */
+ __u32 reserved[3];
+};
+
+struct kvm_s390_zpci_op {
+ /* in */
+ __u32 fh; /* target device */
+ __u8 op; /* operation to perform */
+ __u8 pad[3];
+ union {
+ /* for KVM_S390_ZPCIOP_REG_AEN */
+ struct {
+ __u64 ibv; /* Guest addr of interrupt bit vector */
+ __u64 sb; /* Guest addr of summary bit */
+ __u32 flags;
+ __u32 noi; /* Number of interrupts */
+ __u8 isc; /* Guest interrupt subclass */
+ __u8 sbo; /* Offset of guest summary bit vector */
+ __u16 pad;
+ } reg_aen;
+ __u64 reserved[8];
+ } u;
+};
+
+/* types for kvm_s390_zpci_op->op */
+#define KVM_S390_ZPCIOP_REG_AEN 0
+#define KVM_S390_ZPCIOP_DEREG_AEN 1
+
+/* flags for kvm_s390_zpci_op->u.reg_aen.flags */
+#define KVM_S390_ZPCIOP_REGAEN_HOST (1 << 0)
/* Device control API: s390-specific devices */
#define KVM_DEV_FLIC_GET_ALL_IRQS 1
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index 7a562b4199c8..fa029d0dc28f 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -64,6 +64,7 @@ obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o
obj-$(CONFIG_FUNCTION_TRACER) += mcount.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_KEXEC_CORE) += machine_kexec.o relocate_kernel.o
+obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o
obj-$(CONFIG_UPROBES) += uprobes.o
obj-$(CONFIG_JUMP_LABEL) += jump_label.o
diff --git a/arch/s390/kernel/cache.c b/arch/s390/kernel/cache.c
index 56254fa06f99..4f2669030220 100644
--- a/arch/s390/kernel/cache.c
+++ b/arch/s390/kernel/cache.c
@@ -166,5 +166,6 @@ int populate_cache_leaves(unsigned int cpu)
ci_leaf_init(this_leaf++, pvt, ctype, level, cpu);
}
}
+ this_cpu_ci->cpu_map_populated = true;
return 0;
}
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c
index f8fc6c25d051..1942e2a9f8db 100644
--- a/arch/s390/kernel/compat_signal.c
+++ b/arch/s390/kernel/compat_signal.c
@@ -24,12 +24,12 @@
#include <linux/tty.h>
#include <linux/personality.h>
#include <linux/binfmts.h>
+#include <asm/access-regs.h>
#include <asm/ucontext.h>
#include <linux/uaccess.h>
#include <asm/lowcore.h>
-#include <asm/switch_to.h>
#include <asm/vdso.h>
-#include <asm/fpu/api.h>
+#include <asm/fpu.h>
#include "compat_linux.h"
#include "compat_ptrace.h"
#include "entry.h"
@@ -56,7 +56,7 @@ typedef struct
static void store_sigregs(void)
{
save_access_regs(current->thread.acrs);
- save_fpu_regs();
+ save_user_fpu_regs();
}
/* Load registers after signal return */
@@ -79,7 +79,7 @@ static int save_sigregs32(struct pt_regs *regs, _sigregs32 __user *sregs)
user_sregs.regs.gprs[i] = (__u32) regs->gprs[i];
memcpy(&user_sregs.regs.acrs, current->thread.acrs,
sizeof(user_sregs.regs.acrs));
- fpregs_store((_s390_fp_regs *) &user_sregs.fpregs, &current->thread.fpu);
+ fpregs_store((_s390_fp_regs *) &user_sregs.fpregs, &current->thread.ufpu);
if (__copy_to_user(sregs, &user_sregs, sizeof(_sigregs32)))
return -EFAULT;
return 0;
@@ -113,7 +113,7 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs)
regs->gprs[i] = (__u64) user_sregs.regs.gprs[i];
memcpy(&current->thread.acrs, &user_sregs.regs.acrs,
sizeof(current->thread.acrs));
- fpregs_load((_s390_fp_regs *) &user_sregs.fpregs, &current->thread.fpu);
+ fpregs_load((_s390_fp_regs *)&user_sregs.fpregs, &current->thread.ufpu);
clear_pt_regs_flag(regs, PIF_SYSCALL); /* No longer in a system call */
return 0;
@@ -136,11 +136,11 @@ static int save_sigregs_ext32(struct pt_regs *regs,
/* Save vector registers to signal stack */
if (cpu_has_vx()) {
for (i = 0; i < __NUM_VXRS_LOW; i++)
- vxrs[i] = current->thread.fpu.vxrs[i].low;
+ vxrs[i] = current->thread.ufpu.vxrs[i].low;
if (__copy_to_user(&sregs_ext->vxrs_low, vxrs,
sizeof(sregs_ext->vxrs_low)) ||
__copy_to_user(&sregs_ext->vxrs_high,
- current->thread.fpu.vxrs + __NUM_VXRS_LOW,
+ current->thread.ufpu.vxrs + __NUM_VXRS_LOW,
sizeof(sregs_ext->vxrs_high)))
return -EFAULT;
}
@@ -165,12 +165,12 @@ static int restore_sigregs_ext32(struct pt_regs *regs,
if (cpu_has_vx()) {
if (__copy_from_user(vxrs, &sregs_ext->vxrs_low,
sizeof(sregs_ext->vxrs_low)) ||
- __copy_from_user(current->thread.fpu.vxrs + __NUM_VXRS_LOW,
+ __copy_from_user(current->thread.ufpu.vxrs + __NUM_VXRS_LOW,
&sregs_ext->vxrs_high,
sizeof(sregs_ext->vxrs_high)))
return -EFAULT;
for (i = 0; i < __NUM_VXRS_LOW; i++)
- current->thread.fpu.vxrs[i].low = vxrs[i];
+ current->thread.ufpu.vxrs[i].low = vxrs[i];
}
return 0;
}
@@ -184,7 +184,7 @@ COMPAT_SYSCALL_DEFINE0(sigreturn)
if (get_compat_sigset(&set, (compat_sigset_t __user *)frame->sc.oldmask))
goto badframe;
set_current_blocked(&set);
- save_fpu_regs();
+ save_user_fpu_regs();
if (restore_sigregs32(regs, &frame->sregs))
goto badframe;
if (restore_sigregs_ext32(regs, &frame->sregs_ext))
@@ -207,7 +207,7 @@ COMPAT_SYSCALL_DEFINE0(rt_sigreturn)
set_current_blocked(&set);
if (compat_restore_altstack(&frame->uc.uc_stack))
goto badframe;
- save_fpu_regs();
+ save_user_fpu_regs();
if (restore_sigregs32(regs, &frame->uc.uc_mcontext))
goto badframe;
if (restore_sigregs_ext32(regs, &frame->uc.uc_mcontext_ext))
diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c
index 5c46c2659305..d09ebb6f5262 100644
--- a/arch/s390/kernel/crash_dump.c
+++ b/arch/s390/kernel/crash_dump.c
@@ -22,7 +22,7 @@
#include <asm/ipl.h>
#include <asm/sclp.h>
#include <asm/maccess.h>
-#include <asm/fpu/api.h>
+#include <asm/fpu.h>
#define PTR_ADD(x, y) (((char *) (x)) + ((unsigned long) (y)))
#define PTR_SUB(x, y) (((char *) (x)) - ((unsigned long) (y)))
diff --git a/arch/s390/kernel/diag.c b/arch/s390/kernel/diag.c
index 92fdc35f028c..8dee9aa0ec95 100644
--- a/arch/s390/kernel/diag.c
+++ b/arch/s390/kernel/diag.c
@@ -147,11 +147,40 @@ void notrace diag_stat_inc_norecursion(enum diag_stat_enum nr)
EXPORT_SYMBOL(diag_stat_inc_norecursion);
/*
+ * Diagnose 0c: Pseudo Timer
+ */
+void diag0c(struct hypfs_diag0c_entry *data)
+{
+ diag_stat_inc(DIAG_STAT_X00C);
+ diag_amode31_ops.diag0c(virt_to_phys(data));
+}
+
+/*
* Diagnose 14: Input spool file manipulation
+ *
+ * The subcode parameter determines the type of the first parameter rx.
+ * Currently used are the following 3 subcommands:
+ * 0x0: Read the Next Spool File Buffer (Data Record)
+ * 0x28: Position a Spool File to the Designated Record
+ * 0xfff: Retrieve Next File Descriptor
+ *
+ * For subcommands 0x0 and 0xfff, the value of the first parameter is
+ * a virtual address of a memory buffer and needs virtual to physical
+ * address translation. For other subcommands the rx parameter is not
+ * a virtual address.
*/
int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode)
{
diag_stat_inc(DIAG_STAT_X014);
+ switch (subcode) {
+ case 0x0:
+ case 0xfff:
+ rx = virt_to_phys((void *)rx);
+ break;
+ default:
+ /* Do nothing */
+ break;
+ }
return diag_amode31_ops.diag14(rx, ry1, subcode);
}
EXPORT_SYMBOL(diag14);
@@ -265,6 +294,6 @@ EXPORT_SYMBOL(diag224);
int diag26c(void *req, void *resp, enum diag26c_sc subcode)
{
diag_stat_inc(DIAG_STAT_X26C);
- return diag_amode31_ops.diag26c(req, resp, subcode);
+ return diag_amode31_ops.diag26c(virt_to_phys(req), virt_to_phys(resp), subcode);
}
EXPORT_SYMBOL(diag26c);
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index 2345ea332b97..c666271433fb 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -19,8 +19,10 @@
#include <linux/kernel.h>
#include <asm/asm-extable.h>
#include <linux/memblock.h>
+#include <asm/access-regs.h>
#include <asm/diag.h>
#include <asm/ebcdic.h>
+#include <asm/fpu.h>
#include <asm/ipl.h>
#include <asm/lowcore.h>
#include <asm/processor.h>
@@ -31,7 +33,6 @@
#include <asm/sclp.h>
#include <asm/facility.h>
#include <asm/boot_data.h>
-#include <asm/switch_to.h>
#include "entry.h"
#define decompressor_handled_param(param) \
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 49a11f6dd7ae..3dc85638bc63 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -24,7 +24,7 @@
#include <asm/page.h>
#include <asm/sigp.h>
#include <asm/irq.h>
-#include <asm/vx-insn.h>
+#include <asm/fpu-insn.h>
#include <asm/setup.h>
#include <asm/nmi.h>
#include <asm/nospec-insn.h>
@@ -119,33 +119,11 @@ _LPP_OFFSET = __LC_LPP
.endm
#if IS_ENABLED(CONFIG_KVM)
- /*
- * The OUTSIDE macro jumps to the provided label in case the value
- * in the provided register is outside of the provided range. The
- * macro is useful for checking whether a PSW stored in a register
- * pair points inside or outside of a block of instructions.
- * @reg: register to check
- * @start: start of the range
- * @end: end of the range
- * @outside_label: jump here if @reg is outside of [@start..@end)
- */
- .macro OUTSIDE reg,start,end,outside_label
- lgr %r14,\reg
- larl %r13,\start
- slgr %r14,%r13
- clgfrl %r14,.Lrange_size\@
- jhe \outside_label
- .section .rodata, "a"
- .balign 4
-.Lrange_size\@:
- .long \end - \start
- .previous
- .endm
-
- .macro SIEEXIT
- lg %r9,__SF_SIE_CONTROL(%r15) # get control block pointer
+ .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
larl %r9,sie_exit # skip forward to sie_exit
.endm
#endif
@@ -171,13 +149,13 @@ _LPP_OFFSET = __LC_LPP
nop 0
/*
- * Scheduler resume function, called by switch_to
- * gpr2 = (task_struct *) prev
- * gpr3 = (task_struct *) next
+ * Scheduler resume function, called by __switch_to
+ * gpr2 = (task_struct *)prev
+ * gpr3 = (task_struct *)next
* Returns:
* gpr2 = prev
*/
-SYM_FUNC_START(__switch_to)
+SYM_FUNC_START(__switch_to_asm)
stmg %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task
lghi %r4,__TASK_stack
lghi %r1,__TASK_thread
@@ -193,7 +171,7 @@ SYM_FUNC_START(__switch_to)
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)
+SYM_FUNC_END(__switch_to_asm)
#if IS_ENABLED(CONFIG_KVM)
/*
@@ -214,14 +192,13 @@ SYM_FUNC_START(__sie64a)
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:
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...
jnz .Lsie_skip
- TSTMSK __LC_CPU_FLAGS,_CIF_FPU
- jo .Lsie_skip # exit if fp/vx regs changed
lg %r14,__SF_SIE_CONTROL_PHYS(%r15) # get sie block phys addr
BPEXIT __SF_SIE_FLAGS(%r15),_TIF_ISOLATE_BP_GUEST
.Lsie_entry:
@@ -236,7 +213,7 @@ SYM_FUNC_START(__sie64a)
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
-.Lsie_done:
+ ni __LC_CPU_FLAGS+7,255-_CIF_SIE
# 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.
@@ -339,20 +316,13 @@ SYM_CODE_START(pgm_check_handler)
stpt __LC_SYS_ENTER_TIMER
BPOFF
stmg %r8,%r15,__LC_SAVE_AREA_SYNC
- lghi %r10,0
+ lgr %r10,%r15
lmg %r8,%r9,__LC_PGM_OLD_PSW
tmhh %r8,0x0001 # coming from user space?
jno .Lpgm_skip_asce
lctlg %c1,%c1,__LC_KERNEL_ASCE
j 3f # -> fault in user space
.Lpgm_skip_asce:
-#if IS_ENABLED(CONFIG_KVM)
- # cleanup critical section for program checks in __sie64a
- OUTSIDE %r9,.Lsie_gmap,.Lsie_done,1f
- BPENTER __SF_SIE_FLAGS(%r15),_TIF_ISOLATE_BP_GUEST
- SIEEXIT
- lghi %r10,_PIF_GUEST_FAULT
-#endif
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
@@ -363,13 +333,20 @@ SYM_CODE_START(pgm_check_handler)
CHECK_VMAP_STACK __LC_SAVE_AREA_SYNC,4f
3: lg %r15,__LC_KERNEL_STACK
4: la %r11,STACK_FRAME_OVERHEAD(%r15)
- stg %r10,__PT_FLAGS(%r11)
+ 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
- stmg %r8,%r9,__PT_PSW(%r11)
-
+ stctg %c1,%c1,__PT_CR1(%r11)
+#if IS_ENABLED(CONFIG_KVM)
+ lg %r12,__LC_GMAP
+ clc __GMAP_ASCE(8,%r12), __PT_CR1(%r11)
+ jne 5f
+ BPENTER __SF_SIE_FLAGS(%r10),_TIF_ISOLATE_BP_GUEST
+ SIEEXIT __SF_SIE_CONTROL(%r10)
+#endif
+5: stmg %r8,%r9,__PT_PSW(%r11)
# clear user controlled registers to prevent speculative use
xgr %r0,%r0
xgr %r1,%r1
@@ -418,9 +395,10 @@ SYM_CODE_START(\name)
tmhh %r8,0x0001 # interrupting from user ?
jnz 1f
#if IS_ENABLED(CONFIG_KVM)
- OUTSIDE %r9,.Lsie_gmap,.Lsie_done,0f
+ TSTMSK __LC_CPU_FLAGS,_CIF_SIE
+ jz 0f
BPENTER __SF_SIE_FLAGS(%r15),_TIF_ISOLATE_BP_GUEST
- SIEEXIT
+ SIEEXIT __SF_SIE_CONTROL(%r15)
#endif
0: CHECK_STACK __LC_SAVE_AREA_ASYNC
aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
@@ -489,16 +467,11 @@ SYM_FUNC_END(psw_idle)
*/
SYM_CODE_START(mcck_int_handler)
BPOFF
- la %r1,4095 # validate r1
- spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # validate cpu timer
- LBEAR __LC_LAST_BREAK_SAVE_AREA-4095(%r1) # validate bear
- lmg %r0,%r15,__LC_GPREGS_SAVE_AREA # validate gprs
lmg %r8,%r9,__LC_MCK_OLD_PSW
TSTMSK __LC_MCCK_CODE,MCCK_CODE_SYSTEM_DAMAGE
jo .Lmcck_panic # yes -> rest of mcck code invalid
TSTMSK __LC_MCCK_CODE,MCCK_CODE_CR_VALID
jno .Lmcck_panic # control registers invalid -> panic
- lctlg %c0,%c15,__LC_CREGS_SAVE_AREA # validate ctl regs
ptlb
lghi %r14,__LC_CPU_TIMER_SAVE_AREA
mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
@@ -520,11 +493,20 @@ SYM_CODE_START(mcck_int_handler)
TSTMSK __LC_MCCK_CODE,MCCK_CODE_PSW_IA_VALID
jno .Lmcck_panic
#if IS_ENABLED(CONFIG_KVM)
- OUTSIDE %r9,.Lsie_gmap,.Lsie_done,.Lmcck_user
- OUTSIDE %r9,.Lsie_entry,.Lsie_leave,4f
+ TSTMSK __LC_CPU_FLAGS,_CIF_SIE
+ jz .Lmcck_user
+ # Need to compare the address instead of a CIF_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
+ # handled by the host.
+ larl %r14,.Lsie_entry
+ clgrjl %r9,%r14, 4f
+ larl %r14,.Lsie_leave
+ clgrjhe %r9,%r14, 4f
oi __LC_CPU_FLAGS+7, _CIF_MCCK_GUEST
4: BPENTER __SF_SIE_FLAGS(%r15),_TIF_ISOLATE_BP_GUEST
- SIEEXIT
+ SIEEXIT __SF_SIE_CONTROL(%r15)
#endif
.Lmcck_user:
lg %r15,__LC_MCCK_STACK
@@ -653,6 +635,7 @@ SYM_DATA_START_LOCAL(daton_psw)
SYM_DATA_END(daton_psw)
.section .rodata, "a"
+ .balign 8
#define SYSCALL(esame,emu) .quad __s390x_ ## esame
SYM_DATA_START(sys_call_table)
#include "asm/syscall_table.h"
diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h
index 9f41853f36b9..21969520f947 100644
--- a/arch/s390/kernel/entry.h
+++ b/arch/s390/kernel/entry.h
@@ -19,6 +19,7 @@ void mcck_int_handler(void);
void restart_int_handler(void);
void early_pgm_check_handler(void);
+struct task_struct *__switch_to_asm(struct task_struct *prev, struct task_struct *next);
void __ret_from_fork(struct task_struct *prev, struct pt_regs *regs);
void __do_pgm_check(struct pt_regs *regs);
void __do_syscall(struct pt_regs *regs, int per_trap);
diff --git a/arch/s390/kernel/fpu.c b/arch/s390/kernel/fpu.c
index a4f3449cc814..fa90bbdc5ef9 100644
--- a/arch/s390/kernel/fpu.c
+++ b/arch/s390/kernel/fpu.c
@@ -8,256 +8,186 @@
#include <linux/kernel.h>
#include <linux/cpu.h>
#include <linux/sched.h>
-#include <asm/fpu/types.h>
-#include <asm/fpu/api.h>
-#include <asm/vx-insn.h>
+#include <asm/fpu.h>
-void __kernel_fpu_begin(struct kernel_fpu *state, u32 flags)
+void __kernel_fpu_begin(struct kernel_fpu *state, int flags)
{
+ __vector128 *vxrs = state->vxrs;
+ int mask;
+
/*
* Limit the save to the FPU/vector registers already
- * in use by the previous context
+ * in use by the previous context.
*/
- flags &= state->mask;
-
+ flags &= state->hdr.mask;
if (flags & KERNEL_FPC)
- /* Save floating point control */
- asm volatile("stfpc %0" : "=Q" (state->fpc));
-
+ fpu_stfpc(&state->hdr.fpc);
if (!cpu_has_vx()) {
- if (flags & KERNEL_VXR_V0V7) {
- /* Save floating-point registers */
- asm volatile("std 0,%0" : "=Q" (state->fprs[0]));
- asm volatile("std 1,%0" : "=Q" (state->fprs[1]));
- asm volatile("std 2,%0" : "=Q" (state->fprs[2]));
- asm volatile("std 3,%0" : "=Q" (state->fprs[3]));
- asm volatile("std 4,%0" : "=Q" (state->fprs[4]));
- asm volatile("std 5,%0" : "=Q" (state->fprs[5]));
- asm volatile("std 6,%0" : "=Q" (state->fprs[6]));
- asm volatile("std 7,%0" : "=Q" (state->fprs[7]));
- asm volatile("std 8,%0" : "=Q" (state->fprs[8]));
- asm volatile("std 9,%0" : "=Q" (state->fprs[9]));
- asm volatile("std 10,%0" : "=Q" (state->fprs[10]));
- asm volatile("std 11,%0" : "=Q" (state->fprs[11]));
- asm volatile("std 12,%0" : "=Q" (state->fprs[12]));
- asm volatile("std 13,%0" : "=Q" (state->fprs[13]));
- asm volatile("std 14,%0" : "=Q" (state->fprs[14]));
- asm volatile("std 15,%0" : "=Q" (state->fprs[15]));
- }
+ if (flags & KERNEL_VXR_LOW)
+ save_fp_regs_vx(vxrs);
return;
}
-
- /* Test and save vector registers */
- asm volatile (
- /*
- * Test if any vector register must be saved and, if so,
- * test if all register can be saved.
- */
- " la 1,%[vxrs]\n" /* load save area */
- " tmll %[m],30\n" /* KERNEL_VXR */
- " jz 7f\n" /* no work -> done */
- " jo 5f\n" /* -> save V0..V31 */
- /*
- * Test for special case KERNEL_FPU_MID only. In this
- * case a vstm V8..V23 is the best instruction
- */
- " chi %[m],12\n" /* KERNEL_VXR_MID */
- " jne 0f\n" /* -> save V8..V23 */
- " VSTM 8,23,128,1\n" /* vstm %v8,%v23,128(%r1) */
- " j 7f\n"
- /* Test and save the first half of 16 vector registers */
- "0: tmll %[m],6\n" /* KERNEL_VXR_LOW */
- " jz 3f\n" /* -> KERNEL_VXR_HIGH */
- " jo 2f\n" /* 11 -> save V0..V15 */
- " brc 2,1f\n" /* 10 -> save V8..V15 */
- " VSTM 0,7,0,1\n" /* vstm %v0,%v7,0(%r1) */
- " j 3f\n"
- "1: VSTM 8,15,128,1\n" /* vstm %v8,%v15,128(%r1) */
- " j 3f\n"
- "2: VSTM 0,15,0,1\n" /* vstm %v0,%v15,0(%r1) */
- /* Test and save the second half of 16 vector registers */
- "3: tmll %[m],24\n" /* KERNEL_VXR_HIGH */
- " jz 7f\n"
- " jo 6f\n" /* 11 -> save V16..V31 */
- " brc 2,4f\n" /* 10 -> save V24..V31 */
- " VSTM 16,23,256,1\n" /* vstm %v16,%v23,256(%r1) */
- " j 7f\n"
- "4: VSTM 24,31,384,1\n" /* vstm %v24,%v31,384(%r1) */
- " j 7f\n"
- "5: VSTM 0,15,0,1\n" /* vstm %v0,%v15,0(%r1) */
- "6: VSTM 16,31,256,1\n" /* vstm %v16,%v31,256(%r1) */
- "7:"
- : [vxrs] "=Q" (*(struct vx_array *) &state->vxrs)
- : [m] "d" (flags)
- : "1", "cc");
+ mask = flags & KERNEL_VXR;
+ if (mask == KERNEL_VXR) {
+ vxrs += fpu_vstm(0, 15, vxrs);
+ vxrs += fpu_vstm(16, 31, vxrs);
+ return;
+ }
+ if (mask == KERNEL_VXR_MID) {
+ vxrs += fpu_vstm(8, 23, vxrs);
+ return;
+ }
+ mask = flags & KERNEL_VXR_LOW;
+ if (mask) {
+ if (mask == KERNEL_VXR_LOW)
+ vxrs += fpu_vstm(0, 15, vxrs);
+ else if (mask == KERNEL_VXR_V0V7)
+ vxrs += fpu_vstm(0, 7, vxrs);
+ else
+ vxrs += fpu_vstm(8, 15, vxrs);
+ }
+ mask = flags & KERNEL_VXR_HIGH;
+ if (mask) {
+ if (mask == KERNEL_VXR_HIGH)
+ vxrs += fpu_vstm(16, 31, vxrs);
+ else if (mask == KERNEL_VXR_V16V23)
+ vxrs += fpu_vstm(16, 23, vxrs);
+ else
+ vxrs += fpu_vstm(24, 31, vxrs);
+ }
}
EXPORT_SYMBOL(__kernel_fpu_begin);
-void __kernel_fpu_end(struct kernel_fpu *state, u32 flags)
+void __kernel_fpu_end(struct kernel_fpu *state, int flags)
{
+ __vector128 *vxrs = state->vxrs;
+ int mask;
+
/*
* Limit the restore to the FPU/vector registers of the
- * previous context that have been overwritte by the
- * current context
+ * previous context that have been overwritten by the
+ * current context.
*/
- flags &= state->mask;
-
+ flags &= state->hdr.mask;
if (flags & KERNEL_FPC)
- /* Restore floating-point controls */
- asm volatile("lfpc %0" : : "Q" (state->fpc));
-
+ fpu_lfpc(&state->hdr.fpc);
if (!cpu_has_vx()) {
- if (flags & KERNEL_VXR_V0V7) {
- /* Restore floating-point registers */
- asm volatile("ld 0,%0" : : "Q" (state->fprs[0]));
- asm volatile("ld 1,%0" : : "Q" (state->fprs[1]));
- asm volatile("ld 2,%0" : : "Q" (state->fprs[2]));
- asm volatile("ld 3,%0" : : "Q" (state->fprs[3]));
- asm volatile("ld 4,%0" : : "Q" (state->fprs[4]));
- asm volatile("ld 5,%0" : : "Q" (state->fprs[5]));
- asm volatile("ld 6,%0" : : "Q" (state->fprs[6]));
- asm volatile("ld 7,%0" : : "Q" (state->fprs[7]));
- asm volatile("ld 8,%0" : : "Q" (state->fprs[8]));
- asm volatile("ld 9,%0" : : "Q" (state->fprs[9]));
- asm volatile("ld 10,%0" : : "Q" (state->fprs[10]));
- asm volatile("ld 11,%0" : : "Q" (state->fprs[11]));
- asm volatile("ld 12,%0" : : "Q" (state->fprs[12]));
- asm volatile("ld 13,%0" : : "Q" (state->fprs[13]));
- asm volatile("ld 14,%0" : : "Q" (state->fprs[14]));
- asm volatile("ld 15,%0" : : "Q" (state->fprs[15]));
- }
+ if (flags & KERNEL_VXR_LOW)
+ load_fp_regs_vx(vxrs);
return;
}
-
- /* Test and restore (load) vector registers */
- asm volatile (
- /*
- * Test if any vector register must be loaded and, if so,
- * test if all registers can be loaded at once.
- */
- " la 1,%[vxrs]\n" /* load restore area */
- " tmll %[m],30\n" /* KERNEL_VXR */
- " jz 7f\n" /* no work -> done */
- " jo 5f\n" /* -> restore V0..V31 */
- /*
- * Test for special case KERNEL_FPU_MID only. In this
- * case a vlm V8..V23 is the best instruction
- */
- " chi %[m],12\n" /* KERNEL_VXR_MID */
- " jne 0f\n" /* -> restore V8..V23 */
- " VLM 8,23,128,1\n" /* vlm %v8,%v23,128(%r1) */
- " j 7f\n"
- /* Test and restore the first half of 16 vector registers */
- "0: tmll %[m],6\n" /* KERNEL_VXR_LOW */
- " jz 3f\n" /* -> KERNEL_VXR_HIGH */
- " jo 2f\n" /* 11 -> restore V0..V15 */
- " brc 2,1f\n" /* 10 -> restore V8..V15 */
- " VLM 0,7,0,1\n" /* vlm %v0,%v7,0(%r1) */
- " j 3f\n"
- "1: VLM 8,15,128,1\n" /* vlm %v8,%v15,128(%r1) */
- " j 3f\n"
- "2: VLM 0,15,0,1\n" /* vlm %v0,%v15,0(%r1) */
- /* Test and restore the second half of 16 vector registers */
- "3: tmll %[m],24\n" /* KERNEL_VXR_HIGH */
- " jz 7f\n"
- " jo 6f\n" /* 11 -> restore V16..V31 */
- " brc 2,4f\n" /* 10 -> restore V24..V31 */
- " VLM 16,23,256,1\n" /* vlm %v16,%v23,256(%r1) */
- " j 7f\n"
- "4: VLM 24,31,384,1\n" /* vlm %v24,%v31,384(%r1) */
- " j 7f\n"
- "5: VLM 0,15,0,1\n" /* vlm %v0,%v15,0(%r1) */
- "6: VLM 16,31,256,1\n" /* vlm %v16,%v31,256(%r1) */
- "7:"
- : [vxrs] "=Q" (*(struct vx_array *) &state->vxrs)
- : [m] "d" (flags)
- : "1", "cc");
+ mask = flags & KERNEL_VXR;
+ if (mask == KERNEL_VXR) {
+ vxrs += fpu_vlm(0, 15, vxrs);
+ vxrs += fpu_vlm(16, 31, vxrs);
+ return;
+ }
+ if (mask == KERNEL_VXR_MID) {
+ vxrs += fpu_vlm(8, 23, vxrs);
+ return;
+ }
+ mask = flags & KERNEL_VXR_LOW;
+ if (mask) {
+ if (mask == KERNEL_VXR_LOW)
+ vxrs += fpu_vlm(0, 15, vxrs);
+ else if (mask == KERNEL_VXR_V0V7)
+ vxrs += fpu_vlm(0, 7, vxrs);
+ else
+ vxrs += fpu_vlm(8, 15, vxrs);
+ }
+ mask = flags & KERNEL_VXR_HIGH;
+ if (mask) {
+ if (mask == KERNEL_VXR_HIGH)
+ vxrs += fpu_vlm(16, 31, vxrs);
+ else if (mask == KERNEL_VXR_V16V23)
+ vxrs += fpu_vlm(16, 23, vxrs);
+ else
+ vxrs += fpu_vlm(24, 31, vxrs);
+ }
}
EXPORT_SYMBOL(__kernel_fpu_end);
-void __load_fpu_regs(void)
+void load_fpu_state(struct fpu *state, int flags)
{
- unsigned long *regs = current->thread.fpu.regs;
- struct fpu *state = &current->thread.fpu;
+ __vector128 *vxrs = &state->vxrs[0];
+ int mask;
- sfpc_safe(state->fpc);
- if (likely(cpu_has_vx())) {
- asm volatile("lgr 1,%0\n"
- "VLM 0,15,0,1\n"
- "VLM 16,31,256,1\n"
- :
- : "d" (regs)
- : "1", "cc", "memory");
- } else {
- asm volatile("ld 0,%0" : : "Q" (regs[0]));
- asm volatile("ld 1,%0" : : "Q" (regs[1]));
- asm volatile("ld 2,%0" : : "Q" (regs[2]));
- asm volatile("ld 3,%0" : : "Q" (regs[3]));
- asm volatile("ld 4,%0" : : "Q" (regs[4]));
- asm volatile("ld 5,%0" : : "Q" (regs[5]));
- asm volatile("ld 6,%0" : : "Q" (regs[6]));
- asm volatile("ld 7,%0" : : "Q" (regs[7]));
- asm volatile("ld 8,%0" : : "Q" (regs[8]));
- asm volatile("ld 9,%0" : : "Q" (regs[9]));
- asm volatile("ld 10,%0" : : "Q" (regs[10]));
- asm volatile("ld 11,%0" : : "Q" (regs[11]));
- asm volatile("ld 12,%0" : : "Q" (regs[12]));
- asm volatile("ld 13,%0" : : "Q" (regs[13]));
- asm volatile("ld 14,%0" : : "Q" (regs[14]));
- asm volatile("ld 15,%0" : : "Q" (regs[15]));
+ if (flags & KERNEL_FPC)
+ fpu_lfpc(&state->fpc);
+ if (!cpu_has_vx()) {
+ if (flags & KERNEL_VXR_V0V7)
+ load_fp_regs_vx(state->vxrs);
+ return;
+ }
+ mask = flags & KERNEL_VXR;
+ if (mask == KERNEL_VXR) {
+ fpu_vlm(0, 15, &vxrs[0]);
+ fpu_vlm(16, 31, &vxrs[16]);
+ return;
+ }
+ if (mask == KERNEL_VXR_MID) {
+ fpu_vlm(8, 23, &vxrs[8]);
+ return;
+ }
+ mask = flags & KERNEL_VXR_LOW;
+ if (mask) {
+ if (mask == KERNEL_VXR_LOW)
+ fpu_vlm(0, 15, &vxrs[0]);
+ else if (mask == KERNEL_VXR_V0V7)
+ fpu_vlm(0, 7, &vxrs[0]);
+ else
+ fpu_vlm(8, 15, &vxrs[8]);
+ }
+ mask = flags & KERNEL_VXR_HIGH;
+ if (mask) {
+ if (mask == KERNEL_VXR_HIGH)
+ fpu_vlm(16, 31, &vxrs[16]);
+ else if (mask == KERNEL_VXR_V16V23)
+ fpu_vlm(16, 23, &vxrs[16]);
+ else
+ fpu_vlm(24, 31, &vxrs[24]);
}
- clear_cpu_flag(CIF_FPU);
-}
-
-void load_fpu_regs(void)
-{
- raw_local_irq_disable();
- __load_fpu_regs();
- raw_local_irq_enable();
}
-EXPORT_SYMBOL(load_fpu_regs);
-void save_fpu_regs(void)
+void save_fpu_state(struct fpu *state, int flags)
{
- unsigned long flags, *regs;
- struct fpu *state;
-
- local_irq_save(flags);
+ __vector128 *vxrs = &state->vxrs[0];
+ int mask;
- if (test_cpu_flag(CIF_FPU))
- goto out;
-
- state = &current->thread.fpu;
- regs = current->thread.fpu.regs;
-
- asm volatile("stfpc %0" : "=Q" (state->fpc));
- if (likely(cpu_has_vx())) {
- asm volatile("lgr 1,%0\n"
- "VSTM 0,15,0,1\n"
- "VSTM 16,31,256,1\n"
- :
- : "d" (regs)
- : "1", "cc", "memory");
- } else {
- asm volatile("std 0,%0" : "=Q" (regs[0]));
- asm volatile("std 1,%0" : "=Q" (regs[1]));
- asm volatile("std 2,%0" : "=Q" (regs[2]));
- asm volatile("std 3,%0" : "=Q" (regs[3]));
- asm volatile("std 4,%0" : "=Q" (regs[4]));
- asm volatile("std 5,%0" : "=Q" (regs[5]));
- asm volatile("std 6,%0" : "=Q" (regs[6]));
- asm volatile("std 7,%0" : "=Q" (regs[7]));
- asm volatile("std 8,%0" : "=Q" (regs[8]));
- asm volatile("std 9,%0" : "=Q" (regs[9]));
- asm volatile("std 10,%0" : "=Q" (regs[10]));
- asm volatile("std 11,%0" : "=Q" (regs[11]));
- asm volatile("std 12,%0" : "=Q" (regs[12]));
- asm volatile("std 13,%0" : "=Q" (regs[13]));
- asm volatile("std 14,%0" : "=Q" (regs[14]));
- asm volatile("std 15,%0" : "=Q" (regs[15]));
+ if (flags & KERNEL_FPC)
+ fpu_stfpc(&state->fpc);
+ if (!cpu_has_vx()) {
+ if (flags & KERNEL_VXR_LOW)
+ save_fp_regs_vx(state->vxrs);
+ return;
+ }
+ mask = flags & KERNEL_VXR;
+ if (mask == KERNEL_VXR) {
+ fpu_vstm(0, 15, &vxrs[0]);
+ fpu_vstm(16, 31, &vxrs[16]);
+ return;
+ }
+ if (mask == KERNEL_VXR_MID) {
+ fpu_vstm(8, 23, &vxrs[8]);
+ return;
+ }
+ mask = flags & KERNEL_VXR_LOW;
+ if (mask) {
+ if (mask == KERNEL_VXR_LOW)
+ fpu_vstm(0, 15, &vxrs[0]);
+ else if (mask == KERNEL_VXR_V0V7)
+ fpu_vstm(0, 7, &vxrs[0]);
+ else
+ fpu_vstm(8, 15, &vxrs[8]);
+ }
+ mask = flags & KERNEL_VXR_HIGH;
+ if (mask) {
+ if (mask == KERNEL_VXR_HIGH)
+ fpu_vstm(16, 31, &vxrs[16]);
+ else if (mask == KERNEL_VXR_V16V23)
+ fpu_vstm(16, 23, &vxrs[16]);
+ else
+ fpu_vstm(24, 31, &vxrs[24]);
}
- set_cpu_flag(CIF_FPU);
-out:
- local_irq_restore(flags);
}
-EXPORT_SYMBOL(save_fpu_regs);
+EXPORT_SYMBOL(save_fpu_state);
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index ba75f6bee774..1486350a4177 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -1941,8 +1941,7 @@ static void dump_reipl_run(struct shutdown_trigger *trigger)
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));
- csum = (__force unsigned int)
- csum_partial(reipl_block_actual, reipl_block_actual->hdr.len, 0);
+ 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);
abs_lc->ipib_checksum = csum;
diff --git a/arch/s390/kernel/kexec_elf.c b/arch/s390/kernel/kexec_elf.c
index 9da6fa30c447..4d364de43799 100644
--- a/arch/s390/kernel/kexec_elf.c
+++ b/arch/s390/kernel/kexec_elf.c
@@ -40,8 +40,10 @@ static int kexec_file_add_kernel_elf(struct kimage *image,
buf.bufsz = phdr->p_filesz;
buf.mem = ALIGN(phdr->p_paddr, phdr->p_align);
+#ifdef CONFIG_CRASH_DUMP
if (image->type == KEXEC_TYPE_CRASH)
buf.mem += crashk_res.start;
+#endif
buf.memsz = phdr->p_memsz;
data->memsz = ALIGN(data->memsz, phdr->p_align) + buf.memsz;
diff --git a/arch/s390/kernel/kexec_image.c b/arch/s390/kernel/kexec_image.c
index af23eff5774d..a32ce8bea745 100644
--- a/arch/s390/kernel/kexec_image.c
+++ b/arch/s390/kernel/kexec_image.c
@@ -24,8 +24,10 @@ static int kexec_file_add_kernel_image(struct kimage *image,
buf.bufsz = image->kernel_buf_len;
buf.mem = 0;
+#ifdef CONFIG_CRASH_DUMP
if (image->type == KEXEC_TYPE_CRASH)
buf.mem += crashk_res.start;
+#endif
buf.memsz = buf.bufsz;
data->kernel_buf = image->kernel_buf;
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c
index aa22ffc16bcd..3aee98efc374 100644
--- a/arch/s390/kernel/machine_kexec.c
+++ b/arch/s390/kernel/machine_kexec.c
@@ -13,8 +13,10 @@
#include <linux/reboot.h>
#include <linux/ftrace.h>
#include <linux/debug_locks.h>
+#include <asm/guarded_storage.h>
#include <asm/pfault.h>
#include <asm/cio.h>
+#include <asm/fpu.h>
#include <asm/setup.h>
#include <asm/smp.h>
#include <asm/ipl.h>
@@ -26,7 +28,6 @@
#include <asm/os_info.h>
#include <asm/set_memory.h>
#include <asm/stacktrace.h>
-#include <asm/switch_to.h>
#include <asm/nmi.h>
#include <asm/sclp.h>
@@ -209,21 +210,6 @@ void machine_kexec_cleanup(struct kimage *image)
{
}
-void arch_crash_save_vmcoreinfo(void)
-{
- struct lowcore *abs_lc;
-
- VMCOREINFO_SYMBOL(lowcore_ptr);
- VMCOREINFO_SYMBOL(high_memory);
- 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("KERNELOFFSET=%lx\n", kaslr_offset());
- abs_lc = get_abs_lowcore();
- abs_lc->vmcore_info = paddr_vmcoreinfo_note();
- put_abs_lowcore(abs_lc);
-}
-
void machine_shutdown(void)
{
}
diff --git a/arch/s390/kernel/machine_kexec_file.c b/arch/s390/kernel/machine_kexec_file.c
index 8d207b82d9fe..c2bac14dd668 100644
--- a/arch/s390/kernel/machine_kexec_file.c
+++ b/arch/s390/kernel/machine_kexec_file.c
@@ -105,6 +105,7 @@ static int kexec_file_update_purgatory(struct kimage *image,
if (ret)
return ret;
+#ifdef CONFIG_CRASH_DUMP
if (image->type == KEXEC_TYPE_CRASH) {
u64 crash_size;
@@ -121,6 +122,7 @@ static int kexec_file_update_purgatory(struct kimage *image,
sizeof(crash_size),
false);
}
+#endif
return ret;
}
@@ -134,8 +136,10 @@ static int kexec_file_add_purgatory(struct kimage *image,
data->memsz = ALIGN(data->memsz, PAGE_SIZE);
buf.mem = data->memsz;
+#ifdef CONFIG_CRASH_DUMP
if (image->type == KEXEC_TYPE_CRASH)
buf.mem += crashk_res.start;
+#endif
ret = kexec_load_purgatory(image, &buf);
if (ret)
@@ -158,8 +162,10 @@ static int kexec_file_add_initrd(struct kimage *image,
data->memsz = ALIGN(data->memsz, PAGE_SIZE);
buf.mem = data->memsz;
+#ifdef CONFIG_CRASH_DUMP
if (image->type == KEXEC_TYPE_CRASH)
buf.mem += crashk_res.start;
+#endif
buf.memsz = buf.bufsz;
data->parm->initrd_start = data->memsz;
@@ -223,8 +229,10 @@ static int kexec_file_add_ipl_report(struct kimage *image,
data->kernel_buf + offsetof(struct lowcore, ipl_parmblock_ptr);
*lc_ipl_parmblock_ptr = (__u32)buf.mem;
+#ifdef CONFIG_CRASH_DUMP
if (image->type == KEXEC_TYPE_CRASH)
buf.mem += crashk_res.start;
+#endif
ret = kexec_add_buffer(&buf);
out:
@@ -268,10 +276,12 @@ void *kexec_file_add_components(struct kimage *image,
memcpy(data.parm->command_line, image->cmdline_buf,
image->cmdline_buf_len);
+#ifdef CONFIG_CRASH_DUMP
if (image->type == KEXEC_TYPE_CRASH) {
data.parm->oldmem_base = crashk_res.start;
data.parm->oldmem_size = crashk_res.end - crashk_res.start + 1;
}
+#endif
if (image->initrd_buf) {
ret = kexec_file_add_initrd(image, &data);
diff --git a/arch/s390/kernel/nmi.c b/arch/s390/kernel/nmi.c
index 9ad44c26d1a2..c77382a67325 100644
--- a/arch/s390/kernel/nmi.c
+++ b/arch/s390/kernel/nmi.c
@@ -23,16 +23,14 @@
#include <linux/export.h>
#include <asm/lowcore.h>
#include <asm/ctlreg.h>
+#include <asm/fpu.h>
#include <asm/smp.h>
#include <asm/stp.h>
#include <asm/cputime.h>
#include <asm/nmi.h>
#include <asm/crw.h>
-#include <asm/switch_to.h>
#include <asm/asm-offsets.h>
#include <asm/pai.h>
-#include <asm/vx-insn.h>
-#include <asm/fpu/api.h>
struct mcck_struct {
unsigned int kill_task : 1;
@@ -204,133 +202,63 @@ void s390_handle_mcck(void)
}
}
-/*
- * returns 0 if register contents could be validated
- * returns 1 otherwise
+/**
+ * nmi_registers_valid - verify if registers are valid
+ * @mci: machine check interruption code
+ *
+ * Inspect a machine check interruption code and verify if all required
+ * registers are valid. For some registers the corresponding validity bit is
+ * ignored and the registers are set to the expected value.
+ * Returns true if all registers are valid, otherwise false.
*/
-static int notrace s390_validate_registers(union mci mci)
+static bool notrace nmi_registers_valid(union mci mci)
{
- struct mcesa *mcesa;
- void *fpt_save_area;
union ctlreg2 cr2;
- int kill_task;
- u64 zero;
-
- kill_task = 0;
- zero = 0;
-
- if (!mci.gr || !mci.fp)
- kill_task = 1;
- fpt_save_area = &S390_lowcore.floating_pt_save_area;
- if (!mci.fc) {
- kill_task = 1;
- asm volatile(
- " lfpc %0\n"
- :
- : "Q" (zero));
- } else {
- asm volatile(
- " lfpc %0\n"
- :
- : "Q" (S390_lowcore.fpt_creg_save_area));
- }
- mcesa = __va(S390_lowcore.mcesad & MCESA_ORIGIN_MASK);
- if (!cpu_has_vx()) {
- /* Validate floating point registers */
- asm volatile(
- " ld 0,0(%0)\n"
- " ld 1,8(%0)\n"
- " ld 2,16(%0)\n"
- " ld 3,24(%0)\n"
- " ld 4,32(%0)\n"
- " ld 5,40(%0)\n"
- " ld 6,48(%0)\n"
- " ld 7,56(%0)\n"
- " ld 8,64(%0)\n"
- " ld 9,72(%0)\n"
- " ld 10,80(%0)\n"
- " ld 11,88(%0)\n"
- " ld 12,96(%0)\n"
- " ld 13,104(%0)\n"
- " ld 14,112(%0)\n"
- " ld 15,120(%0)\n"
- :
- : "a" (fpt_save_area)
- : "memory");
- } else {
- /* Validate vector registers */
- union ctlreg0 cr0;
-
- /*
- * The vector validity must only be checked if not running a
- * KVM guest. For KVM guests the machine check is forwarded by
- * KVM and it is the responsibility of the guest to take
- * appropriate actions. The host vector or FPU values have been
- * saved by KVM and will be restored by KVM.
- */
- if (!mci.vr && !test_cpu_flag(CIF_MCCK_GUEST))
- kill_task = 1;
- cr0.reg = S390_lowcore.cregs_save_area[0];
- cr0.afp = cr0.vx = 1;
- local_ctl_load(0, &cr0.reg);
- asm volatile(
- " la 1,%0\n"
- " VLM 0,15,0,1\n"
- " VLM 16,31,256,1\n"
- :
- : "Q" (*(struct vx_array *)mcesa->vector_save_area)
- : "1");
- local_ctl_load(0, &S390_lowcore.cregs_save_area[0]);
- }
- /* Validate access registers */
- asm volatile(
- " lam 0,15,0(%0)\n"
- :
- : "a" (&S390_lowcore.access_regs_save_area)
- : "memory");
- if (!mci.ar)
- kill_task = 1;
- /* Validate guarded storage registers */
- cr2.reg = S390_lowcore.cregs_save_area[2];
- if (cr2.gse) {
- if (!mci.gs) {
- /*
- * 2 cases:
- * - machine check in kernel or userspace
- * - machine check while running SIE (KVM guest)
- * For kernel or userspace the userspace values of
- * guarded storage control can not be recreated, the
- * process must be terminated.
- * For SIE the guest values of guarded storage can not
- * be recreated. This is either due to a bug or due to
- * GS being disabled in the guest. The guest will be
- * notified by KVM code and the guests machine check
- * handling must take care of this. The host values
- * are saved by KVM and are not affected.
- */
- if (!test_cpu_flag(CIF_MCCK_GUEST))
- kill_task = 1;
- } else {
- load_gs_cb((struct gs_cb *)mcesa->guarded_storage_save_area);
- }
- }
/*
- * The getcpu vdso syscall reads CPU number from the programmable
+ * The getcpu vdso syscall reads the CPU number from the programmable
* field of the TOD clock. Disregard the TOD programmable register
- * validity bit and load the CPU number into the TOD programmable
- * field unconditionally.
+ * validity bit and load the CPU number into the TOD programmable field
+ * unconditionally.
*/
set_tod_programmable_field(raw_smp_processor_id());
- /* Validate clock comparator register */
+ /*
+ * Set the clock comparator register to the next expected value.
+ */
set_clock_comparator(S390_lowcore.clock_comparator);
-
+ if (!mci.gr || !mci.fp || !mci.fc)
+ return false;
+ /*
+ * The vector validity must only be checked if not running a
+ * KVM guest. For KVM guests the machine check is forwarded by
+ * KVM and it is the responsibility of the guest to take
+ * appropriate actions. The host vector or FPU values have been
+ * saved by KVM and will be restored by KVM.
+ */
+ if (!mci.vr && !test_cpu_flag(CIF_MCCK_GUEST))
+ return false;
+ if (!mci.ar)
+ return false;
+ /*
+ * Two cases for guarded storage registers:
+ * - machine check in kernel or userspace
+ * - machine check while running SIE (KVM guest)
+ * For kernel or userspace the userspace values of guarded storage
+ * control can not be recreated, the process must be terminated.
+ * For SIE the guest values of guarded storage can not be recreated.
+ * This is either due to a bug or due to GS being disabled in the
+ * guest. The guest will be notified by KVM code and the guests machine
+ * 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];
+ if (cr2.gse && !mci.gs && !test_cpu_flag(CIF_MCCK_GUEST))
+ return false;
if (!mci.ms || !mci.pm || !mci.ia)
- kill_task = 1;
-
- return kill_task;
+ return false;
+ return true;
}
-NOKPROBE_SYMBOL(s390_validate_registers);
+NOKPROBE_SYMBOL(nmi_registers_valid);
/*
* Backup the guest's machine check info to its description block
@@ -428,7 +356,7 @@ void notrace s390_do_machine_check(struct pt_regs *regs)
s390_handle_damage();
}
}
- if (s390_validate_registers(mci)) {
+ if (!nmi_registers_valid(mci)) {
if (!user_mode(regs))
s390_handle_damage();
/*
diff --git a/arch/s390/kernel/os_info.c b/arch/s390/kernel/os_info.c
index 6e1824141b29..a801e6bd5341 100644
--- a/arch/s390/kernel/os_info.c
+++ b/arch/s390/kernel/os_info.c
@@ -29,7 +29,7 @@ static struct os_info os_info __page_aligned_data;
u32 os_info_csum(struct os_info *os_info)
{
int size = sizeof(*os_info) - offsetof(struct os_info, version_major);
- return (__force u32)csum_partial(&os_info->version_major, size, 0);
+ return (__force u32)cksm(&os_info->version_major, size, 0);
}
/*
@@ -49,7 +49,7 @@ void os_info_entry_add(int nr, void *ptr, u64 size)
{
os_info.entry[nr].addr = __pa(ptr);
os_info.entry[nr].size = size;
- os_info.entry[nr].csum = (__force u32)csum_partial(ptr, size, 0);
+ os_info.entry[nr].csum = (__force u32)cksm(ptr, size, 0);
os_info.csum = os_info_csum(&os_info);
}
@@ -98,7 +98,7 @@ static void os_info_old_alloc(int nr, int align)
msg = "copy failed";
goto fail_free;
}
- csum = (__force u32)csum_partial(buf_align, size, 0);
+ csum = (__force u32)cksm(buf_align, size, 0);
if (csum != os_info_old->entry[nr].csum) {
msg = "checksum failed";
goto fail_free;
diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c
index bf8a672b15a4..4ad472d130a3 100644
--- a/arch/s390/kernel/perf_pai_crypto.c
+++ b/arch/s390/kernel/perf_pai_crypto.c
@@ -90,7 +90,6 @@ static void paicrypt_event_destroy(struct perf_event *event)
event->cpu);
struct paicrypt_map *cpump = mp->mapptr;
- cpump->event = NULL;
static_branch_dec(&pai_key);
mutex_lock(&pai_reserve_mutex);
debug_sprintf_event(cfm_dbg, 5, "%s event %#llx cpu %d users %d"
@@ -98,6 +97,7 @@ static void paicrypt_event_destroy(struct perf_event *event)
event->attr.config, event->cpu,
cpump->active_events, cpump->mode,
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,
@@ -260,6 +260,7 @@ static int paicrypt_event_init(struct perf_event *event)
{
struct perf_event_attr *a = &event->attr;
struct paicrypt_map *cpump;
+ int rc = 0;
/* PAI crypto PMU registered as PERF_TYPE_RAW, check event type */
if (a->type != PERF_TYPE_RAW && event->pmu->type != a->type)
@@ -274,10 +275,21 @@ static int paicrypt_event_init(struct perf_event *event)
/* 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 */
+ if (a->sample_period) {
+ PAI_SAVE_AREA(event) = get_zeroed_page(GFP_KERNEL);
+ if (!PAI_SAVE_AREA(event)) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ }
cpump = paicrypt_busy(event);
- if (IS_ERR(cpump))
- return PTR_ERR(cpump);
+ if (IS_ERR(cpump)) {
+ free_page(PAI_SAVE_AREA(event));
+ rc = PTR_ERR(cpump);
+ goto out;
+ }
event->destroy = paicrypt_event_destroy;
@@ -293,7 +305,8 @@ static int paicrypt_event_init(struct perf_event *event)
}
static_branch_inc(&pai_key);
- return 0;
+out:
+ return rc;
}
static void paicrypt_read(struct perf_event *event)
@@ -310,20 +323,15 @@ static void paicrypt_read(struct perf_event *event)
static void paicrypt_start(struct perf_event *event, int flags)
{
+ struct paicrypt_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr);
+ struct paicrypt_map *cpump = mp->mapptr;
u64 sum;
- /* Event initialization sets last_tag to 0. When later on the events
- * are deleted and re-added, do not reset the event count value to zero.
- * Events are added, deleted and re-added when 2 or more events
- * are active at the same time.
- */
if (!event->attr.sample_period) { /* Counting */
- if (!event->hw.last_tag) {
- event->hw.last_tag = 1;
- sum = paicrypt_getall(event); /* Get current value */
- local64_set(&event->hw.prev_count, sum);
- }
+ 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);
}
}
@@ -339,7 +347,6 @@ static int paicrypt_add(struct perf_event *event, int flags)
WRITE_ONCE(S390_lowcore.ccd, ccd);
local_ctl_set_bit(0, CR0_CRYPTOGRAPHY_COUNTER_BIT);
}
- cpump->event = event;
if (flags & PERF_EF_START)
paicrypt_start(event, PERF_EF_RELOAD);
event->hw.state = 0;
@@ -348,10 +355,15 @@ static int paicrypt_add(struct perf_event *event, int flags)
static void paicrypt_stop(struct perf_event *event, int flags)
{
- if (!event->attr.sample_period) /* Counting */
+ struct paicrypt_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr);
+ struct paicrypt_map *cpump = mp->mapptr;
+
+ if (!event->attr.sample_period) { /* Counting */
paicrypt_read(event);
- else /* Sampling */
+ } else { /* Sampling */
perf_sched_cb_dec(event->pmu);
+ cpump->event = NULL;
+ }
event->hw.state = PERF_HES_STOPPED;
}
@@ -367,23 +379,34 @@ static void paicrypt_del(struct perf_event *event, int flags)
}
}
-/* Create raw data and save it in buffer. Returns number of bytes copied.
- * Saves only positive counter entries of the form
+/* Create raw data and save it in buffer. Calculate the delta for each
+ * counter between this invocation and the last invocation.
+ * Returns number of bytes copied.
+ * Saves only entries with positive counter difference of the form
* 2 bytes: Number of counter
* 8 bytes: Value of counter
*/
static size_t paicrypt_copy(struct pai_userdata *userdata, unsigned long *page,
- bool exclude_user, bool exclude_kernel)
+ unsigned long *page_old, bool exclude_user,
+ bool exclude_kernel)
{
int i, outidx = 0;
for (i = 1; i <= paicrypt_cnt; i++) {
- u64 val = 0;
+ u64 val = 0, val_old = 0;
- if (!exclude_kernel)
+ if (!exclude_kernel) {
val += paicrypt_getctr(page, i, true);
- if (!exclude_user)
+ val_old += paicrypt_getctr(page_old, i, true);
+ }
+ if (!exclude_user) {
val += paicrypt_getctr(page, i, false);
+ val_old += paicrypt_getctr(page_old, i, false);
+ }
+ if (val >= val_old)
+ val -= val_old;
+ else
+ val = (~0ULL - val_old) + val + 1;
if (val) {
userdata[outidx].num = i;
userdata[outidx].value = val;
@@ -426,8 +449,8 @@ static int paicrypt_push_sample(size_t rawsize, struct paicrypt_map *cpump,
overflow = perf_event_overflow(event, &data, &regs);
perf_event_update_userpage(event);
- /* Clear lowcore page after read */
- memset(cpump->page, 0, PAGE_SIZE);
+ /* Save crypto counter lowcore page after reading event data. */
+ memcpy((void *)PAI_SAVE_AREA(event), cpump->page, PAGE_SIZE);
return overflow;
}
@@ -443,6 +466,7 @@ static int paicrypt_have_sample(void)
if (!event) /* No event active */
return 0;
rawsize = paicrypt_copy(cpump->save, cpump->page,
+ (unsigned long *)PAI_SAVE_AREA(event),
cpump->event->attr.exclude_user,
cpump->event->attr.exclude_kernel);
if (rawsize) /* No incremented counters */
@@ -694,6 +718,12 @@ static int __init attr_event_init_one(struct attribute **attrs, int num)
{
struct perf_pmu_events_attr *pa;
+ /* Index larger than array_size, no counter name available */
+ if (num >= ARRAY_SIZE(paicrypt_ctrnames)) {
+ attrs[num] = NULL;
+ return 0;
+ }
+
pa = kzalloc(sizeof(*pa), GFP_KERNEL);
if (!pa)
return -ENOMEM;
@@ -714,14 +744,13 @@ static int __init attr_event_init(void)
struct attribute **attrs;
int ret, i;
- attrs = kmalloc_array(ARRAY_SIZE(paicrypt_ctrnames) + 1, sizeof(*attrs),
- GFP_KERNEL);
+ attrs = kmalloc_array(paicrypt_cnt + 2, sizeof(*attrs), GFP_KERNEL);
if (!attrs)
return -ENOMEM;
- for (i = 0; i < ARRAY_SIZE(paicrypt_ctrnames); i++) {
+ for (i = 0; i <= paicrypt_cnt; i++) {
ret = attr_event_init_one(attrs, i);
if (ret) {
- attr_event_free(attrs, i - 1);
+ attr_event_free(attrs, i);
return ret;
}
}
@@ -742,8 +771,10 @@ static int __init paicrypt_init(void)
paicrypt_cnt = ib.num_cc;
if (paicrypt_cnt == 0)
return 0;
- if (paicrypt_cnt >= PAI_CRYPTO_MAXCTR)
- paicrypt_cnt = PAI_CRYPTO_MAXCTR - 1;
+ if (paicrypt_cnt >= PAI_CRYPTO_MAXCTR) {
+ pr_err("Too many PMU pai_crypto counters %d\n", paicrypt_cnt);
+ return -E2BIG;
+ }
rc = attr_event_init(); /* Export known PAI crypto events */
if (rc) {
diff --git a/arch/s390/kernel/perf_pai_ext.c b/arch/s390/kernel/perf_pai_ext.c
index af7f2b538c8f..a6da7e0cc7a6 100644
--- a/arch/s390/kernel/perf_pai_ext.c
+++ b/arch/s390/kernel/perf_pai_ext.c
@@ -120,8 +120,8 @@ static void paiext_event_destroy(struct perf_event *event)
struct paiext_mapptr *mp = per_cpu_ptr(paiext_root.mapptr, event->cpu);
struct paiext_map *cpump = mp->mapptr;
+ free_page(PAI_SAVE_AREA(event));
mutex_lock(&paiext_reserve_mutex);
- cpump->event = NULL;
if (refcount_dec_and_test(&cpump->refcnt)) /* Last reference gone */
paiext_free(mp);
paiext_root_free();
@@ -202,7 +202,6 @@ static int paiext_alloc(struct perf_event_attr *a, struct perf_event *event)
}
rc = 0;
- cpump->event = event;
undo:
if (rc) {
@@ -256,10 +255,18 @@ static int paiext_event_init(struct perf_event *event)
/* Prohibit exclude_user event selection */
if (a->exclude_user)
return -EINVAL;
+ /* Get a page to store last counter values for sampling */
+ if (a->sample_period) {
+ PAI_SAVE_AREA(event) = get_zeroed_page(GFP_KERNEL);
+ if (!PAI_SAVE_AREA(event))
+ return -ENOMEM;
+ }
rc = paiext_alloc(a, event);
- if (rc)
+ if (rc) {
+ free_page(PAI_SAVE_AREA(event));
return rc;
+ }
event->destroy = paiext_event_destroy;
if (a->sample_period) {
@@ -319,15 +326,15 @@ static void paiext_read(struct perf_event *event)
static void paiext_start(struct perf_event *event, int flags)
{
+ struct paiext_mapptr *mp = this_cpu_ptr(paiext_root.mapptr);
+ struct paiext_map *cpump = mp->mapptr;
u64 sum;
if (!event->attr.sample_period) { /* Counting */
- if (!event->hw.last_tag) {
- event->hw.last_tag = 1;
- sum = paiext_getall(event); /* Get current value */
- local64_set(&event->hw.prev_count, sum);
- }
+ 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);
}
}
@@ -346,7 +353,6 @@ static int paiext_add(struct perf_event *event, int flags)
debug_sprintf_event(paiext_dbg, 4, "%s 1508 %llx acc %llx\n",
__func__, S390_lowcore.aicd, pcb->acc);
}
- cpump->event = event;
if (flags & PERF_EF_START)
paiext_start(event, PERF_EF_RELOAD);
event->hw.state = 0;
@@ -355,10 +361,15 @@ static int paiext_add(struct perf_event *event, int flags)
static void paiext_stop(struct perf_event *event, int flags)
{
- if (!event->attr.sample_period) /* Counting */
+ struct paiext_mapptr *mp = this_cpu_ptr(paiext_root.mapptr);
+ struct paiext_map *cpump = mp->mapptr;
+
+ if (!event->attr.sample_period) { /* Counting */
paiext_read(event);
- else /* Sampling */
+ } else { /* Sampling */
perf_sched_cb_dec(event->pmu);
+ cpump->event = NULL;
+ }
event->hw.state = PERF_HES_STOPPED;
}
@@ -384,13 +395,19 @@ static void paiext_del(struct perf_event *event, int flags)
* 2 bytes: Number of counter
* 8 bytes: Value of counter
*/
-static size_t paiext_copy(struct pai_userdata *userdata, unsigned long *area)
+static size_t paiext_copy(struct pai_userdata *userdata, unsigned long *area,
+ unsigned long *area_old)
{
int i, outidx = 0;
for (i = 1; i <= paiext_cnt; i++) {
u64 val = paiext_getctr(area, i);
+ u64 val_old = paiext_getctr(area_old, i);
+ if (val >= val_old)
+ val -= val_old;
+ else
+ val = (~0ULL - val_old) + val + 1;
if (val) {
userdata[outidx].num = i;
userdata[outidx].value = val;
@@ -446,8 +463,9 @@ static int paiext_push_sample(size_t rawsize, struct paiext_map *cpump,
overflow = perf_event_overflow(event, &data, &regs);
perf_event_update_userpage(event);
- /* Clear lowcore area after read */
- memset(cpump->area, 0, PAIE1_CTRBLOCK_SZ);
+ /* Save NNPA lowcore area after read in event */
+ memcpy((void *)PAI_SAVE_AREA(event), cpump->area,
+ PAIE1_CTRBLOCK_SZ);
return overflow;
}
@@ -462,7 +480,8 @@ static int paiext_have_sample(void)
if (!event)
return 0;
- rawsize = paiext_copy(cpump->save, cpump->area);
+ 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;
@@ -584,6 +603,12 @@ static int __init attr_event_init_one(struct attribute **attrs, int num)
{
struct perf_pmu_events_attr *pa;
+ /* Index larger than array_size, no counter name available */
+ if (num >= ARRAY_SIZE(paiext_ctrnames)) {
+ attrs[num] = NULL;
+ return 0;
+ }
+
pa = kzalloc(sizeof(*pa), GFP_KERNEL);
if (!pa)
return -ENOMEM;
@@ -604,14 +629,13 @@ static int __init attr_event_init(void)
struct attribute **attrs;
int ret, i;
- attrs = kmalloc_array(ARRAY_SIZE(paiext_ctrnames) + 1, sizeof(*attrs),
- GFP_KERNEL);
+ attrs = kmalloc_array(paiext_cnt + 2, sizeof(*attrs), GFP_KERNEL);
if (!attrs)
return -ENOMEM;
- for (i = 0; i < ARRAY_SIZE(paiext_ctrnames); i++) {
+ for (i = 0; i <= paiext_cnt; i++) {
ret = attr_event_init_one(attrs, i);
if (ret) {
- attr_event_free(attrs, i - 1);
+ attr_event_free(attrs, i);
return ret;
}
}
diff --git a/arch/s390/kernel/perf_regs.c b/arch/s390/kernel/perf_regs.c
index 3d93656bd948..a6b058ee4a36 100644
--- a/arch/s390/kernel/perf_regs.c
+++ b/arch/s390/kernel/perf_regs.c
@@ -5,8 +5,7 @@
#include <linux/errno.h>
#include <linux/bug.h>
#include <asm/ptrace.h>
-#include <asm/fpu/api.h>
-#include <asm/fpu/types.h>
+#include <asm/fpu.h>
u64 perf_reg_value(struct pt_regs *regs, int idx)
{
@@ -20,10 +19,7 @@ u64 perf_reg_value(struct pt_regs *regs, int idx)
return 0;
idx -= PERF_REG_S390_FP0;
- if (cpu_has_vx())
- fp = *(freg_t *)(current->thread.fpu.vxrs + idx);
- else
- fp = current->thread.fpu.fprs[idx];
+ fp = *(freg_t *)(current->thread.ufpu.vxrs + idx);
return fp.ui;
}
@@ -65,6 +61,6 @@ void perf_get_regs_user(struct perf_regs *regs_user,
*/
regs_user->regs = task_pt_regs(current);
if (user_mode(regs_user->regs))
- save_fpu_regs();
+ save_user_fpu_regs();
regs_user->abi = perf_reg_abi(current);
}
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 4e3b366589fb..dd456b475861 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -31,15 +31,19 @@
#include <linux/init_task.h>
#include <linux/entry-common.h>
#include <linux/io.h>
+#include <asm/guarded_storage.h>
+#include <asm/access-regs.h>
+#include <asm/switch_to.h>
#include <asm/cpu_mf.h>
#include <asm/processor.h>
+#include <asm/ptrace.h>
#include <asm/vtimer.h>
#include <asm/exec.h>
+#include <asm/fpu.h>
#include <asm/irq.h>
#include <asm/nmi.h>
#include <asm/smp.h>
#include <asm/stacktrace.h>
-#include <asm/switch_to.h>
#include <asm/runtime_instr.h>
#include <asm/unwind.h>
#include "entry.h"
@@ -84,13 +88,13 @@ 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 CIF_FPU flag to lazy restore the FPU register
+ * task and set the TIF_FPU flag to lazy restore the FPU register
* state when returning to user space.
*/
- save_fpu_regs();
+ save_user_fpu_regs();
*dst = *src;
- dst->thread.fpu.regs = dst->thread.fpu.fprs;
+ dst->thread.kfpu_flags = 0;
/*
* Don't transfer over the runtime instrumentation or the guarded
@@ -186,8 +190,23 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
void execve_tail(void)
{
- current->thread.fpu.fpc = 0;
- asm volatile("sfpc %0" : : "d" (0));
+ current->thread.ufpu.fpc = 0;
+ fpu_sfpc(0);
+}
+
+struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *next)
+{
+ save_user_fpu_regs();
+ save_kernel_fpu_regs(&prev->thread);
+ save_access_regs(&prev->thread.acrs[0]);
+ save_ri_cb(prev->thread.ri_cb);
+ save_gs_cb(prev->thread.gs_cb);
+ update_cr_regs(next);
+ restore_kernel_fpu_regs(&next->thread);
+ restore_access_regs(&next->thread.acrs[0]);
+ restore_ri_cb(next->thread.ri_cb, prev->thread.ri_cb);
+ restore_gs_cb(next->thread.gs_cb);
+ return __switch_to_asm(prev, next);
}
unsigned long __get_wchan(struct task_struct *p)
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index f1897a8bb221..1cfed8b710b8 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -24,13 +24,14 @@
#include <linux/seccomp.h>
#include <linux/compat.h>
#include <trace/syscall.h>
+#include <asm/guarded_storage.h>
+#include <asm/access-regs.h>
#include <asm/page.h>
#include <linux/uaccess.h>
#include <asm/unistd.h>
-#include <asm/switch_to.h>
#include <asm/runtime_instr.h>
#include <asm/facility.h>
-#include <asm/fpu/api.h>
+#include <asm/fpu.h>
#include "entry.h"
@@ -246,22 +247,15 @@ static unsigned long __peek_user(struct task_struct *child, addr_t addr)
/*
* floating point control reg. is in the thread structure
*/
- tmp = child->thread.fpu.fpc;
+ tmp = child->thread.ufpu.fpc;
tmp <<= BITS_PER_LONG - 32;
} else if (addr < offsetof(struct user, regs.fp_regs) + sizeof(s390_fp_regs)) {
/*
- * floating point regs. are either in child->thread.fpu
- * or the child->thread.fpu.vxrs array
+ * floating point regs. are in the child->thread.ufpu.vxrs array
*/
offset = addr - offsetof(struct user, regs.fp_regs.fprs);
- if (cpu_has_vx())
- tmp = *(addr_t *)
- ((addr_t) child->thread.fpu.vxrs + 2*offset);
- else
- tmp = *(addr_t *)
- ((addr_t) child->thread.fpu.fprs + offset);
-
+ tmp = *(addr_t *)((addr_t)child->thread.ufpu.vxrs + 2 * offset);
} else if (addr < offsetof(struct user, regs.per_info) + sizeof(per_struct)) {
/*
* Handle access to the per_info structure.
@@ -395,21 +389,14 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)
*/
if ((unsigned int)data != 0)
return -EINVAL;
- child->thread.fpu.fpc = data >> (BITS_PER_LONG - 32);
+ child->thread.ufpu.fpc = data >> (BITS_PER_LONG - 32);
} else if (addr < offsetof(struct user, regs.fp_regs) + sizeof(s390_fp_regs)) {
/*
- * floating point regs. are either in child->thread.fpu
- * or the child->thread.fpu.vxrs array
+ * floating point regs. are in the child->thread.ufpu.vxrs array
*/
offset = addr - offsetof(struct user, regs.fp_regs.fprs);
- if (cpu_has_vx())
- *(addr_t *)((addr_t)
- child->thread.fpu.vxrs + 2*offset) = data;
- else
- *(addr_t *)((addr_t)
- child->thread.fpu.fprs + offset) = data;
-
+ *(addr_t *)((addr_t)child->thread.ufpu.vxrs + 2 * offset) = data;
} else if (addr < offsetof(struct user, regs.per_info) + sizeof(per_struct)) {
/*
* Handle access to the per_info structure.
@@ -622,21 +609,14 @@ static u32 __peek_user_compat(struct task_struct *child, addr_t addr)
/*
* floating point control reg. is in the thread structure
*/
- tmp = child->thread.fpu.fpc;
+ tmp = child->thread.ufpu.fpc;
} else if (addr < offsetof(struct compat_user, regs.fp_regs) + sizeof(s390_fp_regs)) {
/*
- * floating point regs. are either in child->thread.fpu
- * or the child->thread.fpu.vxrs array
+ * floating point regs. are in the child->thread.ufpu.vxrs array
*/
offset = addr - offsetof(struct compat_user, regs.fp_regs.fprs);
- if (cpu_has_vx())
- tmp = *(__u32 *)
- ((addr_t) child->thread.fpu.vxrs + 2*offset);
- else
- tmp = *(__u32 *)
- ((addr_t) child->thread.fpu.fprs + offset);
-
+ tmp = *(__u32 *)((addr_t)child->thread.ufpu.vxrs + 2 * offset);
} else if (addr < offsetof(struct compat_user, regs.per_info) + sizeof(struct compat_per_struct_kernel)) {
/*
* Handle access to the per_info structure.
@@ -748,21 +728,14 @@ static int __poke_user_compat(struct task_struct *child,
/*
* floating point control reg. is in the thread structure
*/
- child->thread.fpu.fpc = data;
+ child->thread.ufpu.fpc = data;
} else if (addr < offsetof(struct compat_user, regs.fp_regs) + sizeof(s390_fp_regs)) {
/*
- * floating point regs. are either in child->thread.fpu
- * or the child->thread.fpu.vxrs array
+ * floating point regs. are in the child->thread.ufpu.vxrs array
*/
offset = addr - offsetof(struct compat_user, regs.fp_regs.fprs);
- if (cpu_has_vx())
- *(__u32 *)((addr_t)
- child->thread.fpu.vxrs + 2*offset) = tmp;
- else
- *(__u32 *)((addr_t)
- child->thread.fpu.fprs + offset) = tmp;
-
+ *(__u32 *)((addr_t)child->thread.ufpu.vxrs + 2 * offset) = tmp;
} else if (addr < offsetof(struct compat_user, regs.per_info) + sizeof(struct compat_per_struct_kernel)) {
/*
* Handle access to the per_info structure.
@@ -893,10 +866,10 @@ static int s390_fpregs_get(struct task_struct *target,
_s390_fp_regs fp_regs;
if (target == current)
- save_fpu_regs();
+ save_user_fpu_regs();
- fp_regs.fpc = target->thread.fpu.fpc;
- fpregs_store(&fp_regs, &target->thread.fpu);
+ fp_regs.fpc = target->thread.ufpu.fpc;
+ fpregs_store(&fp_regs, &target->thread.ufpu);
return membuf_write(&to, &fp_regs, sizeof(fp_regs));
}
@@ -910,22 +883,17 @@ static int s390_fpregs_set(struct task_struct *target,
freg_t fprs[__NUM_FPRS];
if (target == current)
- save_fpu_regs();
-
- if (cpu_has_vx())
- convert_vx_to_fp(fprs, target->thread.fpu.vxrs);
- else
- memcpy(&fprs, target->thread.fpu.fprs, sizeof(fprs));
-
+ save_user_fpu_regs();
+ convert_vx_to_fp(fprs, target->thread.ufpu.vxrs);
if (count > 0 && pos < offsetof(s390_fp_regs, fprs)) {
- u32 ufpc[2] = { target->thread.fpu.fpc, 0 };
+ u32 ufpc[2] = { target->thread.ufpu.fpc, 0 };
rc = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &ufpc,
0, offsetof(s390_fp_regs, fprs));
if (rc)
return rc;
if (ufpc[1] != 0)
return -EINVAL;
- target->thread.fpu.fpc = ufpc[0];
+ target->thread.ufpu.fpc = ufpc[0];
}
if (rc == 0 && count > 0)
@@ -933,12 +901,7 @@ static int s390_fpregs_set(struct task_struct *target,
fprs, offsetof(s390_fp_regs, fprs), -1);
if (rc)
return rc;
-
- if (cpu_has_vx())
- convert_fp_to_vx(target->thread.fpu.vxrs, fprs);
- else
- memcpy(target->thread.fpu.fprs, &fprs, sizeof(fprs));
-
+ convert_fp_to_vx(target->thread.ufpu.vxrs, fprs);
return rc;
}
@@ -988,9 +951,9 @@ static int s390_vxrs_low_get(struct task_struct *target,
if (!cpu_has_vx())
return -ENODEV;
if (target == current)
- save_fpu_regs();
+ save_user_fpu_regs();
for (i = 0; i < __NUM_VXRS_LOW; i++)
- vxrs[i] = target->thread.fpu.vxrs[i].low;
+ vxrs[i] = target->thread.ufpu.vxrs[i].low;
return membuf_write(&to, vxrs, sizeof(vxrs));
}
@@ -1005,15 +968,15 @@ static int s390_vxrs_low_set(struct task_struct *target,
if (!cpu_has_vx())
return -ENODEV;
if (target == current)
- save_fpu_regs();
+ save_user_fpu_regs();
for (i = 0; i < __NUM_VXRS_LOW; i++)
- vxrs[i] = target->thread.fpu.vxrs[i].low;
+ vxrs[i] = target->thread.ufpu.vxrs[i].low;
rc = user_regset_copyin(&pos, &count, &kbuf, &ubuf, vxrs, 0, -1);
if (rc == 0)
for (i = 0; i < __NUM_VXRS_LOW; i++)
- target->thread.fpu.vxrs[i].low = vxrs[i];
+ target->thread.ufpu.vxrs[i].low = vxrs[i];
return rc;
}
@@ -1025,8 +988,8 @@ static int s390_vxrs_high_get(struct task_struct *target,
if (!cpu_has_vx())
return -ENODEV;
if (target == current)
- save_fpu_regs();
- return membuf_write(&to, target->thread.fpu.vxrs + __NUM_VXRS_LOW,
+ save_user_fpu_regs();
+ return membuf_write(&to, target->thread.ufpu.vxrs + __NUM_VXRS_LOW,
__NUM_VXRS_HIGH * sizeof(__vector128));
}
@@ -1040,10 +1003,10 @@ static int s390_vxrs_high_set(struct task_struct *target,
if (!cpu_has_vx())
return -ENODEV;
if (target == current)
- save_fpu_regs();
+ save_user_fpu_regs();
rc = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
- target->thread.fpu.vxrs + __NUM_VXRS_LOW, 0, -1);
+ target->thread.ufpu.vxrs + __NUM_VXRS_LOW, 0, -1);
return rc;
}
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index d1f3b56e7afc..24ed33f044ec 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -504,12 +504,12 @@ static void __init setup_resources(void)
int j;
u64 i;
- code_resource.start = (unsigned long) _text;
- code_resource.end = (unsigned long) _etext - 1;
- data_resource.start = (unsigned long) _etext;
- data_resource.end = (unsigned long) _edata - 1;
- bss_resource.start = (unsigned long) __bss_start;
- bss_resource.end = (unsigned long) __bss_stop - 1;
+ code_resource.start = __pa_symbol(_text);
+ code_resource.end = __pa_symbol(_etext) - 1;
+ data_resource.start = __pa_symbol(_etext);
+ data_resource.end = __pa_symbol(_edata) - 1;
+ bss_resource.start = __pa_symbol(__bss_start);
+ bss_resource.end = __pa_symbol(__bss_stop) - 1;
for_each_mem_range(i, &start, &end) {
res = memblock_alloc(sizeof(*res), 8);
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index 43e9661cd715..6c2cb345402f 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -30,8 +30,8 @@
#include <linux/compat.h>
#include <asm/ucontext.h>
#include <linux/uaccess.h>
+#include <asm/access-regs.h>
#include <asm/lowcore.h>
-#include <asm/switch_to.h>
#include <asm/vdso.h>
#include "entry.h"
@@ -109,7 +109,7 @@ struct rt_sigframe
static void store_sigregs(void)
{
save_access_regs(current->thread.acrs);
- save_fpu_regs();
+ save_user_fpu_regs();
}
/* Load registers after signal return */
@@ -131,7 +131,7 @@ static int save_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
memcpy(&user_sregs.regs.gprs, &regs->gprs, sizeof(sregs->regs.gprs));
memcpy(&user_sregs.regs.acrs, current->thread.acrs,
sizeof(user_sregs.regs.acrs));
- fpregs_store(&user_sregs.fpregs, &current->thread.fpu);
+ fpregs_store(&user_sregs.fpregs, &current->thread.ufpu);
if (__copy_to_user(sregs, &user_sregs, sizeof(_sigregs)))
return -EFAULT;
return 0;
@@ -165,7 +165,7 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
memcpy(&current->thread.acrs, &user_sregs.regs.acrs,
sizeof(current->thread.acrs));
- fpregs_load(&user_sregs.fpregs, &current->thread.fpu);
+ fpregs_load(&user_sregs.fpregs, &current->thread.ufpu);
clear_pt_regs_flag(regs, PIF_SYSCALL); /* No longer in a system call */
return 0;
@@ -181,11 +181,11 @@ static int save_sigregs_ext(struct pt_regs *regs,
/* Save vector registers to signal stack */
if (cpu_has_vx()) {
for (i = 0; i < __NUM_VXRS_LOW; i++)
- vxrs[i] = current->thread.fpu.vxrs[i].low;
+ vxrs[i] = current->thread.ufpu.vxrs[i].low;
if (__copy_to_user(&sregs_ext->vxrs_low, vxrs,
sizeof(sregs_ext->vxrs_low)) ||
__copy_to_user(&sregs_ext->vxrs_high,
- current->thread.fpu.vxrs + __NUM_VXRS_LOW,
+ current->thread.ufpu.vxrs + __NUM_VXRS_LOW,
sizeof(sregs_ext->vxrs_high)))
return -EFAULT;
}
@@ -202,12 +202,12 @@ static int restore_sigregs_ext(struct pt_regs *regs,
if (cpu_has_vx()) {
if (__copy_from_user(vxrs, &sregs_ext->vxrs_low,
sizeof(sregs_ext->vxrs_low)) ||
- __copy_from_user(current->thread.fpu.vxrs + __NUM_VXRS_LOW,
+ __copy_from_user(current->thread.ufpu.vxrs + __NUM_VXRS_LOW,
&sregs_ext->vxrs_high,
sizeof(sregs_ext->vxrs_high)))
return -EFAULT;
for (i = 0; i < __NUM_VXRS_LOW; i++)
- current->thread.fpu.vxrs[i].low = vxrs[i];
+ current->thread.ufpu.vxrs[i].low = vxrs[i];
}
return 0;
}
@@ -222,7 +222,7 @@ SYSCALL_DEFINE0(sigreturn)
if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE))
goto badframe;
set_current_blocked(&set);
- save_fpu_regs();
+ save_user_fpu_regs();
if (restore_sigregs(regs, &frame->sregs))
goto badframe;
if (restore_sigregs_ext(regs, &frame->sregs_ext))
@@ -246,7 +246,7 @@ SYSCALL_DEFINE0(rt_sigreturn)
set_current_blocked(&set);
if (restore_altstack(&frame->uc.uc_stack))
goto badframe;
- save_fpu_regs();
+ save_user_fpu_regs();
if (restore_sigregs(regs, &frame->uc.uc_mcontext))
goto badframe;
if (restore_sigregs_ext(regs, &frame->uc.uc_mcontext_ext))
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index c39d9f0d4b1c..0324649aae0a 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -36,12 +36,13 @@
#include <linux/sched/task_stack.h>
#include <linux/crash_dump.h>
#include <linux/kprobes.h>
+#include <asm/access-regs.h>
#include <asm/asm-offsets.h>
#include <asm/ctlreg.h>
#include <asm/pfault.h>
#include <asm/diag.h>
-#include <asm/switch_to.h>
#include <asm/facility.h>
+#include <asm/fpu.h>
#include <asm/ipl.h>
#include <asm/setup.h>
#include <asm/irq.h>
diff --git a/arch/s390/kernel/sysinfo.c b/arch/s390/kernel/sysinfo.c
index f6f8f498c9be..2be30a96696a 100644
--- a/arch/s390/kernel/sysinfo.c
+++ b/arch/s390/kernel/sysinfo.c
@@ -20,7 +20,7 @@
#include <asm/sysinfo.h>
#include <asm/cpcmd.h>
#include <asm/topology.h>
-#include <asm/fpu/api.h>
+#include <asm/fpu.h>
int topology_max_mnest;
@@ -397,7 +397,7 @@ static void service_level_vm_print(struct seq_file *m,
{
char *query_buffer, *str;
- query_buffer = kmalloc(1024, GFP_KERNEL | GFP_DMA);
+ query_buffer = kmalloc(1024, GFP_KERNEL);
if (!query_buffer)
return;
cpcmd("QUERY CPLEVEL", query_buffer, 1024, NULL);
@@ -426,9 +426,9 @@ subsys_initcall(create_proc_service_level);
*/
void s390_adjust_jiffies(void)
{
+ DECLARE_KERNEL_FPU_ONSTACK16(fpu);
struct sysinfo_1_2_2 *info;
unsigned long capability;
- struct kernel_fpu fpu;
info = (void *) get_zeroed_page(GFP_KERNEL);
if (!info)
@@ -447,21 +447,14 @@ void s390_adjust_jiffies(void)
* point division ..
*/
kernel_fpu_begin(&fpu, KERNEL_FPR);
- asm volatile(
- " sfpc %3\n"
- " l %0,%1\n"
- " tmlh %0,0xff80\n"
- " jnz 0f\n"
- " cefbr %%f2,%0\n"
- " j 1f\n"
- "0: le %%f2,%1\n"
- "1: cefbr %%f0,%2\n"
- " debr %%f0,%%f2\n"
- " cgebr %0,5,%%f0\n"
- : "=&d" (capability)
- : "Q" (info->capability), "d" (10000000), "d" (0)
- : "cc"
- );
+ fpu_sfpc(0);
+ if (info->capability & 0xff800000)
+ fpu_ldgr(2, info->capability);
+ else
+ fpu_cefbr(2, info->capability);
+ fpu_cefbr(0, 10000000);
+ fpu_debr(0, 2);
+ capability = fpu_cgebr(0, 5);
kernel_fpu_end(&fpu, KERNEL_FPR);
} else
/*
diff --git a/arch/s390/kernel/text_amode31.S b/arch/s390/kernel/text_amode31.S
index 14c6d25c035f..c0a70efa2426 100644
--- a/arch/s390/kernel/text_amode31.S
+++ b/arch/s390/kernel/text_amode31.S
@@ -90,7 +90,7 @@ SYM_FUNC_START(_diag26c_amode31)
SYM_FUNC_END(_diag26c_amode31)
/*
- * void _diag0c_amode31(struct hypfs_diag0c_entry *entry)
+ * void _diag0c_amode31(unsigned long rx)
*/
SYM_FUNC_START(_diag0c_amode31)
sam31
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 14abad953c02..fb9f31f36628 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -251,8 +251,8 @@ static struct clocksource clocksource_tod = {
.rating = 400,
.read = read_tod_clock,
.mask = CLOCKSOURCE_MASK(64),
- .mult = 1000,
- .shift = 12,
+ .mult = 4096000,
+ .shift = 24,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
.vdso_clock_mode = VDSO_CLOCKMODE_TOD,
};
@@ -716,7 +716,7 @@ out_unlock:
/*
* STP subsys sysfs interface functions
*/
-static struct bus_type stp_subsys = {
+static const struct bus_type stp_subsys = {
.name = "stp",
.dev_name = "stp",
};
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 46dac4540ca8..52578b5cecbd 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -28,8 +28,8 @@
#include <linux/cpu.h>
#include <linux/entry-common.h>
#include <asm/asm-extable.h>
-#include <asm/fpu/api.h>
#include <asm/vtime.h>
+#include <asm/fpu.h>
#include "entry.h"
static inline void __user *get_trap_ip(struct pt_regs *regs)
@@ -201,8 +201,8 @@ static void vector_exception(struct pt_regs *regs)
}
/* get vector interrupt code from fpc */
- save_fpu_regs();
- vic = (current->thread.fpu.fpc & 0xf00) >> 8;
+ save_user_fpu_regs();
+ vic = (current->thread.ufpu.fpc & 0xf00) >> 8;
switch (vic) {
case 1: /* invalid vector operation */
si_code = FPE_FLTINV;
@@ -227,9 +227,9 @@ static void vector_exception(struct pt_regs *regs)
static void data_exception(struct pt_regs *regs)
{
- save_fpu_regs();
- if (current->thread.fpu.fpc & FPC_DXC_MASK)
- do_fp_trap(regs, current->thread.fpu.fpc);
+ save_user_fpu_regs();
+ if (current->thread.ufpu.fpc & FPC_DXC_MASK)
+ do_fp_trap(regs, current->thread.ufpu.fpc);
else
do_trap(regs, SIGILL, ILL_ILLOPN, "data exception");
}
diff --git a/arch/s390/kernel/uprobes.c b/arch/s390/kernel/uprobes.c
index b88345ef8bd9..5b0633ea8d93 100644
--- a/arch/s390/kernel/uprobes.c
+++ b/arch/s390/kernel/uprobes.c
@@ -12,7 +12,6 @@
#include <linux/kdebug.h>
#include <linux/sched/task_stack.h>
-#include <asm/switch_to.h>
#include <asm/facility.h>
#include <asm/kprobes.h>
#include <asm/dis.h>
diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c
index bbaefd84f15e..a45b3a4c91db 100644
--- a/arch/s390/kernel/vdso.c
+++ b/arch/s390/kernel/vdso.c
@@ -25,10 +25,7 @@ extern char vdso32_start[], vdso32_end[];
static struct vm_special_mapping vvar_mapping;
-static union {
- struct vdso_data data[CS_BASES];
- u8 page[PAGE_SIZE];
-} vdso_data_store __page_aligned_data;
+static union vdso_data_store vdso_data_store __page_aligned_data;
struct vdso_data *vdso_data = vdso_data_store.data;
diff --git a/arch/s390/kernel/vdso32/Makefile b/arch/s390/kernel/vdso32/Makefile
index caec7db6f966..b12a274cbb47 100644
--- a/arch/s390/kernel/vdso32/Makefile
+++ b/arch/s390/kernel/vdso32/Makefile
@@ -22,7 +22,7 @@ KBUILD_CFLAGS_32 := $(filter-out -m64,$(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
-LDFLAGS_vdso32.so.dbg += -fPIC -shared -soname=linux-vdso32.so.1 \
+LDFLAGS_vdso32.so.dbg += -shared -soname=linux-vdso32.so.1 \
--hash-style=both --build-id=sha1 -melf_s390 -T
$(targets:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_32)
diff --git a/arch/s390/kernel/vdso32/vdso32.lds.S b/arch/s390/kernel/vdso32/vdso32.lds.S
index edf5ff1debe1..65b9513a5a0e 100644
--- a/arch/s390/kernel/vdso32/vdso32.lds.S
+++ b/arch/s390/kernel/vdso32/vdso32.lds.S
@@ -9,7 +9,6 @@
OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390")
OUTPUT_ARCH(s390:31-bit)
-ENTRY(_start)
SECTIONS
{
diff --git a/arch/s390/kernel/vdso64/Makefile b/arch/s390/kernel/vdso64/Makefile
index e3c9085f8fa7..ef9832726097 100644
--- a/arch/s390/kernel/vdso64/Makefile
+++ b/arch/s390/kernel/vdso64/Makefile
@@ -25,8 +25,9 @@ KBUILD_AFLAGS_64 += -m64
KBUILD_CFLAGS_64 := $(filter-out -m64,$(KBUILD_CFLAGS))
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
-ldflags-y := -fPIC -shared -soname=linux-vdso64.so.1 \
+ldflags-y := -shared -soname=linux-vdso64.so.1 \
--hash-style=both --build-id=sha1 -T
$(targets:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_64)
diff --git a/arch/s390/kernel/vdso64/vdso64.lds.S b/arch/s390/kernel/vdso64/vdso64.lds.S
index 4461ea151e49..37e2a505e81d 100644
--- a/arch/s390/kernel/vdso64/vdso64.lds.S
+++ b/arch/s390/kernel/vdso64/vdso64.lds.S
@@ -9,7 +9,6 @@
OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390")
OUTPUT_ARCH(s390:64-bit)
-ENTRY(_start)
SECTIONS
{
diff --git a/arch/s390/kernel/vmcore_info.c b/arch/s390/kernel/vmcore_info.c
new file mode 100644
index 000000000000..d296dfc22191
--- /dev/null
+++ b/arch/s390/kernel/vmcore_info.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/vmcore_info.h>
+#include <asm/abs_lowcore.h>
+#include <linux/mm.h>
+#include <asm/setup.h>
+
+void arch_crash_save_vmcoreinfo(void)
+{
+ struct lowcore *abs_lc;
+
+ VMCOREINFO_SYMBOL(lowcore_ptr);
+ VMCOREINFO_SYMBOL(high_memory);
+ 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("KERNELOFFSET=%lx\n", kaslr_offset());
+ 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 e32ef446f451..48de296e8905 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -59,6 +59,14 @@ SECTIONS
} :text = 0x0700
RO_DATA(PAGE_SIZE)
+ .data.rel.ro : {
+ *(.data.rel.ro .data.rel.ro.*)
+ }
+ .got : {
+ __got_start = .;
+ *(.got)
+ __got_end = .;
+ }
. = ALIGN(PAGE_SIZE);
_sdata = .; /* Start of data section */
@@ -73,6 +81,9 @@ SECTIONS
__end_ro_after_init = .;
RW_DATA(0x100, PAGE_SIZE, THREAD_SIZE)
+ .data.rel : {
+ *(.data.rel*)
+ }
BOOT_DATA_PRESERVED
. = ALIGN(8);
@@ -181,6 +192,7 @@ SECTIONS
PERCPU_SECTION(0x100)
+#ifdef CONFIG_PIE_BUILD
.dynsym ALIGN(8) : {
__dynsym_start = .;
*(.dynsym)
@@ -191,6 +203,19 @@ SECTIONS
*(.rela*)
__rela_dyn_end = .;
}
+ .dynamic ALIGN(8) : {
+ *(.dynamic)
+ }
+ .dynstr ALIGN(8) : {
+ *(.dynstr)
+ }
+#endif
+ .hash ALIGN(8) : {
+ *(.hash)
+ }
+ .gnu.hash ALIGN(8) : {
+ *(.gnu.hash)
+ }
. = ALIGN(PAGE_SIZE);
__init_end = .; /* freed after init ends here */
@@ -214,9 +239,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)
@@ -235,6 +265,30 @@ SECTIONS
DWARF_DEBUG
ELF_DETAILS
+ /*
+ * Make sure that the .got.plt is either completely empty or it
+ * contains only the three reserved double words.
+ */
+ .got.plt : {
+ *(.got.plt)
+ }
+ ASSERT(SIZEOF(.got.plt) == 0 || SIZEOF(.got.plt) == 0x18, "Unexpected GOT/PLT entries detected!")
+
+ /*
+ * Sections that should stay zero sized, which is safer to
+ * explicitly check instead of blindly discarding.
+ */
+ .plt : {
+ *(.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
/DISCARD/ : {
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index e0a88dcaf5cb..24a18e5ef6e8 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -210,13 +210,13 @@ void vtime_flush(struct task_struct *tsk)
virt_timer_expire();
steal = S390_lowcore.steal_timer;
- avg_steal = S390_lowcore.avg_steal_timer / 2;
+ avg_steal = S390_lowcore.avg_steal_timer;
if ((s64) steal > 0) {
S390_lowcore.steal_timer = 0;
account_steal_time(cputime_to_nsecs(steal));
avg_steal += steal;
}
- S390_lowcore.avg_steal_timer = avg_steal;
+ S390_lowcore.avg_steal_timer = avg_steal / 2;
}
static u64 vtime_delta(void)
diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig
index 72e9b7dcdf7d..cae908d64550 100644
--- a/arch/s390/kvm/Kconfig
+++ b/arch/s390/kvm/Kconfig
@@ -19,7 +19,6 @@ if VIRTUALIZATION
config KVM
def_tristate y
prompt "Kernel-based Virtual Machine (KVM) support"
- depends on HAVE_KVM
select HAVE_KVM_CPU_RELAX_INTERCEPT
select HAVE_KVM_VCPU_ASYNC_IOCTL
select KVM_ASYNC_PF
diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c
index 3c65b8258ae6..2a32438e09ce 100644
--- a/arch/s390/kvm/diag.c
+++ b/arch/s390/kvm/diag.c
@@ -102,7 +102,7 @@ static int __diag_page_ref_service(struct kvm_vcpu *vcpu)
parm.token_addr & 7 || parm.zarch != 0x8000000000000000ULL)
return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
- if (kvm_is_error_gpa(vcpu->kvm, parm.token_addr))
+ if (!kvm_is_gpa_in_memslot(vcpu->kvm, parm.token_addr))
return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
vcpu->arch.pfault_token = parm.token_addr;
diff --git a/arch/s390/kvm/gaccess.c b/arch/s390/kvm/gaccess.c
index 5bfcc50c1a68..5bf3d94e9dda 100644
--- a/arch/s390/kvm/gaccess.c
+++ b/arch/s390/kvm/gaccess.c
@@ -11,11 +11,11 @@
#include <linux/err.h>
#include <linux/pgtable.h>
#include <linux/bitfield.h>
+#include <asm/access-regs.h>
#include <asm/fault.h>
#include <asm/gmap.h>
#include "kvm-s390.h"
#include "gaccess.h"
-#include <asm/switch_to.h>
union asce {
unsigned long val;
@@ -391,7 +391,8 @@ static int ar_translation(struct kvm_vcpu *vcpu, union asce *asce, u8 ar,
if (ar >= NUM_ACRS)
return -EINVAL;
- save_access_regs(vcpu->run->s.regs.acrs);
+ if (vcpu->arch.acrs_loaded)
+ save_access_regs(vcpu->run->s.regs.acrs);
alet.val = vcpu->run->s.regs.acrs[ar];
if (ar == 0 || alet.val == 0) {
@@ -664,7 +665,7 @@ static unsigned long guest_translate(struct kvm_vcpu *vcpu, unsigned long gva,
case ASCE_TYPE_REGION1: {
union region1_table_entry rfte;
- if (kvm_is_error_gpa(vcpu->kvm, ptr))
+ if (!kvm_is_gpa_in_memslot(vcpu->kvm, ptr))
return PGM_ADDRESSING;
if (deref_table(vcpu->kvm, ptr, &rfte.val))
return -EFAULT;
@@ -682,7 +683,7 @@ static unsigned long guest_translate(struct kvm_vcpu *vcpu, unsigned long gva,
case ASCE_TYPE_REGION2: {
union region2_table_entry rste;
- if (kvm_is_error_gpa(vcpu->kvm, ptr))
+ if (!kvm_is_gpa_in_memslot(vcpu->kvm, ptr))
return PGM_ADDRESSING;
if (deref_table(vcpu->kvm, ptr, &rste.val))
return -EFAULT;
@@ -700,7 +701,7 @@ static unsigned long guest_translate(struct kvm_vcpu *vcpu, unsigned long gva,
case ASCE_TYPE_REGION3: {
union region3_table_entry rtte;
- if (kvm_is_error_gpa(vcpu->kvm, ptr))
+ if (!kvm_is_gpa_in_memslot(vcpu->kvm, ptr))
return PGM_ADDRESSING;
if (deref_table(vcpu->kvm, ptr, &rtte.val))
return -EFAULT;
@@ -728,7 +729,7 @@ static unsigned long guest_translate(struct kvm_vcpu *vcpu, unsigned long gva,
case ASCE_TYPE_SEGMENT: {
union segment_table_entry ste;
- if (kvm_is_error_gpa(vcpu->kvm, ptr))
+ if (!kvm_is_gpa_in_memslot(vcpu->kvm, ptr))
return PGM_ADDRESSING;
if (deref_table(vcpu->kvm, ptr, &ste.val))
return -EFAULT;
@@ -748,7 +749,7 @@ static unsigned long guest_translate(struct kvm_vcpu *vcpu, unsigned long gva,
ptr = ste.fc0.pto * (PAGE_SIZE / 2) + vaddr.px * 8;
}
}
- if (kvm_is_error_gpa(vcpu->kvm, ptr))
+ if (!kvm_is_gpa_in_memslot(vcpu->kvm, ptr))
return PGM_ADDRESSING;
if (deref_table(vcpu->kvm, ptr, &pte.val))
return -EFAULT;
@@ -770,7 +771,7 @@ absolute_address:
*prot = PROT_TYPE_IEP;
return PGM_PROTECTION;
}
- if (kvm_is_error_gpa(vcpu->kvm, raddr.addr))
+ if (!kvm_is_gpa_in_memslot(vcpu->kvm, raddr.addr))
return PGM_ADDRESSING;
*gpa = raddr.addr;
return 0;
@@ -957,7 +958,7 @@ static int guest_range_to_gpas(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar,
return rc;
} else {
gpa = kvm_s390_real_to_abs(vcpu, ga);
- if (kvm_is_error_gpa(vcpu->kvm, gpa)) {
+ if (!kvm_is_gpa_in_memslot(vcpu->kvm, gpa)) {
rc = PGM_ADDRESSING;
prot = PROT_NONE;
}
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index fc4007cc067a..4f0e7f61edf7 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -19,13 +19,13 @@
#include <linux/slab.h>
#include <linux/bitmap.h>
#include <linux/vmalloc.h>
+#include <asm/access-regs.h>
#include <asm/asm-offsets.h>
#include <asm/dis.h>
#include <linux/uaccess.h>
#include <asm/sclp.h>
#include <asm/isc.h>
#include <asm/gmap.h>
-#include <asm/switch_to.h>
#include <asm/nmi.h>
#include <asm/airq.h>
#include <asm/tpi.h>
@@ -584,7 +584,7 @@ static int __write_machine_check(struct kvm_vcpu *vcpu,
mci.val = mchk->mcic;
/* take care of lazy register loading */
- save_fpu_regs();
+ kvm_s390_fpu_store(vcpu->run);
save_access_regs(vcpu->run->s.regs.acrs);
if (MACHINE_HAS_GS && vcpu->arch.gs_enabled)
save_gs_cb(current->thread.gs_cb);
@@ -648,7 +648,7 @@ static int __write_machine_check(struct kvm_vcpu *vcpu,
}
rc |= write_guest_lc(vcpu, __LC_GPREGS_SAVE_AREA,
vcpu->run->s.regs.gprs, 128);
- rc |= put_guest_lc(vcpu, current->thread.fpu.fpc,
+ rc |= put_guest_lc(vcpu, vcpu->run->s.regs.fpc,
(u32 __user *) __LC_FP_CREG_SAVE_AREA);
rc |= put_guest_lc(vcpu, vcpu->arch.sie_block->todpr,
(u32 __user *) __LC_TOD_PROGREG_SAVE_AREA);
@@ -1031,7 +1031,7 @@ static int __must_check __deliver_service_ev(struct kvm_vcpu *vcpu)
return 0;
}
ext = fi->srv_signal;
- /* only clear the event bit */
+ /* only clear the event bits */
fi->srv_signal.ext_params &= ~SCCB_EVENT_PENDING;
clear_bit(IRQ_PEND_EXT_SERVICE_EV, &fi->pending_irqs);
spin_unlock(&fi->lock);
@@ -1041,7 +1041,7 @@ static int __must_check __deliver_service_ev(struct kvm_vcpu *vcpu)
trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_INT_SERVICE,
ext.ext_params, 0);
- return write_sclp(vcpu, SCCB_EVENT_PENDING);
+ return write_sclp(vcpu, ext.ext_params & SCCB_EVENT_PENDING);
}
static int __must_check __deliver_pfault_done(struct kvm_vcpu *vcpu)
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index ea63ac769889..5147b943a864 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -33,19 +33,19 @@
#include <linux/pgtable.h>
#include <linux/mmu_notifier.h>
+#include <asm/access-regs.h>
#include <asm/asm-offsets.h>
#include <asm/lowcore.h>
#include <asm/stp.h>
#include <asm/gmap.h>
#include <asm/nmi.h>
-#include <asm/switch_to.h>
#include <asm/isc.h>
#include <asm/sclp.h>
#include <asm/cpacf.h>
#include <asm/timex.h>
+#include <asm/fpu.h>
#include <asm/ap.h>
#include <asm/uv.h>
-#include <asm/fpu/api.h>
#include "kvm-s390.h"
#include "gaccess.h"
#include "pci.h"
@@ -2878,7 +2878,7 @@ static int kvm_s390_vm_mem_op_abs(struct kvm *kvm, struct kvm_s390_mem_op *mop)
srcu_idx = srcu_read_lock(&kvm->srcu);
- if (kvm_is_error_gpa(kvm, mop->gaddr)) {
+ if (!kvm_is_gpa_in_memslot(kvm, mop->gaddr)) {
r = PGM_ADDRESSING;
goto out_unlock;
}
@@ -2940,7 +2940,7 @@ static int kvm_s390_vm_mem_op_cmpxchg(struct kvm *kvm, struct kvm_s390_mem_op *m
srcu_idx = srcu_read_lock(&kvm->srcu);
- if (kvm_is_error_gpa(kvm, mop->gaddr)) {
+ if (!kvm_is_gpa_in_memslot(kvm, mop->gaddr)) {
r = PGM_ADDRESSING;
goto out_unlock;
}
@@ -3153,7 +3153,7 @@ static int kvm_s390_apxa_installed(void)
*/
static void kvm_s390_set_crycb_format(struct kvm *kvm)
{
- kvm->arch.crypto.crycbd = (__u32)(unsigned long) kvm->arch.crypto.crycb;
+ kvm->arch.crypto.crycbd = virt_to_phys(kvm->arch.crypto.crycb);
/* Clear the CRYCB format bits - i.e., set format 0 by default */
kvm->arch.crypto.crycbd &= ~(CRYCB_FORMAT_MASK);
@@ -3951,6 +3951,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
KVM_SYNC_ARCH0 |
KVM_SYNC_PFAULT |
KVM_SYNC_DIAG318;
+ vcpu->arch.acrs_loaded = false;
kvm_s390_set_prefix(vcpu, 0);
if (test_kvm_facility(vcpu->kvm, 64))
vcpu->run->kvm_valid_regs |= KVM_SYNC_RICCB;
@@ -4829,8 +4830,6 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
vcpu->run->s.regs.gprs,
sizeof(sie_page->pv_grregs));
}
- if (test_cpu_flag(CIF_FPU))
- load_fpu_regs();
exit_reason = sie64a(vcpu->arch.sie_block,
vcpu->run->s.regs.gprs);
if (kvm_s390_pv_cpu_is_protected(vcpu)) {
@@ -4951,16 +4950,8 @@ static void sync_regs(struct kvm_vcpu *vcpu)
}
save_access_regs(vcpu->arch.host_acrs);
restore_access_regs(vcpu->run->s.regs.acrs);
- /* save host (userspace) fprs/vrs */
- save_fpu_regs();
- vcpu->arch.host_fpregs.fpc = current->thread.fpu.fpc;
- vcpu->arch.host_fpregs.regs = current->thread.fpu.regs;
- if (cpu_has_vx())
- current->thread.fpu.regs = vcpu->run->s.regs.vrs;
- else
- current->thread.fpu.regs = vcpu->run->s.regs.fprs;
- current->thread.fpu.fpc = vcpu->run->s.regs.fpc;
-
+ vcpu->arch.acrs_loaded = true;
+ kvm_s390_fpu_load(vcpu->run);
/* Sync fmt2 only data */
if (likely(!kvm_s390_pv_cpu_is_protected(vcpu))) {
sync_regs_fmt2(vcpu);
@@ -5021,12 +5012,8 @@ static void store_regs(struct kvm_vcpu *vcpu)
kvm_run->s.regs.pfc = vcpu->arch.pfault_compare;
save_access_regs(vcpu->run->s.regs.acrs);
restore_access_regs(vcpu->arch.host_acrs);
- /* Save guest register state */
- save_fpu_regs();
- vcpu->run->s.regs.fpc = current->thread.fpu.fpc;
- /* Restore will be done lazily at return */
- current->thread.fpu.fpc = vcpu->arch.host_fpregs.fpc;
- current->thread.fpu.regs = vcpu->arch.host_fpregs.regs;
+ vcpu->arch.acrs_loaded = false;
+ kvm_s390_fpu_store(vcpu->run);
if (likely(!kvm_s390_pv_cpu_is_protected(vcpu)))
store_regs_fmt2(vcpu);
}
@@ -5034,6 +5021,7 @@ static void store_regs(struct kvm_vcpu *vcpu)
int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
{
struct kvm_run *kvm_run = vcpu->run;
+ DECLARE_KERNEL_FPU_ONSTACK32(fpu);
int rc;
/*
@@ -5075,6 +5063,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
goto out;
}
+ kernel_fpu_begin(&fpu, KERNEL_FPC | KERNEL_VXR);
sync_regs(vcpu);
enable_cpu_timer_accounting(vcpu);
@@ -5098,6 +5087,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
disable_cpu_timer_accounting(vcpu);
store_regs(vcpu);
+ kernel_fpu_end(&fpu, KERNEL_FPC | KERNEL_VXR);
kvm_sigset_deactivate(vcpu);
@@ -5172,8 +5162,7 @@ int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
* switch in the run ioctl. Let's update our copies before we save
* it into the save area
*/
- save_fpu_regs();
- vcpu->run->s.regs.fpc = current->thread.fpu.fpc;
+ kvm_s390_fpu_store(vcpu->run);
save_access_regs(vcpu->run->s.regs.acrs);
return kvm_s390_store_status_unloaded(vcpu, addr);
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h
index a7ea80cfa445..111eb5c74784 100644
--- a/arch/s390/kvm/kvm-s390.h
+++ b/arch/s390/kvm/kvm-s390.h
@@ -20,6 +20,24 @@
#include <asm/processor.h>
#include <asm/sclp.h>
+static inline void kvm_s390_fpu_store(struct kvm_run *run)
+{
+ fpu_stfpc(&run->s.regs.fpc);
+ if (cpu_has_vx())
+ save_vx_regs((__vector128 *)&run->s.regs.vrs);
+ else
+ save_fp_regs((freg_t *)&run->s.regs.fprs);
+}
+
+static inline void kvm_s390_fpu_load(struct kvm_run *run)
+{
+ fpu_lfpc_safe(&run->s.regs.fpc);
+ if (cpu_has_vx())
+ load_vx_regs((__vector128 *)&run->s.regs.vrs);
+ else
+ load_fp_regs((freg_t *)&run->s.regs.fprs);
+}
+
/* Transactional Memory Execution related macros */
#define IS_TE_ENABLED(vcpu) ((vcpu->arch.sie_block->ecb & ECB_TE))
#define TDB_FORMAT1 1
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index f875a404a0a0..1be19cc9d73c 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -149,7 +149,7 @@ static int handle_set_prefix(struct kvm_vcpu *vcpu)
* first page, since address is 8k aligned and memory pieces are always
* at least 1MB aligned and have at least a size of 1MB.
*/
- if (kvm_is_error_gpa(vcpu->kvm, address))
+ if (!kvm_is_gpa_in_memslot(vcpu->kvm, address))
return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
kvm_s390_set_prefix(vcpu, address);
@@ -464,7 +464,7 @@ static int handle_test_block(struct kvm_vcpu *vcpu)
return kvm_s390_inject_prog_irq(vcpu, &vcpu->arch.pgm);
addr = kvm_s390_real_to_abs(vcpu, addr);
- if (kvm_is_error_gpa(vcpu->kvm, addr))
+ if (!kvm_is_gpa_in_memslot(vcpu->kvm, addr))
return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
/*
* We don't expect errors on modern systems, and do not care
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c
index d9696b530064..55c34cb35428 100644
--- a/arch/s390/kvm/sigp.c
+++ b/arch/s390/kvm/sigp.c
@@ -172,7 +172,7 @@ static int __sigp_set_prefix(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu,
* first page, since address is 8k aligned and memory pieces are always
* at least 1MB aligned and have at least a size of 1MB.
*/
- if (kvm_is_error_gpa(vcpu->kvm, irq.u.prefix.address)) {
+ if (!kvm_is_gpa_in_memslot(vcpu->kvm, irq.u.prefix.address)) {
*reg &= 0xffffffff00000000UL;
*reg |= SIGP_STATUS_INVALID_PARAMETER;
return SIGP_CC_STATUS_STORED;
diff --git a/arch/s390/kvm/vsie.c b/arch/s390/kvm/vsie.c
index 3af3bd20ac7b..b2c9f010f0fe 100644
--- a/arch/s390/kvm/vsie.c
+++ b/arch/s390/kvm/vsie.c
@@ -18,7 +18,6 @@
#include <asm/sclp.h>
#include <asm/nmi.h>
#include <asm/dis.h>
-#include <asm/fpu/api.h>
#include <asm/facility.h>
#include "kvm-s390.h"
#include "gaccess.h"
@@ -1149,8 +1148,6 @@ static int do_vsie_run(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
*/
vcpu->arch.sie_block->prog0c |= PROG_IN_SIE;
barrier();
- if (test_cpu_flag(CIF_FPU))
- load_fpu_regs();
if (!kvm_s390_vcpu_sie_inhibited(vcpu))
rc = sie64a(scb_s, vcpu->run->s.regs.gprs);
barrier();
diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile
index 7c50eca85ca4..90eac15ea62a 100644
--- a/arch/s390/lib/Makefile
+++ b/arch/s390/lib/Makefile
@@ -4,6 +4,7 @@
#
lib-y += delay.o string.o uaccess.o find.o spinlock.o tishift.o
+lib-y += csum-partial.o
obj-y += mem.o xor.o
lib-$(CONFIG_KPROBES) += probes.o
lib-$(CONFIG_UPROBES) += probes.o
diff --git a/arch/s390/lib/csum-partial.c b/arch/s390/lib/csum-partial.c
new file mode 100644
index 000000000000..458abd9bac70
--- /dev/null
+++ b/arch/s390/lib/csum-partial.c
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/export.h>
+#include <asm/checksum.h>
+#include <asm/fpu.h>
+
+/*
+ * Computes the checksum of a memory block at src, length len,
+ * and adds in "sum" (32-bit). If copy is true copies to dst.
+ *
+ * Returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic.
+ *
+ * This function must be called with even lengths, except
+ * for the last fragment, which may be odd.
+ *
+ * It's best to have src and dst aligned on a 64-bit boundary.
+ */
+static __always_inline __wsum csum_copy(void *dst, const void *src, int len, __wsum sum, bool copy)
+{
+ DECLARE_KERNEL_FPU_ONSTACK8(vxstate);
+
+ if (!cpu_has_vx()) {
+ if (copy)
+ memcpy(dst, src, len);
+ return cksm(dst, len, sum);
+ }
+ kernel_fpu_begin(&vxstate, KERNEL_VXR_V16V23);
+ fpu_vlvgf(16, (__force u32)sum, 1);
+ fpu_vzero(17);
+ fpu_vzero(18);
+ fpu_vzero(19);
+ while (len >= 64) {
+ fpu_vlm(20, 23, src);
+ if (copy) {
+ fpu_vstm(20, 23, dst);
+ dst += 64;
+ }
+ fpu_vcksm(16, 20, 16);
+ fpu_vcksm(17, 21, 17);
+ fpu_vcksm(18, 22, 18);
+ fpu_vcksm(19, 23, 19);
+ src += 64;
+ len -= 64;
+ }
+ while (len >= 32) {
+ fpu_vlm(20, 21, src);
+ if (copy) {
+ fpu_vstm(20, 21, dst);
+ dst += 32;
+ }
+ fpu_vcksm(16, 20, 16);
+ fpu_vcksm(17, 21, 17);
+ src += 32;
+ len -= 32;
+ }
+ while (len >= 16) {
+ fpu_vl(20, src);
+ if (copy) {
+ fpu_vst(20, dst);
+ dst += 16;
+ }
+ fpu_vcksm(16, 20, 16);
+ src += 16;
+ len -= 16;
+ }
+ if (len) {
+ fpu_vll(20, len - 1, src);
+ if (copy)
+ fpu_vstl(20, len - 1, dst);
+ fpu_vcksm(16, 20, 16);
+ }
+ fpu_vcksm(18, 19, 18);
+ fpu_vcksm(16, 17, 16);
+ fpu_vcksm(16, 18, 16);
+ sum = (__force __wsum)fpu_vlgvf(16, 1);
+ kernel_fpu_end(&vxstate, KERNEL_VXR_V16V23);
+ return sum;
+}
+
+__wsum csum_partial(const void *buff, int len, __wsum sum)
+{
+ return csum_copy(NULL, buff, len, sum, false);
+}
+EXPORT_SYMBOL(csum_partial);
+
+__wsum csum_partial_copy_nocheck(const void *src, void *dst, int len)
+{
+ return csum_copy(dst, src, len, 0, true);
+}
+EXPORT_SYMBOL(csum_partial_copy_nocheck);
diff --git a/arch/s390/mm/Makefile b/arch/s390/mm/Makefile
index 352ff520fd94..f6c2db7a8669 100644
--- a/arch/s390/mm/Makefile
+++ b/arch/s390/mm/Makefile
@@ -7,6 +7,7 @@ obj-y := init.o fault.o extmem.o mmap.o vmem.o maccess.o
obj-y += page-states.o pageattr.o pgtable.o pgalloc.o extable.o
obj-$(CONFIG_CMM) += cmm.o
+obj-$(CONFIG_DEBUG_VIRTUAL) += physaddr.o
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
obj-$(CONFIG_PTDUMP_CORE) += dump_pagetables.o
obj-$(CONFIG_PGSTE) += gmap.o
diff --git a/arch/s390/mm/dump_pagetables.c b/arch/s390/mm/dump_pagetables.c
index d37a8f607b71..ffd07ed7b4af 100644
--- a/arch/s390/mm/dump_pagetables.c
+++ b/arch/s390/mm/dump_pagetables.c
@@ -6,7 +6,6 @@
#include <linux/mm.h>
#include <linux/kfence.h>
#include <linux/kasan.h>
-#include <asm/ptdump.h>
#include <asm/kasan.h>
#include <asm/abs_lowcore.h>
#include <asm/nospec-branch.h>
@@ -122,7 +121,6 @@ static void print_prot(struct seq_file *m, unsigned int pr, int level)
static void note_prot_wx(struct pg_state *st, unsigned long addr)
{
-#ifdef CONFIG_DEBUG_WX
if (!st->check_wx)
return;
if (st->current_prot & _PAGE_INVALID)
@@ -139,10 +137,10 @@ static void note_prot_wx(struct pg_state *st, unsigned long addr)
*/
if (addr == PAGE_SIZE && (nospec_uses_trampoline() || !static_key_enabled(&cpu_has_bear)))
return;
- WARN_ONCE(1, "s390/mm: Found insecure W+X mapping at address %pS\n",
+ WARN_ONCE(IS_ENABLED(CONFIG_DEBUG_WX),
+ "s390/mm: Found insecure W+X mapping at address %pS\n",
(void *)st->start_address);
st->wx_pages += (addr - st->start_address) / PAGE_SIZE;
-#endif /* CONFIG_DEBUG_WX */
}
static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level, u64 val)
@@ -194,8 +192,7 @@ static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
}
}
-#ifdef CONFIG_DEBUG_WX
-void ptdump_check_wx(void)
+bool ptdump_check_wx(void)
{
struct pg_state st = {
.ptdump = {
@@ -218,16 +215,20 @@ void ptdump_check_wx(void)
};
if (!MACHINE_HAS_NX)
- return;
+ return true;
ptdump_walk_pgd(&st.ptdump, &init_mm, NULL);
- if (st.wx_pages)
+ if (st.wx_pages) {
pr_warn("Checked W+X mappings: FAILED, %lu W+X pages found\n", st.wx_pages);
- else
+
+ return false;
+ } else {
pr_info("Checked W+X mappings: passed, no %sW+X pages found\n",
(nospec_uses_trampoline() || !static_key_enabled(&cpu_has_bear)) ?
"unexpected " : "");
+
+ return true;
+ }
}
-#endif /* CONFIG_DEBUG_WX */
#ifdef CONFIG_PTDUMP_DEBUGFS
static int ptdump_show(struct seq_file *m, void *v)
diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c
index e41869f5cc95..282fefe107a2 100644
--- a/arch/s390/mm/extmem.c
+++ b/arch/s390/mm/extmem.c
@@ -136,7 +136,7 @@ dcss_diag(int *func, void *parameter,
unsigned long rx, ry;
int rc;
- rx = (unsigned long) parameter;
+ rx = virt_to_phys(parameter);
ry = (unsigned long) *func;
diag_stat_inc(DIAG_STAT_X064);
@@ -178,7 +178,7 @@ query_segment_type (struct dcss_segment *seg)
/* initialize diag input parameters */
qin->qopcode = DCSS_FINDSEGA;
- qin->qoutptr = (unsigned long) qout;
+ qin->qoutptr = virt_to_phys(qout);
qin->qoutlen = sizeof(struct qout64);
memcpy (qin->qname, seg->dcss_name, 8);
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index ac4c78546d97..0c66b32e0f9f 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -67,13 +67,15 @@ early_initcall(fault_init);
static enum fault_type get_fault_type(struct pt_regs *regs)
{
union teid teid = { .val = regs->int_parm_long };
+ struct gmap *gmap;
if (likely(teid.as == PSW_BITS_AS_PRIMARY)) {
if (user_mode(regs))
return USER_FAULT;
if (!IS_ENABLED(CONFIG_PGSTE))
return KERNEL_FAULT;
- if (test_pt_regs_flag(regs, PIF_GUEST_FAULT))
+ gmap = (struct gmap *)S390_lowcore.gmap;
+ if (gmap && gmap->asce == regs->cr1)
return GMAP_FAULT;
return KERNEL_FAULT;
}
diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c
index 8da39deb56ca..094b43b121cd 100644
--- a/arch/s390/mm/gmap.c
+++ b/arch/s390/mm/gmap.c
@@ -206,9 +206,11 @@ static void gmap_free(struct gmap *gmap)
/* Free additional data for a shadow gmap */
if (gmap_is_shadow(gmap)) {
+ struct ptdesc *ptdesc, *n;
+
/* Free all page tables. */
- list_for_each_entry_safe(page, next, &gmap->pt_list, lru)
- page_table_free_pgste(page);
+ list_for_each_entry_safe(ptdesc, n, &gmap->pt_list, pt_list)
+ page_table_free_pgste(ptdesc);
gmap_rmap_radix_tree_free(&gmap->host_to_rmap);
/* Release reference to the parent */
gmap_put(gmap->parent);
@@ -596,12 +598,12 @@ int __gmap_link(struct gmap *gmap, unsigned long gaddr, unsigned long vmaddr)
pud = pud_offset(p4d, vmaddr);
VM_BUG_ON(pud_none(*pud));
/* large puds cannot yet be handled */
- if (pud_large(*pud))
+ if (pud_leaf(*pud))
return -EFAULT;
pmd = pmd_offset(pud, vmaddr);
VM_BUG_ON(pmd_none(*pmd));
/* Are we allowed to use huge pages? */
- if (pmd_large(*pmd) && !gmap->mm->context.allow_gmap_hpage_1m)
+ if (pmd_leaf(*pmd) && !gmap->mm->context.allow_gmap_hpage_1m)
return -EFAULT;
/* Link gmap segment table entry location to page table. */
rc = radix_tree_preload(GFP_KERNEL_ACCOUNT);
@@ -613,7 +615,7 @@ int __gmap_link(struct gmap *gmap, unsigned long gaddr, unsigned long vmaddr)
rc = radix_tree_insert(&gmap->host_to_guest,
vmaddr >> PMD_SHIFT, table);
if (!rc) {
- if (pmd_large(*pmd)) {
+ if (pmd_leaf(*pmd)) {
*table = (pmd_val(*pmd) &
_SEGMENT_ENTRY_HARDWARE_BITS_LARGE)
| _SEGMENT_ENTRY_GMAP_UC;
@@ -943,7 +945,7 @@ static inline pmd_t *gmap_pmd_op_walk(struct gmap *gmap, unsigned long gaddr)
}
/* 4k page table entries are locked via the pte (pte_alloc_map_lock). */
- if (!pmd_large(*pmdp))
+ if (!pmd_leaf(*pmdp))
spin_unlock(&gmap->guest_table_lock);
return pmdp;
}
@@ -955,7 +957,7 @@ static inline pmd_t *gmap_pmd_op_walk(struct gmap *gmap, unsigned long gaddr)
*/
static inline void gmap_pmd_op_end(struct gmap *gmap, pmd_t *pmdp)
{
- if (pmd_large(*pmdp))
+ if (pmd_leaf(*pmdp))
spin_unlock(&gmap->guest_table_lock);
}
@@ -1066,7 +1068,7 @@ static int gmap_protect_range(struct gmap *gmap, unsigned long gaddr,
rc = -EAGAIN;
pmdp = gmap_pmd_op_walk(gmap, gaddr);
if (pmdp) {
- if (!pmd_large(*pmdp)) {
+ if (!pmd_leaf(*pmdp)) {
rc = gmap_protect_pte(gmap, gaddr, pmdp, prot,
bits);
if (!rc) {
@@ -1348,7 +1350,7 @@ static void gmap_unshadow_pgt(struct gmap *sg, unsigned long raddr)
{
unsigned long *ste;
phys_addr_t sto, pgt;
- struct page *page;
+ struct ptdesc *ptdesc;
BUG_ON(!gmap_is_shadow(sg));
ste = gmap_table_walk(sg, raddr, 1); /* get segment pointer */
@@ -1361,9 +1363,9 @@ static void gmap_unshadow_pgt(struct gmap *sg, unsigned long raddr)
*ste = _SEGMENT_ENTRY_EMPTY;
__gmap_unshadow_pgt(sg, raddr, __va(pgt));
/* Free page table */
- page = phys_to_page(pgt);
- list_del(&page->lru);
- page_table_free_pgste(page);
+ ptdesc = page_ptdesc(phys_to_page(pgt));
+ list_del(&ptdesc->pt_list);
+ page_table_free_pgste(ptdesc);
}
/**
@@ -1377,7 +1379,7 @@ static void gmap_unshadow_pgt(struct gmap *sg, unsigned long raddr)
static void __gmap_unshadow_sgt(struct gmap *sg, unsigned long raddr,
unsigned long *sgt)
{
- struct page *page;
+ struct ptdesc *ptdesc;
phys_addr_t pgt;
int i;
@@ -1389,9 +1391,9 @@ static void __gmap_unshadow_sgt(struct gmap *sg, unsigned long raddr,
sgt[i] = _SEGMENT_ENTRY_EMPTY;
__gmap_unshadow_pgt(sg, raddr, __va(pgt));
/* Free page table */
- page = phys_to_page(pgt);
- list_del(&page->lru);
- page_table_free_pgste(page);
+ ptdesc = page_ptdesc(phys_to_page(pgt));
+ list_del(&ptdesc->pt_list);
+ page_table_free_pgste(ptdesc);
}
}
@@ -2058,19 +2060,19 @@ int gmap_shadow_pgt(struct gmap *sg, unsigned long saddr, unsigned long pgt,
{
unsigned long raddr, origin;
unsigned long *table;
- struct page *page;
+ struct ptdesc *ptdesc;
phys_addr_t s_pgt;
int rc;
BUG_ON(!gmap_is_shadow(sg) || (pgt & _SEGMENT_ENTRY_LARGE));
/* Allocate a shadow page table */
- page = page_table_alloc_pgste(sg->mm);
- if (!page)
+ ptdesc = page_table_alloc_pgste(sg->mm);
+ if (!ptdesc)
return -ENOMEM;
- page->index = pgt & _SEGMENT_ENTRY_ORIGIN;
+ ptdesc->pt_index = pgt & _SEGMENT_ENTRY_ORIGIN;
if (fake)
- page->index |= GMAP_SHADOW_FAKE_TABLE;
- s_pgt = page_to_phys(page);
+ ptdesc->pt_index |= GMAP_SHADOW_FAKE_TABLE;
+ s_pgt = page_to_phys(ptdesc_page(ptdesc));
/* Install shadow page table */
spin_lock(&sg->guest_table_lock);
table = gmap_table_walk(sg, saddr, 1); /* get segment pointer */
@@ -2088,7 +2090,7 @@ int gmap_shadow_pgt(struct gmap *sg, unsigned long saddr, unsigned long pgt,
/* mark as invalid as long as the parent table is not protected */
*table = (unsigned long) s_pgt | _SEGMENT_ENTRY |
(pgt & _SEGMENT_ENTRY_PROTECT) | _SEGMENT_ENTRY_INVALID;
- list_add(&page->lru, &sg->pt_list);
+ list_add(&ptdesc->pt_list, &sg->pt_list);
if (fake) {
/* nothing to protect for fake tables */
*table &= ~_SEGMENT_ENTRY_INVALID;
@@ -2114,7 +2116,7 @@ int gmap_shadow_pgt(struct gmap *sg, unsigned long saddr, unsigned long pgt,
return rc;
out_free:
spin_unlock(&sg->guest_table_lock);
- page_table_free_pgste(page);
+ page_table_free_pgste(ptdesc);
return rc;
}
@@ -2498,7 +2500,7 @@ void gmap_sync_dirty_log_pmd(struct gmap *gmap, unsigned long bitmap[4],
if (!pmdp)
return;
- if (pmd_large(*pmdp)) {
+ if (pmd_leaf(*pmdp)) {
if (gmap_test_and_clear_dirty_pmd(gmap, pmdp, gaddr))
bitmap_fill(bitmap, _PAGE_ENTRIES);
} else {
diff --git a/arch/s390/mm/hugetlbpage.c b/arch/s390/mm/hugetlbpage.c
index 297a6d897d5a..c2e8242bd15d 100644
--- a/arch/s390/mm/hugetlbpage.c
+++ b/arch/s390/mm/hugetlbpage.c
@@ -224,7 +224,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm,
if (p4d_present(*p4dp)) {
pudp = pud_offset(p4dp, addr);
if (pud_present(*pudp)) {
- if (pud_large(*pudp))
+ if (pud_leaf(*pudp))
return (pte_t *) pudp;
pmdp = pmd_offset(pudp, addr);
}
@@ -235,12 +235,12 @@ pte_t *huge_pte_offset(struct mm_struct *mm,
int pmd_huge(pmd_t pmd)
{
- return pmd_large(pmd);
+ return pmd_leaf(pmd);
}
int pud_huge(pud_t pud)
{
- return pud_large(pud);
+ return pud_leaf(pud);
}
bool __init arch_hugetlb_valid_size(unsigned long size)
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index 43e612bc2bcd..f6391442c0c2 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -37,7 +37,6 @@
#include <asm/pgalloc.h>
#include <asm/ctlreg.h>
#include <asm/kfence.h>
-#include <asm/ptdump.h>
#include <asm/dma.h>
#include <asm/abs_lowcore.h>
#include <asm/tlb.h>
@@ -109,7 +108,6 @@ void mark_rodata_ro(void)
__set_memory_ro(__start_ro_after_init, __end_ro_after_init);
pr_info("Write protected read-only-after-init data: %luk\n", size >> 10);
- debug_checkwx();
}
int set_memory_encrypted(unsigned long vaddr, int numpages)
@@ -281,9 +279,6 @@ int arch_add_memory(int nid, u64 start, u64 size,
unsigned long size_pages = PFN_DOWN(size);
int rc;
- if (WARN_ON_ONCE(params->altmap))
- return -EINVAL;
-
if (WARN_ON_ONCE(params->pgprot.pgprot != PAGE_KERNEL.pgprot))
return -EINVAL;
diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c
index fc9a7dc26c5e..b14fc0887654 100644
--- a/arch/s390/mm/mmap.c
+++ b/arch/s390/mm/mmap.c
@@ -71,6 +71,15 @@ static inline unsigned long mmap_base(unsigned long rnd,
return PAGE_ALIGN(STACK_TOP - gap - rnd);
}
+static int get_align_mask(struct file *filp, unsigned long flags)
+{
+ if (!(current->flags & PF_RANDOMIZE))
+ return 0;
+ if (filp || (flags & MAP_SHARED))
+ return MMAP_ALIGN_MASK << PAGE_SHIFT;
+ return 0;
+}
+
unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
unsigned long len, unsigned long pgoff,
unsigned long flags)
@@ -97,10 +106,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
info.length = len;
info.low_limit = mm->mmap_base;
info.high_limit = TASK_SIZE;
- if (filp || (flags & MAP_SHARED))
- info.align_mask = MMAP_ALIGN_MASK << PAGE_SHIFT;
- else
- info.align_mask = 0;
+ info.align_mask = get_align_mask(filp, flags);
info.align_offset = pgoff << PAGE_SHIFT;
addr = vm_unmapped_area(&info);
if (offset_in_page(addr))
@@ -138,10 +144,7 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp, unsigned long ad
info.length = len;
info.low_limit = PAGE_SIZE;
info.high_limit = mm->mmap_base;
- if (filp || (flags & MAP_SHARED))
- info.align_mask = MMAP_ALIGN_MASK << PAGE_SHIFT;
- else
- info.align_mask = 0;
+ info.align_mask = get_align_mask(filp, flags);
info.align_offset = pgoff << PAGE_SHIFT;
addr = vm_unmapped_area(&info);
diff --git a/arch/s390/mm/pageattr.c b/arch/s390/mm/pageattr.c
index 631e3a4ee2de..01bc8fad64d6 100644
--- a/arch/s390/mm/pageattr.c
+++ b/arch/s390/mm/pageattr.c
@@ -185,7 +185,7 @@ static int walk_pmd_level(pud_t *pudp, unsigned long addr, unsigned long end,
if (pmd_none(*pmdp))
return -EINVAL;
next = pmd_addr_end(addr, end);
- if (pmd_large(*pmdp)) {
+ if (pmd_leaf(*pmdp)) {
need_split = !!(flags & SET_MEMORY_4K);
need_split |= !!(addr & ~PMD_MASK);
need_split |= !!(addr + PMD_SIZE > next);
@@ -274,7 +274,7 @@ static int walk_pud_level(p4d_t *p4d, unsigned long addr, unsigned long end,
if (pud_none(*pudp))
return -EINVAL;
next = pud_addr_end(addr, end);
- if (pud_large(*pudp)) {
+ if (pud_leaf(*pudp)) {
need_split = !!(flags & SET_MEMORY_4K);
need_split |= !!(addr & ~PUD_MASK);
need_split |= !!(addr + PUD_SIZE > next);
diff --git a/arch/s390/mm/pgalloc.c b/arch/s390/mm/pgalloc.c
index 008e487c94a6..abb629d7e131 100644
--- a/arch/s390/mm/pgalloc.c
+++ b/arch/s390/mm/pgalloc.c
@@ -135,7 +135,7 @@ err_p4d:
#ifdef CONFIG_PGSTE
-struct page *page_table_alloc_pgste(struct mm_struct *mm)
+struct ptdesc *page_table_alloc_pgste(struct mm_struct *mm)
{
struct ptdesc *ptdesc;
u64 *table;
@@ -147,12 +147,12 @@ struct page *page_table_alloc_pgste(struct mm_struct *mm)
memset64(table, _PAGE_INVALID, PTRS_PER_PTE);
memset64(table + PTRS_PER_PTE, 0, PTRS_PER_PTE);
}
- return ptdesc_page(ptdesc);
+ return ptdesc;
}
-void page_table_free_pgste(struct page *page)
+void page_table_free_pgste(struct ptdesc *ptdesc)
{
- pagetable_free(page_ptdesc(page));
+ pagetable_free(ptdesc);
}
#endif /* CONFIG_PGSTE */
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index 99422926efe1..2c944bafb030 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -470,7 +470,7 @@ static int pmd_lookup(struct mm_struct *mm, unsigned long addr, pmd_t **pmdp)
return -ENOENT;
/* Large PUDs are not supported yet. */
- if (pud_large(*pud))
+ if (pud_leaf(*pud))
return -EFAULT;
*pmdp = pmd_offset(pud, addr);
@@ -721,9 +721,9 @@ static void ptep_zap_swap_entry(struct mm_struct *mm, swp_entry_t entry)
if (!non_swap_entry(entry))
dec_mm_counter(mm, MM_SWAPENTS);
else if (is_migration_entry(entry)) {
- struct page *page = pfn_swap_entry_to_page(entry);
+ struct folio *folio = pfn_swap_entry_folio(entry);
- dec_mm_counter(mm, mm_counter(page));
+ dec_mm_counter(mm, mm_counter(folio));
}
free_swap_and_cache(entry);
}
@@ -827,7 +827,7 @@ again:
return key ? -EFAULT : 0;
}
- if (pmd_large(*pmdp)) {
+ if (pmd_leaf(*pmdp)) {
paddr = pmd_val(*pmdp) & HPAGE_MASK;
paddr |= addr & ~HPAGE_MASK;
/*
@@ -938,7 +938,7 @@ again:
return 0;
}
- if (pmd_large(*pmdp)) {
+ if (pmd_leaf(*pmdp)) {
paddr = pmd_val(*pmdp) & HPAGE_MASK;
paddr |= addr & ~HPAGE_MASK;
cc = page_reset_referenced(paddr);
@@ -1002,7 +1002,7 @@ again:
return 0;
}
- if (pmd_large(*pmdp)) {
+ if (pmd_leaf(*pmdp)) {
paddr = pmd_val(*pmdp) & HPAGE_MASK;
paddr |= addr & ~HPAGE_MASK;
*key = page_get_storage_key(paddr);
diff --git a/arch/s390/mm/physaddr.c b/arch/s390/mm/physaddr.c
new file mode 100644
index 000000000000..59de866c72d9
--- /dev/null
+++ b/arch/s390/mm/physaddr.c
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/mmdebug.h>
+#include <linux/export.h>
+#include <linux/mm.h>
+#include <asm/page.h>
+
+unsigned long __phys_addr(unsigned long x, bool is_31bit)
+{
+ VIRTUAL_BUG_ON(is_vmalloc_or_module_addr((void *)(x)));
+ x = __pa_nodebug(x);
+ if (is_31bit)
+ VIRTUAL_BUG_ON(x >> 31);
+ return x;
+}
+EXPORT_SYMBOL(__phys_addr);
diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c
index 186a020857cf..85cddf904cb2 100644
--- a/arch/s390/mm/vmem.c
+++ b/arch/s390/mm/vmem.c
@@ -33,8 +33,12 @@ static void __ref *vmem_alloc_pages(unsigned int order)
return memblock_alloc(size, size);
}
-static void vmem_free_pages(unsigned long addr, int order)
+static void vmem_free_pages(unsigned long addr, int order, struct vmem_altmap *altmap)
{
+ if (altmap) {
+ vmem_altmap_free(altmap, 1 << order);
+ return;
+ }
/* We don't expect boot memory to be removed ever. */
if (!slab_is_available() ||
WARN_ON_ONCE(PageReserved(virt_to_page((void *)addr))))
@@ -156,7 +160,8 @@ static bool vmemmap_unuse_sub_pmd(unsigned long start, unsigned long end)
/* __ref: we'll only call vmemmap_alloc_block() via vmemmap_populate() */
static int __ref modify_pte_table(pmd_t *pmd, unsigned long addr,
- unsigned long end, bool add, bool direct)
+ unsigned long end, bool add, bool direct,
+ struct vmem_altmap *altmap)
{
unsigned long prot, pages = 0;
int ret = -ENOMEM;
@@ -172,11 +177,11 @@ static int __ref modify_pte_table(pmd_t *pmd, unsigned long addr,
if (pte_none(*pte))
continue;
if (!direct)
- vmem_free_pages((unsigned long) pfn_to_virt(pte_pfn(*pte)), 0);
+ vmem_free_pages((unsigned long)pfn_to_virt(pte_pfn(*pte)), get_order(PAGE_SIZE), altmap);
pte_clear(&init_mm, addr, pte);
} else if (pte_none(*pte)) {
if (!direct) {
- void *new_page = vmemmap_alloc_block(PAGE_SIZE, NUMA_NO_NODE);
+ void *new_page = vmemmap_alloc_block_buf(PAGE_SIZE, NUMA_NO_NODE, altmap);
if (!new_page)
goto out;
@@ -213,7 +218,8 @@ static void try_free_pte_table(pmd_t *pmd, unsigned long start)
/* __ref: we'll only call vmemmap_alloc_block() via vmemmap_populate() */
static int __ref modify_pmd_table(pud_t *pud, unsigned long addr,
- unsigned long end, bool add, bool direct)
+ unsigned long end, bool add, bool direct,
+ struct vmem_altmap *altmap)
{
unsigned long next, prot, pages = 0;
int ret = -ENOMEM;
@@ -230,15 +236,15 @@ static int __ref modify_pmd_table(pud_t *pud, unsigned long addr,
if (!add) {
if (pmd_none(*pmd))
continue;
- if (pmd_large(*pmd)) {
+ if (pmd_leaf(*pmd)) {
if (IS_ALIGNED(addr, PMD_SIZE) &&
IS_ALIGNED(next, PMD_SIZE)) {
if (!direct)
- vmem_free_pages(pmd_deref(*pmd), get_order(PMD_SIZE));
+ vmem_free_pages(pmd_deref(*pmd), get_order(PMD_SIZE), altmap);
pmd_clear(pmd);
pages++;
} else if (!direct && vmemmap_unuse_sub_pmd(addr, next)) {
- vmem_free_pages(pmd_deref(*pmd), get_order(PMD_SIZE));
+ vmem_free_pages(pmd_deref(*pmd), get_order(PMD_SIZE), altmap);
pmd_clear(pmd);
}
continue;
@@ -261,7 +267,7 @@ static int __ref modify_pmd_table(pud_t *pud, unsigned long addr,
* page tables since vmemmap_populate gets
* called for each section separately.
*/
- new_page = vmemmap_alloc_block(PMD_SIZE, NUMA_NO_NODE);
+ new_page = vmemmap_alloc_block_buf(PMD_SIZE, NUMA_NO_NODE, altmap);
if (new_page) {
set_pmd(pmd, __pmd(__pa(new_page) | prot));
if (!IS_ALIGNED(addr, PMD_SIZE) ||
@@ -275,12 +281,12 @@ static int __ref modify_pmd_table(pud_t *pud, unsigned long addr,
if (!pte)
goto out;
pmd_populate(&init_mm, pmd, pte);
- } else if (pmd_large(*pmd)) {
+ } else if (pmd_leaf(*pmd)) {
if (!direct)
vmemmap_use_sub_pmd(addr, next);
continue;
}
- ret = modify_pte_table(pmd, addr, next, add, direct);
+ ret = modify_pte_table(pmd, addr, next, add, direct, altmap);
if (ret)
goto out;
if (!add)
@@ -302,12 +308,12 @@ static void try_free_pmd_table(pud_t *pud, unsigned long start)
for (i = 0; i < PTRS_PER_PMD; i++, pmd++)
if (!pmd_none(*pmd))
return;
- vmem_free_pages(pud_deref(*pud), CRST_ALLOC_ORDER);
+ vmem_free_pages(pud_deref(*pud), CRST_ALLOC_ORDER, NULL);
pud_clear(pud);
}
static int modify_pud_table(p4d_t *p4d, unsigned long addr, unsigned long end,
- bool add, bool direct)
+ bool add, bool direct, struct vmem_altmap *altmap)
{
unsigned long next, prot, pages = 0;
int ret = -ENOMEM;
@@ -323,7 +329,7 @@ static int modify_pud_table(p4d_t *p4d, unsigned long addr, unsigned long end,
if (!add) {
if (pud_none(*pud))
continue;
- if (pud_large(*pud)) {
+ if (pud_leaf(*pud)) {
if (IS_ALIGNED(addr, PUD_SIZE) &&
IS_ALIGNED(next, PUD_SIZE)) {
pud_clear(pud);
@@ -344,10 +350,10 @@ static int modify_pud_table(p4d_t *p4d, unsigned long addr, unsigned long end,
if (!pmd)
goto out;
pud_populate(&init_mm, pud, pmd);
- } else if (pud_large(*pud)) {
+ } else if (pud_leaf(*pud)) {
continue;
}
- ret = modify_pmd_table(pud, addr, next, add, direct);
+ ret = modify_pmd_table(pud, addr, next, add, direct, altmap);
if (ret)
goto out;
if (!add)
@@ -370,12 +376,12 @@ static void try_free_pud_table(p4d_t *p4d, unsigned long start)
if (!pud_none(*pud))
return;
}
- vmem_free_pages(p4d_deref(*p4d), CRST_ALLOC_ORDER);
+ vmem_free_pages(p4d_deref(*p4d), CRST_ALLOC_ORDER, NULL);
p4d_clear(p4d);
}
static int modify_p4d_table(pgd_t *pgd, unsigned long addr, unsigned long end,
- bool add, bool direct)
+ bool add, bool direct, struct vmem_altmap *altmap)
{
unsigned long next;
int ret = -ENOMEM;
@@ -394,7 +400,7 @@ static int modify_p4d_table(pgd_t *pgd, unsigned long addr, unsigned long end,
goto out;
p4d_populate(&init_mm, p4d, pud);
}
- ret = modify_pud_table(p4d, addr, next, add, direct);
+ ret = modify_pud_table(p4d, addr, next, add, direct, altmap);
if (ret)
goto out;
if (!add)
@@ -415,12 +421,12 @@ static void try_free_p4d_table(pgd_t *pgd, unsigned long start)
if (!p4d_none(*p4d))
return;
}
- vmem_free_pages(pgd_deref(*pgd), CRST_ALLOC_ORDER);
+ vmem_free_pages(pgd_deref(*pgd), CRST_ALLOC_ORDER, NULL);
pgd_clear(pgd);
}
static int modify_pagetable(unsigned long start, unsigned long end, bool add,
- bool direct)
+ bool direct, struct vmem_altmap *altmap)
{
unsigned long addr, next;
int ret = -ENOMEM;
@@ -445,7 +451,7 @@ static int modify_pagetable(unsigned long start, unsigned long end, bool add,
goto out;
pgd_populate(&init_mm, pgd, p4d);
}
- ret = modify_p4d_table(pgd, addr, next, add, direct);
+ ret = modify_p4d_table(pgd, addr, next, add, direct, altmap);
if (ret)
goto out;
if (!add)
@@ -458,14 +464,16 @@ out:
return ret;
}
-static int add_pagetable(unsigned long start, unsigned long end, bool direct)
+static int add_pagetable(unsigned long start, unsigned long end, bool direct,
+ struct vmem_altmap *altmap)
{
- return modify_pagetable(start, end, true, direct);
+ return modify_pagetable(start, end, true, direct, altmap);
}
-static int remove_pagetable(unsigned long start, unsigned long end, bool direct)
+static int remove_pagetable(unsigned long start, unsigned long end, bool direct,
+ struct vmem_altmap *altmap)
{
- return modify_pagetable(start, end, false, direct);
+ return modify_pagetable(start, end, false, direct, altmap);
}
/*
@@ -474,7 +482,7 @@ static int remove_pagetable(unsigned long start, unsigned long end, bool direct)
static int vmem_add_range(unsigned long start, unsigned long size)
{
start = (unsigned long)__va(start);
- return add_pagetable(start, start + size, true);
+ return add_pagetable(start, start + size, true, NULL);
}
/*
@@ -483,7 +491,7 @@ static int vmem_add_range(unsigned long start, unsigned long size)
static void vmem_remove_range(unsigned long start, unsigned long size)
{
start = (unsigned long)__va(start);
- remove_pagetable(start, start + size, true);
+ remove_pagetable(start, start + size, true, NULL);
}
/*
@@ -496,9 +504,9 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
mutex_lock(&vmem_mutex);
/* We don't care about the node, just use NUMA_NO_NODE on allocations */
- ret = add_pagetable(start, end, false);
+ ret = add_pagetable(start, end, false, altmap);
if (ret)
- remove_pagetable(start, end, false);
+ remove_pagetable(start, end, false, altmap);
mutex_unlock(&vmem_mutex);
return ret;
}
@@ -509,7 +517,7 @@ void vmemmap_free(unsigned long start, unsigned long end,
struct vmem_altmap *altmap)
{
mutex_lock(&vmem_mutex);
- remove_pagetable(start, end, false);
+ remove_pagetable(start, end, false, altmap);
mutex_unlock(&vmem_mutex);
}
@@ -591,7 +599,7 @@ pte_t *vmem_get_alloc_pte(unsigned long addr, bool alloc)
if (!pmd)
goto out;
pud_populate(&init_mm, pud, pmd);
- } else if (WARN_ON_ONCE(pud_large(*pud))) {
+ } else if (WARN_ON_ONCE(pud_leaf(*pud))) {
goto out;
}
pmd = pmd_offset(pud, addr);
@@ -602,7 +610,7 @@ pte_t *vmem_get_alloc_pte(unsigned long addr, bool alloc)
if (!pte)
goto out;
pmd_populate(&init_mm, pmd, pte);
- } else if (WARN_ON_ONCE(pmd_large(*pmd))) {
+ } else if (WARN_ON_ONCE(pmd_leaf(*pmd))) {
goto out;
}
ptep = pte_offset_kernel(pmd, addr);
diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c
index b418333bb086..5af0402e94b8 100644
--- a/arch/s390/net/bpf_jit_comp.c
+++ b/arch/s390/net/bpf_jit_comp.c
@@ -516,11 +516,12 @@ static void bpf_skip(struct bpf_jit *jit, int size)
* PLT for hotpatchable calls. The calling convention is the same as for the
* ftrace hotpatch trampolines: %r0 is return address, %r1 is clobbered.
*/
-extern const char bpf_plt[];
-extern const char bpf_plt_ret[];
-extern const char bpf_plt_target[];
-extern const char bpf_plt_end[];
-#define BPF_PLT_SIZE 32
+struct bpf_plt {
+ char code[16];
+ void *ret;
+ void *target;
+} __packed;
+extern const struct bpf_plt bpf_plt;
asm(
".pushsection .rodata\n"
" .balign 8\n"
@@ -531,15 +532,14 @@ asm(
" .balign 8\n"
"bpf_plt_ret: .quad 0\n"
"bpf_plt_target: .quad 0\n"
- "bpf_plt_end:\n"
" .popsection\n"
);
-static void bpf_jit_plt(void *plt, void *ret, void *target)
+static void bpf_jit_plt(struct bpf_plt *plt, void *ret, void *target)
{
- memcpy(plt, bpf_plt, BPF_PLT_SIZE);
- *(void **)((char *)plt + (bpf_plt_ret - bpf_plt)) = ret;
- *(void **)((char *)plt + (bpf_plt_target - bpf_plt)) = target ?: ret;
+ memcpy(plt, &bpf_plt, sizeof(*plt));
+ plt->ret = ret;
+ plt->target = target;
}
/*
@@ -662,9 +662,9 @@ static void bpf_jit_epilogue(struct bpf_jit *jit, u32 stack_depth)
jit->prg = ALIGN(jit->prg, 8);
jit->prologue_plt = jit->prg;
if (jit->prg_buf)
- bpf_jit_plt(jit->prg_buf + jit->prg,
+ bpf_jit_plt((struct bpf_plt *)(jit->prg_buf + jit->prg),
jit->prg_buf + jit->prologue_plt_ret, NULL);
- jit->prg += BPF_PLT_SIZE;
+ jit->prg += sizeof(struct bpf_plt);
}
static int get_probe_mem_regno(const u8 *insn)
@@ -2040,9 +2040,6 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
struct bpf_jit jit;
int pass;
- if (WARN_ON_ONCE(bpf_plt_end - bpf_plt != BPF_PLT_SIZE))
- return orig_fp;
-
if (!fp->jit_requested)
return orig_fp;
@@ -2148,14 +2145,11 @@ bool bpf_jit_supports_far_kfunc_call(void)
int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t,
void *old_addr, void *new_addr)
{
+ struct bpf_plt expected_plt, current_plt, new_plt, *plt;
struct {
u16 opc;
s32 disp;
} __packed insn;
- char expected_plt[BPF_PLT_SIZE];
- char current_plt[BPF_PLT_SIZE];
- char new_plt[BPF_PLT_SIZE];
- char *plt;
char *ret;
int err;
@@ -2174,18 +2168,18 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t,
*/
} else {
/* Verify the PLT. */
- plt = (char *)ip + (insn.disp << 1);
- err = copy_from_kernel_nofault(current_plt, plt, BPF_PLT_SIZE);
+ plt = ip + (insn.disp << 1);
+ err = copy_from_kernel_nofault(&current_plt, plt,
+ sizeof(current_plt));
if (err < 0)
return err;
ret = (char *)ip + 6;
- bpf_jit_plt(expected_plt, ret, old_addr);
- if (memcmp(current_plt, expected_plt, BPF_PLT_SIZE))
+ bpf_jit_plt(&expected_plt, ret, old_addr);
+ if (memcmp(&current_plt, &expected_plt, sizeof(current_plt)))
return -EINVAL;
/* Adjust the call address. */
- bpf_jit_plt(new_plt, ret, new_addr);
- s390_kernel_write(plt + (bpf_plt_target - bpf_plt),
- new_plt + (bpf_plt_target - bpf_plt),
+ bpf_jit_plt(&new_plt, ret, new_addr);
+ s390_kernel_write(&plt->target, &new_plt.target,
sizeof(void *));
}
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index 52a44e353796..26afde0d1ed3 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -28,6 +28,7 @@
#include <linux/jump_label.h>
#include <linux/pci.h>
#include <linux/printk.h>
+#include <linux/lockdep.h>
#include <asm/isc.h>
#include <asm/airq.h>
@@ -730,12 +731,12 @@ EXPORT_SYMBOL_GPL(zpci_disable_device);
* equivalent to its state during boot when first probing a driver.
* Consequently after reset the PCI function requires re-initialization via the
* common PCI code including re-enabling IRQs via pci_alloc_irq_vectors()
- * and enabling the function via e.g.pci_enablde_device_flags().The caller
+ * and enabling the function via e.g. pci_enable_device_flags(). The caller
* must guard against concurrent reset attempts.
*
* In most cases this function should not be called directly but through
* pci_reset_function() or pci_reset_bus() which handle the save/restore and
- * locking.
+ * locking - asserted by lockdep.
*
* Return: 0 on success and an error value otherwise
*/
@@ -744,6 +745,7 @@ int zpci_hot_reset_device(struct zpci_dev *zdev)
u8 status;
int rc;
+ lockdep_assert_held(&zdev->state_lock);
zpci_dbg(3, "rst fid:%x, fh:%x\n", zdev->fid, zdev->fh);
if (zdev_enabled(zdev)) {
/* Disables device access, DMAs and IRQs (reset state) */
@@ -806,7 +808,8 @@ struct zpci_dev *zpci_create_device(u32 fid, u32 fh, enum zpci_state state)
zdev->state = state;
kref_init(&zdev->kref);
- mutex_init(&zdev->lock);
+ mutex_init(&zdev->state_lock);
+ mutex_init(&zdev->fmb_lock);
mutex_init(&zdev->kzdev_lock);
rc = zpci_init_iommu(zdev);
@@ -870,6 +873,10 @@ int zpci_deconfigure_device(struct zpci_dev *zdev)
{
int rc;
+ lockdep_assert_held(&zdev->state_lock);
+ if (zdev->state != ZPCI_FN_STATE_CONFIGURED)
+ return 0;
+
if (zdev->zbus->bus)
zpci_bus_remove_device(zdev, false);
@@ -889,7 +896,7 @@ int zpci_deconfigure_device(struct zpci_dev *zdev)
}
/**
- * zpci_device_reserved() - Mark device as resverved
+ * zpci_device_reserved() - Mark device as reserved
* @zdev: the zpci_dev that was reserved
*
* Handle the case that a given zPCI function was reserved by another system.
@@ -899,8 +906,6 @@ int zpci_deconfigure_device(struct zpci_dev *zdev)
*/
void zpci_device_reserved(struct zpci_dev *zdev)
{
- if (zdev->has_hp_slot)
- zpci_exit_slot(zdev);
/*
* Remove device from zpci_list as it is going away. This also
* makes sure we ignore subsequent zPCI events for this device.
@@ -918,6 +923,9 @@ void zpci_release_device(struct kref *kref)
struct zpci_dev *zdev = container_of(kref, struct zpci_dev, kref);
int ret;
+ if (zdev->has_hp_slot)
+ zpci_exit_slot(zdev);
+
if (zdev->zbus->bus)
zpci_bus_remove_device(zdev, false);
diff --git a/arch/s390/pci/pci_debug.c b/arch/s390/pci/pci_debug.c
index 6dde2263c79d..2cb5043a997d 100644
--- a/arch/s390/pci/pci_debug.c
+++ b/arch/s390/pci/pci_debug.c
@@ -91,9 +91,9 @@ static int pci_perf_show(struct seq_file *m, void *v)
if (!zdev)
return 0;
- mutex_lock(&zdev->lock);
+ mutex_lock(&zdev->fmb_lock);
if (!zdev->fmb) {
- mutex_unlock(&zdev->lock);
+ mutex_unlock(&zdev->fmb_lock);
seq_puts(m, "FMB statistics disabled\n");
return 0;
}
@@ -130,7 +130,7 @@ static int pci_perf_show(struct seq_file *m, void *v)
}
pci_sw_counter_show(m);
- mutex_unlock(&zdev->lock);
+ mutex_unlock(&zdev->fmb_lock);
return 0;
}
@@ -148,7 +148,7 @@ static ssize_t pci_perf_seq_write(struct file *file, const char __user *ubuf,
if (rc)
return rc;
- mutex_lock(&zdev->lock);
+ mutex_lock(&zdev->fmb_lock);
switch (val) {
case 0:
rc = zpci_fmb_disable_device(zdev);
@@ -157,7 +157,7 @@ static ssize_t pci_perf_seq_write(struct file *file, const char __user *ubuf,
rc = zpci_fmb_enable_device(zdev);
break;
}
- mutex_unlock(&zdev->lock);
+ mutex_unlock(&zdev->fmb_lock);
return rc ? rc : count;
}
diff --git a/arch/s390/pci/pci_event.c b/arch/s390/pci/pci_event.c
index 4d9773ef9e0a..dbe95ec5917e 100644
--- a/arch/s390/pci/pci_event.c
+++ b/arch/s390/pci/pci_event.c
@@ -267,6 +267,7 @@ static void __zpci_event_error(struct zpci_ccdf_err *ccdf)
zpci_err_hex(ccdf, sizeof(*ccdf));
if (zdev) {
+ mutex_lock(&zdev->state_lock);
zpci_update_fh(zdev, ccdf->fh);
if (zdev->zbus->bus)
pdev = pci_get_slot(zdev->zbus->bus, zdev->devfn);
@@ -294,6 +295,8 @@ static void __zpci_event_error(struct zpci_ccdf_err *ccdf)
}
pci_dev_put(pdev);
no_pdev:
+ if (zdev)
+ mutex_unlock(&zdev->state_lock);
zpci_zdev_put(zdev);
}
@@ -326,6 +329,10 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
zpci_dbg(3, "avl fid:%x, fh:%x, pec:%x\n",
ccdf->fid, ccdf->fh, ccdf->pec);
+
+ if (existing_zdev)
+ mutex_lock(&zdev->state_lock);
+
switch (ccdf->pec) {
case 0x0301: /* Reserved|Standby -> Configured */
if (!zdev) {
@@ -348,7 +355,7 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
break;
case 0x0303: /* Deconfiguration requested */
if (zdev) {
- /* The event may have been queued before we confirgured
+ /* The event may have been queued before we configured
* the device.
*/
if (zdev->state != ZPCI_FN_STATE_CONFIGURED)
@@ -359,7 +366,7 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
break;
case 0x0304: /* Configured -> Standby|Reserved */
if (zdev) {
- /* The event may have been queued before we confirgured
+ /* The event may have been queued before we configured
* the device.:
*/
if (zdev->state == ZPCI_FN_STATE_CONFIGURED)
@@ -383,8 +390,10 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
default:
break;
}
- if (existing_zdev)
+ if (existing_zdev) {
+ mutex_unlock(&zdev->state_lock);
zpci_zdev_put(zdev);
+ }
}
void zpci_event_availability(void *data)
diff --git a/arch/s390/pci/pci_sysfs.c b/arch/s390/pci/pci_sysfs.c
index 8a7abac51816..a0b872b74fe3 100644
--- a/arch/s390/pci/pci_sysfs.c
+++ b/arch/s390/pci/pci_sysfs.c
@@ -49,6 +49,39 @@ static ssize_t mio_enabled_show(struct device *dev,
}
static DEVICE_ATTR_RO(mio_enabled);
+static int _do_recover(struct pci_dev *pdev, struct zpci_dev *zdev)
+{
+ u8 status;
+ int ret;
+
+ pci_stop_and_remove_bus_device(pdev);
+ if (zdev_enabled(zdev)) {
+ ret = zpci_disable_device(zdev);
+ /*
+ * Due to a z/VM vs LPAR inconsistency in the error
+ * state the FH may indicate an enabled device but
+ * disable says the device is already disabled don't
+ * treat it as an error here.
+ */
+ if (ret == -EINVAL)
+ ret = 0;
+ if (ret)
+ return ret;
+ }
+
+ ret = zpci_enable_device(zdev);
+ if (ret)
+ return ret;
+
+ if (zdev->dma_table) {
+ ret = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
+ virt_to_phys(zdev->dma_table), &status);
+ if (ret)
+ zpci_disable_device(zdev);
+ }
+ return ret;
+}
+
static ssize_t recover_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
@@ -56,7 +89,6 @@ static ssize_t recover_store(struct device *dev, struct device_attribute *attr,
struct pci_dev *pdev = to_pci_dev(dev);
struct zpci_dev *zdev = to_zpci(pdev);
int ret = 0;
- u8 status;
/* Can't use device_remove_self() here as that would lead us to lock
* the pci_rescan_remove_lock while holding the device' kernfs lock.
@@ -70,6 +102,12 @@ static ssize_t recover_store(struct device *dev, struct device_attribute *attr,
*/
kn = sysfs_break_active_protection(&dev->kobj, &attr->attr);
WARN_ON_ONCE(!kn);
+
+ /* Device needs to be configured and state must not change */
+ mutex_lock(&zdev->state_lock);
+ if (zdev->state != ZPCI_FN_STATE_CONFIGURED)
+ goto out;
+
/* device_remove_file() serializes concurrent calls ignoring all but
* the first
*/
@@ -82,35 +120,13 @@ static ssize_t recover_store(struct device *dev, struct device_attribute *attr,
*/
pci_lock_rescan_remove();
if (pci_dev_is_added(pdev)) {
- pci_stop_and_remove_bus_device(pdev);
- if (zdev_enabled(zdev)) {
- ret = zpci_disable_device(zdev);
- /*
- * Due to a z/VM vs LPAR inconsistency in the error
- * state the FH may indicate an enabled device but
- * disable says the device is already disabled don't
- * treat it as an error here.
- */
- if (ret == -EINVAL)
- ret = 0;
- if (ret)
- goto out;
- }
-
- ret = zpci_enable_device(zdev);
- if (ret)
- goto out;
-
- if (zdev->dma_table) {
- ret = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
- virt_to_phys(zdev->dma_table), &status);
- if (ret)
- zpci_disable_device(zdev);
- }
+ ret = _do_recover(pdev, zdev);
}
-out:
pci_rescan_bus(zdev->zbus->bus);
pci_unlock_rescan_remove();
+
+out:
+ mutex_unlock(&zdev->state_lock);
if (kn)
sysfs_unbreak_active_protection(kn);
return ret ? ret : count;
diff --git a/arch/s390/tools/.gitignore b/arch/s390/tools/.gitignore
index ea62f37b79ef..e6af51d9d183 100644
--- a/arch/s390/tools/.gitignore
+++ b/arch/s390/tools/.gitignore
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
gen_facilities
gen_opcode_table
+relocs
diff --git a/arch/s390/tools/Makefile b/arch/s390/tools/Makefile
index f9dd47ff9ac4..f2862364fb42 100644
--- a/arch/s390/tools/Makefile
+++ b/arch/s390/tools/Makefile
@@ -25,3 +25,8 @@ $(kapi)/facility-defs.h: $(obj)/gen_facilities FORCE
$(kapi)/dis-defs.h: $(obj)/gen_opcode_table FORCE
$(call filechk,dis-defs.h)
+
+hostprogs += relocs
+PHONY += relocs
+relocs: $(obj)/relocs
+ @:
diff --git a/arch/s390/tools/relocs.c b/arch/s390/tools/relocs.c
new file mode 100644
index 000000000000..30a732c808f3
--- /dev/null
+++ b/arch/s390/tools/relocs.c
@@ -0,0 +1,387 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <elf.h>
+#include <byteswap.h>
+#define USE_BSD
+#include <endian.h>
+
+#define ELF_BITS 64
+
+#define ELF_MACHINE EM_S390
+#define ELF_MACHINE_NAME "IBM S/390"
+#define SHT_REL_TYPE SHT_RELA
+#define Elf_Rel Elf64_Rela
+
+#define ELF_CLASS ELFCLASS64
+#define ELF_ENDIAN ELFDATA2MSB
+#define ELF_R_SYM(val) ELF64_R_SYM(val)
+#define ELF_R_TYPE(val) ELF64_R_TYPE(val)
+#define ELF_ST_TYPE(o) ELF64_ST_TYPE(o)
+#define ELF_ST_BIND(o) ELF64_ST_BIND(o)
+#define ELF_ST_VISIBILITY(o) ELF64_ST_VISIBILITY(o)
+
+#define ElfW(type) _ElfW(ELF_BITS, type)
+#define _ElfW(bits, type) __ElfW(bits, type)
+#define __ElfW(bits, type) Elf##bits##_##type
+
+#define Elf_Addr ElfW(Addr)
+#define Elf_Ehdr ElfW(Ehdr)
+#define Elf_Phdr ElfW(Phdr)
+#define Elf_Shdr ElfW(Shdr)
+#define Elf_Sym ElfW(Sym)
+
+static Elf_Ehdr ehdr;
+static unsigned long shnum;
+static unsigned int shstrndx;
+
+struct relocs {
+ uint32_t *offset;
+ unsigned long count;
+ unsigned long size;
+};
+
+static struct relocs relocs64;
+#define FMT PRIu64
+
+struct section {
+ Elf_Shdr shdr;
+ struct section *link;
+ Elf_Rel *reltab;
+};
+
+static struct section *secs;
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define le16_to_cpu(val) (val)
+#define le32_to_cpu(val) (val)
+#define le64_to_cpu(val) (val)
+#define be16_to_cpu(val) bswap_16(val)
+#define be32_to_cpu(val) bswap_32(val)
+#define be64_to_cpu(val) bswap_64(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 be16_to_cpu(val) (val)
+#define be32_to_cpu(val) (val)
+#define be64_to_cpu(val) (val)
+#endif
+
+static uint16_t elf16_to_cpu(uint16_t val)
+{
+ if (ehdr.e_ident[EI_DATA] == ELFDATA2LSB)
+ return le16_to_cpu(val);
+ else
+ return be16_to_cpu(val);
+}
+
+static uint32_t elf32_to_cpu(uint32_t val)
+{
+ if (ehdr.e_ident[EI_DATA] == ELFDATA2LSB)
+ return le32_to_cpu(val);
+ else
+ return be32_to_cpu(val);
+}
+
+#define elf_half_to_cpu(x) elf16_to_cpu(x)
+#define elf_word_to_cpu(x) elf32_to_cpu(x)
+
+static uint64_t elf64_to_cpu(uint64_t val)
+{
+ return be64_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)
+
+static void die(char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ exit(1);
+}
+
+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)
+ die("No ELF magic\n");
+ if (ehdr.e_ident[EI_CLASS] != ELF_CLASS)
+ die("Not a %d bit executable\n", ELF_BITS);
+ if (ehdr.e_ident[EI_DATA] != ELF_ENDIAN)
+ die("ELF endian mismatch\n");
+ 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);
+ ehdr.e_version = elf_word_to_cpu(ehdr.e_version);
+ ehdr.e_entry = elf_addr_to_cpu(ehdr.e_entry);
+ ehdr.e_phoff = elf_off_to_cpu(ehdr.e_phoff);
+ ehdr.e_shoff = elf_off_to_cpu(ehdr.e_shoff);
+ ehdr.e_flags = elf_word_to_cpu(ehdr.e_flags);
+ ehdr.e_ehsize = elf_half_to_cpu(ehdr.e_ehsize);
+ ehdr.e_phentsize = elf_half_to_cpu(ehdr.e_phentsize);
+ ehdr.e_phnum = elf_half_to_cpu(ehdr.e_phnum);
+ ehdr.e_shentsize = elf_half_to_cpu(ehdr.e_shentsize);
+ ehdr.e_shnum = elf_half_to_cpu(ehdr.e_shnum);
+ ehdr.e_shstrndx = elf_half_to_cpu(ehdr.e_shstrndx);
+
+ shnum = ehdr.e_shnum;
+ shstrndx = ehdr.e_shstrndx;
+
+ if ((ehdr.e_type != ET_EXEC) && (ehdr.e_type != ET_DYN))
+ die("Unsupported ELF header type\n");
+ if (ehdr.e_machine != ELF_MACHINE)
+ die("Not for %s\n", ELF_MACHINE_NAME);
+ if (ehdr.e_version != EV_CURRENT)
+ die("Unknown ELF version\n");
+ if (ehdr.e_ehsize != sizeof(Elf_Ehdr))
+ die("Bad Elf header size\n");
+ if (ehdr.e_phentsize != sizeof(Elf_Phdr))
+ die("Bad program header entry\n");
+ if (ehdr.e_shentsize != sizeof(Elf_Shdr))
+ die("Bad section header entry\n");
+
+ if (shnum == SHN_UNDEF || shstrndx == SHN_XINDEX) {
+ Elf_Shdr shdr;
+
+ if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0)
+ die("Seek to %" FMT " failed: %s\n", ehdr.e_shoff, strerror(errno));
+
+ if (fread(&shdr, sizeof(shdr), 1, fp) != 1)
+ die("Cannot read initial ELF section header: %s\n", strerror(errno));
+
+ if (shnum == SHN_UNDEF)
+ shnum = elf_xword_to_cpu(shdr.sh_size);
+
+ if (shstrndx == SHN_XINDEX)
+ shstrndx = elf_word_to_cpu(shdr.sh_link);
+ }
+
+ if (shstrndx >= shnum)
+ die("String table index out of bounds\n");
+}
+
+static void read_shdrs(FILE *fp)
+{
+ Elf_Shdr shdr;
+ int i;
+
+ 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));
+
+ 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));
+ }
+
+ 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);
+ sec->shdr.sh_addr = elf_addr_to_cpu(shdr.sh_addr);
+ sec->shdr.sh_offset = elf_off_to_cpu(shdr.sh_offset);
+ sec->shdr.sh_size = elf_xword_to_cpu(shdr.sh_size);
+ sec->shdr.sh_link = elf_word_to_cpu(shdr.sh_link);
+ sec->shdr.sh_info = elf_word_to_cpu(shdr.sh_info);
+ sec->shdr.sh_addralign = elf_xword_to_cpu(shdr.sh_addralign);
+ sec->shdr.sh_entsize = elf_xword_to_cpu(shdr.sh_entsize);
+
+ if (sec->shdr.sh_link < shnum)
+ sec->link = &secs[sec->shdr.sh_link];
+ }
+
+}
+
+static void read_relocs(FILE *fp)
+{
+ int i, j;
+
+ for (i = 0; i < shnum; i++) {
+ struct section *sec = &secs[i];
+
+ 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));
+
+ 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)
+ rel->r_addend = elf_xword_to_cpu(rel->r_addend);
+#endif
+ }
+ }
+}
+
+static void add_reloc(struct relocs *r, uint32_t offset)
+{
+ if (r->count == r->size) {
+ unsigned long newsize = r->size + 50000;
+ void *mem = realloc(r->offset, newsize * sizeof(r->offset[0]));
+
+ if (!mem)
+ die("realloc of %ld entries for relocs failed\n", newsize);
+
+ r->offset = mem;
+ r->size = newsize;
+ }
+ r->offset[r->count++] = offset;
+}
+
+static int do_reloc(struct section *sec, Elf_Rel *rel)
+{
+ unsigned int r_type = ELF64_R_TYPE(rel->r_info);
+ ElfW(Addr) offset = rel->r_offset;
+
+ switch (r_type) {
+ case R_390_NONE:
+ case R_390_PC32:
+ case R_390_PC64:
+ case R_390_PC16DBL:
+ case R_390_PC32DBL:
+ case R_390_PLT32DBL:
+ case R_390_GOTENT:
+ case R_390_GOTPCDBL:
+ case R_390_GOTOFF64:
+ break;
+ case R_390_64:
+ add_reloc(&relocs64, offset);
+ break;
+ default:
+ die("Unsupported relocation type: %d\n", r_type);
+ break;
+ }
+
+ return 0;
+}
+
+static void walk_relocs(void)
+{
+ int i;
+
+ /* Walk through the relocations */
+ for (i = 0; i < shnum; i++) {
+ struct section *sec_applies;
+ int j;
+ struct section *sec = &secs[i];
+
+ if (sec->shdr.sh_type != SHT_REL_TYPE)
+ continue;
+
+ sec_applies = &secs[sec->shdr.sh_info];
+ if (!(sec_applies->shdr.sh_flags & SHF_ALLOC))
+ continue;
+
+ for (j = 0; j < sec->shdr.sh_size / sizeof(Elf_Rel); j++) {
+ Elf_Rel *rel = &sec->reltab[j];
+
+ do_reloc(sec, rel);
+ }
+ }
+}
+
+static int cmp_relocs(const void *va, const void *vb)
+{
+ const uint32_t *a, *b;
+
+ a = va; b = vb;
+ return (*a == *b) ? 0 : (*a > *b) ? 1 : -1;
+}
+
+static void sort_relocs(struct relocs *r)
+{
+ qsort(r->offset, r->count, sizeof(r->offset[0]), cmp_relocs);
+}
+
+static int print_reloc(uint32_t v)
+{
+ return fprintf(stdout, "\t.long 0x%08"PRIx32"\n", v) > 0 ? 0 : -1;
+}
+
+static void emit_relocs(void)
+{
+ int i;
+
+ walk_relocs();
+ sort_relocs(&relocs64);
+
+ printf(".section \".vmlinux.relocs_64\",\"a\"\n");
+ for (i = 0; i < relocs64.count; i++)
+ print_reloc(relocs64.offset[i]);
+}
+
+static void process(FILE *fp)
+{
+ read_ehdr(fp);
+ read_shdrs(fp);
+ read_relocs(fp);
+ emit_relocs();
+}
+
+static void usage(void)
+{
+ die("relocs vmlinux\n");
+}
+
+int main(int argc, char **argv)
+{
+ unsigned char e_ident[EI_NIDENT];
+ const char *fname;
+ FILE *fp;
+
+ fname = NULL;
+
+ if (argc != 2)
+ usage();
+
+ fname = argv[1];
+
+ fp = fopen(fname, "r");
+ if (!fp)
+ die("Cannot open %s: %s\n", fname, strerror(errno));
+
+ if (fread(&e_ident, 1, EI_NIDENT, fp) != EI_NIDENT)
+ die("Cannot read %s: %s", fname, strerror(errno));
+
+ rewind(fp);
+
+ process(fp);
+
+ fclose(fp);
+ return 0;
+}
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 7500521b2b98..2ad3e29f0ebe 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -2,6 +2,7 @@
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)
diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile
index b5e29f99c02c..6c6c791a1d06 100644
--- a/arch/sh/boot/compressed/Makefile
+++ b/arch/sh/boot/compressed/Makefile
@@ -12,6 +12,7 @@ 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/cchips/hd6446x/hd64461.c b/arch/sh/cchips/hd6446x/hd64461.c
index f3fba967445a..81764882d87d 100644
--- a/arch/sh/cchips/hd6446x/hd64461.c
+++ b/arch/sh/cchips/hd6446x/hd64461.c
@@ -72,7 +72,7 @@ static void hd64461_irq_demux(struct irq_desc *desc)
}
}
-int __init setup_hd64461(void)
+static int __init setup_hd64461(void)
{
int irq_base, i;
diff --git a/arch/sh/drivers/dma/dma-sysfs.c b/arch/sh/drivers/dma/dma-sysfs.c
index 431bc18f0a41..9f666280d80c 100644
--- a/arch/sh/drivers/dma/dma-sysfs.c
+++ b/arch/sh/drivers/dma/dma-sysfs.c
@@ -15,7 +15,7 @@
#include <linux/string.h>
#include <asm/dma.h>
-static struct bus_type dma_subsys = {
+static const struct bus_type dma_subsys = {
.name = "dma",
.dev_name = "dma",
};
diff --git a/arch/sh/include/asm/cachetype.h b/arch/sh/include/asm/cachetype.h
new file mode 100644
index 000000000000..a5fffe536068
--- /dev/null
+++ b/arch/sh/include/asm/cachetype.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_SH_CACHETYPE_H
+#define __ASM_SH_CACHETYPE_H
+
+#include <linux/types.h>
+
+#define cpu_dcache_is_aliasing() true
+
+#endif
diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h
index 62f4b9edcb98..f780b467e75d 100644
--- a/arch/sh/include/asm/page.h
+++ b/arch/sh/include/asm/page.h
@@ -9,18 +9,7 @@
#include <linux/const.h>
/* PAGE_SHIFT determines the page size */
-#if defined(CONFIG_PAGE_SIZE_4KB)
-# define PAGE_SHIFT 12
-#elif defined(CONFIG_PAGE_SIZE_8KB)
-# define PAGE_SHIFT 13
-#elif defined(CONFIG_PAGE_SIZE_16KB)
-# define PAGE_SHIFT 14
-#elif defined(CONFIG_PAGE_SIZE_64KB)
-# define PAGE_SHIFT 16
-#else
-# error "Bogus kernel page size?"
-#endif
-
+#define PAGE_SHIFT CONFIG_PAGE_SHIFT
#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
#define PTE_MASK PAGE_MASK
diff --git a/arch/sh/include/asm/word-at-a-time.h b/arch/sh/include/asm/word-at-a-time.h
index 4aa398455b94..95100ce128d6 100644
--- a/arch/sh/include/asm/word-at-a-time.h
+++ b/arch/sh/include/asm/word-at-a-time.h
@@ -5,6 +5,8 @@
#ifdef CONFIG_CPU_BIG_ENDIAN
# include <asm-generic/word-at-a-time.h>
#else
+#include <linux/bitops.h>
+#include <linux/wordpart.h>
/*
* Little-endian version cribbed from x86.
*/
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index 2d7e70537de0..ba917008d63e 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o
obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_MODULES) += sh_ksyms_32.o module.o
obj-$(CONFIG_KEXEC_CORE) += machine_kexec.o relocate_kernel.o
+obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-$(CONFIG_IO_TRAPPED) += io_trapped.o
diff --git a/arch/sh/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c
index fa3a7b36190a..8321b31d2e19 100644
--- a/arch/sh/kernel/machine_kexec.c
+++ b/arch/sh/kernel/machine_kexec.c
@@ -137,22 +137,14 @@ void machine_kexec(struct kimage *image)
__ftrace_enabled_restore(save_ftrace_enabled);
}
-void arch_crash_save_vmcoreinfo(void)
-{
-#ifdef CONFIG_NUMA
- VMCOREINFO_SYMBOL(node_data);
- VMCOREINFO_LENGTH(node_data, MAX_NUMNODES);
-#endif
-#ifdef CONFIG_X2TLB
- VMCOREINFO_CONFIG(X2TLB);
-#endif
-}
-
void __init reserve_crashkernel(void)
{
unsigned long long crash_size, crash_base;
int ret;
+ if (!IS_ENABLED(CONFIG_CRASH_RESERVE))
+ return;
+
ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
&crash_size, &crash_base, NULL, NULL);
if (ret == 0 && crash_size > 0) {
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index d3175f09b3aa..620e5cf8ae1e 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -220,7 +220,7 @@ void __init __add_active_range(unsigned int nid, unsigned long start_pfn,
request_resource(res, &code_resource);
request_resource(res, &data_resource);
request_resource(res, &bss_resource);
-#ifdef CONFIG_KEXEC_CORE
+#ifdef CONFIG_CRASH_RESERVE
request_resource(res, &crashk_res);
#endif
diff --git a/arch/sh/kernel/vmcore_info.c b/arch/sh/kernel/vmcore_info.c
new file mode 100644
index 000000000000..a244a204a1b1
--- /dev/null
+++ b/arch/sh/kernel/vmcore_info.c
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/vmcore_info.h>
+#include <linux/mm.h>
+
+void arch_crash_save_vmcoreinfo(void)
+{
+#ifdef CONFIG_NUMA
+ VMCOREINFO_SYMBOL(node_data);
+ VMCOREINFO_LENGTH(node_data, MAX_NUMNODES);
+#endif
+#ifdef CONFIG_X2TLB
+ VMCOREINFO_CONFIG(X2TLB);
+#endif
+}
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig
index 455311d9a5e9..f32a1963ff0c 100644
--- a/arch/sh/mm/Kconfig
+++ b/arch/sh/mm/Kconfig
@@ -4,6 +4,9 @@ menu "Memory management options"
config MMU
bool "Support for memory management hardware"
depends on !CPU_SH2
+ select HAVE_PAGE_SIZE_4KB
+ select HAVE_PAGE_SIZE_8KB if X2TLB
+ select HAVE_PAGE_SIZE_64KB if CPU_SH4
default y
help
Some SH processors (such as SH-2/SH-2A) lack an MMU. In order to
@@ -13,6 +16,15 @@ config MMU
turning this off will boot the kernel on these machines with the
MMU implicitly switched off.
+config NOMMU
+ def_bool !MMU
+ select HAVE_PAGE_SIZE_4KB
+ select HAVE_PAGE_SIZE_8KB
+ select HAVE_PAGE_SIZE_16KB
+ select HAVE_PAGE_SIZE_64KB
+ help
+ On MMU-less systems, any of these page sizes can be selected
+
config PAGE_OFFSET
hex
default "0x80000000" if MMU
@@ -148,36 +160,6 @@ config HAVE_SRAM_POOL
select GENERIC_ALLOCATOR
choice
- prompt "Kernel page size"
- default PAGE_SIZE_4KB
-
-config PAGE_SIZE_4KB
- bool "4kB"
- help
- This is the default page size used by all SuperH CPUs.
-
-config PAGE_SIZE_8KB
- bool "8kB"
- depends on !MMU || X2TLB
- help
- This enables 8kB pages as supported by SH-X2 and later MMUs.
-
-config PAGE_SIZE_16KB
- bool "16kB"
- depends on !MMU
- help
- This enables 16kB pages on MMU-less SH systems.
-
-config PAGE_SIZE_64KB
- bool "64kB"
- depends on !MMU || CPU_SH4
- help
- This enables support for 64kB pages, possible on all SH-4
- CPUs and later.
-
-endchoice
-
-choice
prompt "HugeTLB page size"
depends on HUGETLB_PAGE
default HUGETLB_PAGE_SIZE_1MB if PAGE_SIZE_64KB
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 204c43cb3d43..11bf9d312318 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -13,6 +13,7 @@ config 64BIT
config SPARC
bool
default y
+ select ARCH_HAS_CPU_CACHE_ALIASING
select ARCH_MIGHT_HAVE_PC_PARPORT if SPARC64 && PCI
select ARCH_MIGHT_HAVE_PC_SERIO
select DMA_OPS
@@ -57,7 +58,10 @@ config SPARC32
select CLZ_TAB
select DMA_DIRECT_REMAP
select GENERIC_ATOMIC64
+ select GENERIC_LIB_CMPDI2
+ select GENERIC_LIB_UCMPDI2
select HAVE_UID16
+ select HAVE_PAGE_SIZE_4KB
select LOCK_MM_AND_FIND_VMA
select OLD_SIGACTION
select ZONE_DMA
@@ -75,6 +79,7 @@ config SPARC64
select HAVE_ARCH_TRANSPARENT_HUGEPAGE
select HAVE_DYNAMIC_FTRACE
select HAVE_FTRACE_MCOUNT_RECORD
+ select HAVE_PAGE_SIZE_8KB
select HAVE_SYSCALL_TRACEPOINTS
select HAVE_CONTEXT_TRACKING_USER
select HAVE_TIF_NOHZ
@@ -112,10 +117,6 @@ config ARCH_PROC_KCORE_TEXT
config CPU_BIG_ENDIAN
def_bool y
-config ARCH_ATU
- bool
- default y if SPARC64
-
config STACKTRACE_SUPPORT
bool
default y if SPARC64
@@ -140,10 +141,6 @@ config HIGHMEM
default y if SPARC32
select KMAP_LOCAL
-config GENERIC_ISA_DMA
- bool
- default y if SPARC32
-
config PGTABLE_LEVELS
default 4 if 64BIT
default 3
@@ -219,6 +216,8 @@ config EARLYFB
bool "Support for early boot text console"
default y
depends on SPARC64
+ select FONT_SUN8x16
+ select FONT_SUPPORT
help
Say Y here to enable a faster early framebuffer boot console.
diff --git a/arch/sparc/Kconfig.debug b/arch/sparc/Kconfig.debug
index 37e003665de6..d475a056a2e0 100644
--- a/arch/sparc/Kconfig.debug
+++ b/arch/sparc/Kconfig.debug
@@ -8,11 +8,8 @@ config MCOUNT
bool
depends on SPARC64
depends on FUNCTION_TRACER
- default y
-
-config FRAME_POINTER
- bool
- depends on MCOUNT
+ select ARCH_WANT_FRAME_POINTERS
+ select FRAME_POINTER
default y
config HAVE_HARDLOCKUP_DETECTOR_SPARC64
diff --git a/arch/sparc/include/asm/cachetype.h b/arch/sparc/include/asm/cachetype.h
new file mode 100644
index 000000000000..caf1c0045892
--- /dev/null
+++ b/arch/sparc/include/asm/cachetype.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_SPARC_CACHETYPE_H
+#define __ASM_SPARC_CACHETYPE_H
+
+#include <asm/page.h>
+
+#ifdef CONFIG_SPARC32
+extern int vac_cache_size;
+#define cpu_dcache_is_aliasing() (vac_cache_size > PAGE_SIZE)
+#else
+#define cpu_dcache_is_aliasing() (L1DCACHE_SIZE > PAGE_SIZE)
+#endif
+
+#endif
diff --git a/arch/sparc/include/asm/hypervisor.h b/arch/sparc/include/asm/hypervisor.h
index 08650d503cc2..f220edcf17c7 100644
--- a/arch/sparc/include/asm/hypervisor.h
+++ b/arch/sparc/include/asm/hypervisor.h
@@ -430,7 +430,7 @@ unsigned long sun4v_cpu_mondo_send(unsigned long cpu_count,
* ERRORS: No errors defined.
*
* Return the hypervisor ID handle for the current CPU. Use by a
- * virtual CPU to discover it's own identity.
+ * virtual CPU to discover its own identity.
*/
#define HV_FAST_CPU_MYID 0x16
@@ -1221,7 +1221,7 @@ unsigned long sun4v_con_write(unsigned long buffer,
* EBADALIGNED software state description is not correctly
* aligned
*
- * This allows the guest to report it's soft state to the hypervisor. There
+ * This allows the guest to report its soft state to the hypervisor. There
* are two primary components to this state. The first part states whether
* the guest software is running or not. The second containts optional
* details specific to the software.
@@ -1502,7 +1502,7 @@ struct hv_trap_trace_entry {
* configuration error of some sort.
*
* The dump services provide an opaque buffer into which the
- * hypervisor can place it's internal state in order to assist in
+ * hypervisor can place its internal state in order to assist in
* debugging such situations. The contents are opaque and extremely
* platform and hypervisor implementation specific. The guest, during
* a core dump, requests that the hypervisor update any information in
diff --git a/arch/sparc/include/asm/ldc.h b/arch/sparc/include/asm/ldc.h
index ca973955ca86..4294738d40be 100644
--- a/arch/sparc/include/asm/ldc.h
+++ b/arch/sparc/include/asm/ldc.h
@@ -13,7 +13,7 @@ void ldom_power_off(void);
* or data becomes available on the receive side.
*
* For non-RAW links, if the LDC_EVENT_RESET event arrives the
- * driver should reset all of it's internal state and reinvoke
+ * driver should reset all of its internal state and reinvoke
* ldc_connect() to try and bring the link up again.
*
* For RAW links, ldc_connect() is not used. Instead the driver
diff --git a/arch/sparc/include/asm/mmu_context_64.h b/arch/sparc/include/asm/mmu_context_64.h
index 799e797c5cdd..08160bf9a0f4 100644
--- a/arch/sparc/include/asm/mmu_context_64.h
+++ b/arch/sparc/include/asm/mmu_context_64.h
@@ -93,7 +93,7 @@ static inline void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, str
/* We have to be extremely careful here or else we will miss
* a TSB grow if we switch back and forth between a kernel
- * thread and an address space which has it's TSB size increased
+ * thread and an address space which has its TSB size increased
* on another processor.
*
* It is possible to play some games in order to optimize the
@@ -118,7 +118,7 @@ static inline void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, str
*
* At that point cpu0 continues to use a stale TSB, the one from
* before the TSB grow performed on cpu1. cpu1 did not cross-call
- * cpu0 to update it's TSB because at that point the cpu_vm_mask
+ * cpu0 to update its TSB because at that point the cpu_vm_mask
* only had cpu1 set in it.
*/
tsb_context_switch_ctx(mm, CTX_HWBITS(mm->context));
diff --git a/arch/sparc/include/asm/page_32.h b/arch/sparc/include/asm/page_32.h
index 6be6f683f98f..9977c77374cd 100644
--- a/arch/sparc/include/asm/page_32.h
+++ b/arch/sparc/include/asm/page_32.h
@@ -11,7 +11,7 @@
#include <linux/const.h>
-#define PAGE_SHIFT 12
+#define PAGE_SHIFT CONFIG_PAGE_SHIFT
#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
diff --git a/arch/sparc/include/asm/page_64.h b/arch/sparc/include/asm/page_64.h
index 254dffd85fb1..e9bd24821c93 100644
--- a/arch/sparc/include/asm/page_64.h
+++ b/arch/sparc/include/asm/page_64.h
@@ -4,8 +4,7 @@
#include <linux/const.h>
-#define PAGE_SHIFT 13
-
+#define PAGE_SHIFT CONFIG_PAGE_SHIFT
#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
diff --git a/arch/sparc/include/asm/parport.h b/arch/sparc/include/asm/parport.h
index 0a7ffcfd59cd..e2eed8f97665 100644
--- a/arch/sparc/include/asm/parport.h
+++ b/arch/sparc/include/asm/parport.h
@@ -1,256 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/* parport.h: sparc64 specific parport initialization and dma.
- *
- * Copyright (C) 1999 Eddie C. Dost (ecd@skynet.be)
- */
+#ifndef ___ASM_SPARC_PARPORT_H
+#define ___ASM_SPARC_PARPORT_H
-#ifndef _ASM_SPARC64_PARPORT_H
-#define _ASM_SPARC64_PARPORT_H 1
-
-#include <linux/of.h>
-#include <linux/platform_device.h>
-
-#include <asm/ebus_dma.h>
-#include <asm/ns87303.h>
-#include <asm/prom.h>
-
-#define PARPORT_PC_MAX_PORTS PARPORT_MAX
-
-/*
- * While sparc64 doesn't have an ISA DMA API, we provide something that looks
- * close enough to make parport_pc happy
- */
-#define HAS_DMA
-
-#ifdef CONFIG_PARPORT_PC_FIFO
-static DEFINE_SPINLOCK(dma_spin_lock);
-
-#define claim_dma_lock() \
-({ unsigned long flags; \
- spin_lock_irqsave(&dma_spin_lock, flags); \
- flags; \
-})
-
-#define release_dma_lock(__flags) \
- spin_unlock_irqrestore(&dma_spin_lock, __flags);
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm/parport_64.h>
+#else
+#include <asm-generic/parport.h>
+#endif
#endif
-static struct sparc_ebus_info {
- struct ebus_dma_info info;
- unsigned int addr;
- unsigned int count;
- int lock;
-
- struct parport *port;
-} sparc_ebus_dmas[PARPORT_PC_MAX_PORTS];
-
-static DECLARE_BITMAP(dma_slot_map, PARPORT_PC_MAX_PORTS);
-
-static inline int request_dma(unsigned int dmanr, const char *device_id)
-{
- if (dmanr >= PARPORT_PC_MAX_PORTS)
- return -EINVAL;
- if (xchg(&sparc_ebus_dmas[dmanr].lock, 1) != 0)
- return -EBUSY;
- return 0;
-}
-
-static inline void free_dma(unsigned int dmanr)
-{
- if (dmanr >= PARPORT_PC_MAX_PORTS) {
- printk(KERN_WARNING "Trying to free DMA%d\n", dmanr);
- return;
- }
- if (xchg(&sparc_ebus_dmas[dmanr].lock, 0) == 0) {
- printk(KERN_WARNING "Trying to free free DMA%d\n", dmanr);
- return;
- }
-}
-
-static inline void enable_dma(unsigned int dmanr)
-{
- ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 1);
-
- if (ebus_dma_request(&sparc_ebus_dmas[dmanr].info,
- sparc_ebus_dmas[dmanr].addr,
- sparc_ebus_dmas[dmanr].count))
- BUG();
-}
-
-static inline void disable_dma(unsigned int dmanr)
-{
- ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 0);
-}
-
-static inline void clear_dma_ff(unsigned int dmanr)
-{
- /* nothing */
-}
-
-static inline void set_dma_mode(unsigned int dmanr, char mode)
-{
- ebus_dma_prepare(&sparc_ebus_dmas[dmanr].info, (mode != DMA_MODE_WRITE));
-}
-
-static inline void set_dma_addr(unsigned int dmanr, unsigned int addr)
-{
- sparc_ebus_dmas[dmanr].addr = addr;
-}
-
-static inline void set_dma_count(unsigned int dmanr, unsigned int count)
-{
- sparc_ebus_dmas[dmanr].count = count;
-}
-
-static inline unsigned int get_dma_residue(unsigned int dmanr)
-{
- return ebus_dma_residue(&sparc_ebus_dmas[dmanr].info);
-}
-
-static int ecpp_probe(struct platform_device *op)
-{
- unsigned long base = op->resource[0].start;
- unsigned long config = op->resource[1].start;
- unsigned long d_base = op->resource[2].start;
- unsigned long d_len;
- struct device_node *parent;
- struct parport *p;
- int slot, err;
-
- parent = op->dev.of_node->parent;
- if (of_node_name_eq(parent, "dma")) {
- p = parport_pc_probe_port(base, base + 0x400,
- op->archdata.irqs[0], PARPORT_DMA_NOFIFO,
- op->dev.parent->parent, 0);
- if (!p)
- return -ENOMEM;
- dev_set_drvdata(&op->dev, p);
- return 0;
- }
-
- for (slot = 0; slot < PARPORT_PC_MAX_PORTS; slot++) {
- if (!test_and_set_bit(slot, dma_slot_map))
- break;
- }
- err = -ENODEV;
- if (slot >= PARPORT_PC_MAX_PORTS)
- goto out_err;
-
- spin_lock_init(&sparc_ebus_dmas[slot].info.lock);
-
- d_len = (op->resource[2].end - d_base) + 1UL;
- sparc_ebus_dmas[slot].info.regs =
- of_ioremap(&op->resource[2], 0, d_len, "ECPP DMA");
-
- if (!sparc_ebus_dmas[slot].info.regs)
- goto out_clear_map;
-
- sparc_ebus_dmas[slot].info.flags = 0;
- sparc_ebus_dmas[slot].info.callback = NULL;
- sparc_ebus_dmas[slot].info.client_cookie = NULL;
- sparc_ebus_dmas[slot].info.irq = 0xdeadbeef;
- strcpy(sparc_ebus_dmas[slot].info.name, "parport");
- if (ebus_dma_register(&sparc_ebus_dmas[slot].info))
- goto out_unmap_regs;
-
- ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 1);
-
- /* Configure IRQ to Push Pull, Level Low */
- /* Enable ECP, set bit 2 of the CTR first */
- outb(0x04, base + 0x02);
- ns87303_modify(config, PCR,
- PCR_EPP_ENABLE |
- PCR_IRQ_ODRAIN,
- PCR_ECP_ENABLE |
- PCR_ECP_CLK_ENA |
- PCR_IRQ_POLAR);
-
- /* CTR bit 5 controls direction of port */
- ns87303_modify(config, PTR,
- 0, PTR_LPT_REG_DIR);
-
- p = parport_pc_probe_port(base, base + 0x400,
- op->archdata.irqs[0],
- slot,
- op->dev.parent,
- 0);
- err = -ENOMEM;
- if (!p)
- goto out_disable_irq;
-
- dev_set_drvdata(&op->dev, p);
-
- return 0;
-
-out_disable_irq:
- ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 0);
- ebus_dma_unregister(&sparc_ebus_dmas[slot].info);
-
-out_unmap_regs:
- of_iounmap(&op->resource[2], sparc_ebus_dmas[slot].info.regs, d_len);
-
-out_clear_map:
- clear_bit(slot, dma_slot_map);
-
-out_err:
- return err;
-}
-
-static int ecpp_remove(struct platform_device *op)
-{
- struct parport *p = dev_get_drvdata(&op->dev);
- int slot = p->dma;
-
- parport_pc_unregister_port(p);
-
- if (slot != PARPORT_DMA_NOFIFO) {
- unsigned long d_base = op->resource[2].start;
- unsigned long d_len;
-
- d_len = (op->resource[2].end - d_base) + 1UL;
-
- ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 0);
- ebus_dma_unregister(&sparc_ebus_dmas[slot].info);
- of_iounmap(&op->resource[2],
- sparc_ebus_dmas[slot].info.regs,
- d_len);
- clear_bit(slot, dma_slot_map);
- }
-
- return 0;
-}
-
-static const struct of_device_id ecpp_match[] = {
- {
- .name = "ecpp",
- },
- {
- .name = "parallel",
- .compatible = "ecpp",
- },
- {
- .name = "parallel",
- .compatible = "ns87317-ecpp",
- },
- {
- .name = "parallel",
- .compatible = "pnpALI,1533,3",
- },
- {},
-};
-
-static struct platform_driver ecpp_driver = {
- .driver = {
- .name = "ecpp",
- .of_match_table = ecpp_match,
- },
- .probe = ecpp_probe,
- .remove = ecpp_remove,
-};
-
-static int parport_pc_find_nonpci_ports(int autoirq, int autodma)
-{
- return platform_driver_register(&ecpp_driver);
-}
-
-#endif /* !(_ASM_SPARC64_PARPORT_H */
diff --git a/arch/sparc/include/asm/parport_64.h b/arch/sparc/include/asm/parport_64.h
new file mode 100644
index 000000000000..0a7ffcfd59cd
--- /dev/null
+++ b/arch/sparc/include/asm/parport_64.h
@@ -0,0 +1,256 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* parport.h: sparc64 specific parport initialization and dma.
+ *
+ * Copyright (C) 1999 Eddie C. Dost (ecd@skynet.be)
+ */
+
+#ifndef _ASM_SPARC64_PARPORT_H
+#define _ASM_SPARC64_PARPORT_H 1
+
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include <asm/ebus_dma.h>
+#include <asm/ns87303.h>
+#include <asm/prom.h>
+
+#define PARPORT_PC_MAX_PORTS PARPORT_MAX
+
+/*
+ * While sparc64 doesn't have an ISA DMA API, we provide something that looks
+ * close enough to make parport_pc happy
+ */
+#define HAS_DMA
+
+#ifdef CONFIG_PARPORT_PC_FIFO
+static DEFINE_SPINLOCK(dma_spin_lock);
+
+#define claim_dma_lock() \
+({ unsigned long flags; \
+ spin_lock_irqsave(&dma_spin_lock, flags); \
+ flags; \
+})
+
+#define release_dma_lock(__flags) \
+ spin_unlock_irqrestore(&dma_spin_lock, __flags);
+#endif
+
+static struct sparc_ebus_info {
+ struct ebus_dma_info info;
+ unsigned int addr;
+ unsigned int count;
+ int lock;
+
+ struct parport *port;
+} sparc_ebus_dmas[PARPORT_PC_MAX_PORTS];
+
+static DECLARE_BITMAP(dma_slot_map, PARPORT_PC_MAX_PORTS);
+
+static inline int request_dma(unsigned int dmanr, const char *device_id)
+{
+ if (dmanr >= PARPORT_PC_MAX_PORTS)
+ return -EINVAL;
+ if (xchg(&sparc_ebus_dmas[dmanr].lock, 1) != 0)
+ return -EBUSY;
+ return 0;
+}
+
+static inline void free_dma(unsigned int dmanr)
+{
+ if (dmanr >= PARPORT_PC_MAX_PORTS) {
+ printk(KERN_WARNING "Trying to free DMA%d\n", dmanr);
+ return;
+ }
+ if (xchg(&sparc_ebus_dmas[dmanr].lock, 0) == 0) {
+ printk(KERN_WARNING "Trying to free free DMA%d\n", dmanr);
+ return;
+ }
+}
+
+static inline void enable_dma(unsigned int dmanr)
+{
+ ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 1);
+
+ if (ebus_dma_request(&sparc_ebus_dmas[dmanr].info,
+ sparc_ebus_dmas[dmanr].addr,
+ sparc_ebus_dmas[dmanr].count))
+ BUG();
+}
+
+static inline void disable_dma(unsigned int dmanr)
+{
+ ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 0);
+}
+
+static inline void clear_dma_ff(unsigned int dmanr)
+{
+ /* nothing */
+}
+
+static inline void set_dma_mode(unsigned int dmanr, char mode)
+{
+ ebus_dma_prepare(&sparc_ebus_dmas[dmanr].info, (mode != DMA_MODE_WRITE));
+}
+
+static inline void set_dma_addr(unsigned int dmanr, unsigned int addr)
+{
+ sparc_ebus_dmas[dmanr].addr = addr;
+}
+
+static inline void set_dma_count(unsigned int dmanr, unsigned int count)
+{
+ sparc_ebus_dmas[dmanr].count = count;
+}
+
+static inline unsigned int get_dma_residue(unsigned int dmanr)
+{
+ return ebus_dma_residue(&sparc_ebus_dmas[dmanr].info);
+}
+
+static int ecpp_probe(struct platform_device *op)
+{
+ unsigned long base = op->resource[0].start;
+ unsigned long config = op->resource[1].start;
+ unsigned long d_base = op->resource[2].start;
+ unsigned long d_len;
+ struct device_node *parent;
+ struct parport *p;
+ int slot, err;
+
+ parent = op->dev.of_node->parent;
+ if (of_node_name_eq(parent, "dma")) {
+ p = parport_pc_probe_port(base, base + 0x400,
+ op->archdata.irqs[0], PARPORT_DMA_NOFIFO,
+ op->dev.parent->parent, 0);
+ if (!p)
+ return -ENOMEM;
+ dev_set_drvdata(&op->dev, p);
+ return 0;
+ }
+
+ for (slot = 0; slot < PARPORT_PC_MAX_PORTS; slot++) {
+ if (!test_and_set_bit(slot, dma_slot_map))
+ break;
+ }
+ err = -ENODEV;
+ if (slot >= PARPORT_PC_MAX_PORTS)
+ goto out_err;
+
+ spin_lock_init(&sparc_ebus_dmas[slot].info.lock);
+
+ d_len = (op->resource[2].end - d_base) + 1UL;
+ sparc_ebus_dmas[slot].info.regs =
+ of_ioremap(&op->resource[2], 0, d_len, "ECPP DMA");
+
+ if (!sparc_ebus_dmas[slot].info.regs)
+ goto out_clear_map;
+
+ sparc_ebus_dmas[slot].info.flags = 0;
+ sparc_ebus_dmas[slot].info.callback = NULL;
+ sparc_ebus_dmas[slot].info.client_cookie = NULL;
+ sparc_ebus_dmas[slot].info.irq = 0xdeadbeef;
+ strcpy(sparc_ebus_dmas[slot].info.name, "parport");
+ if (ebus_dma_register(&sparc_ebus_dmas[slot].info))
+ goto out_unmap_regs;
+
+ ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 1);
+
+ /* Configure IRQ to Push Pull, Level Low */
+ /* Enable ECP, set bit 2 of the CTR first */
+ outb(0x04, base + 0x02);
+ ns87303_modify(config, PCR,
+ PCR_EPP_ENABLE |
+ PCR_IRQ_ODRAIN,
+ PCR_ECP_ENABLE |
+ PCR_ECP_CLK_ENA |
+ PCR_IRQ_POLAR);
+
+ /* CTR bit 5 controls direction of port */
+ ns87303_modify(config, PTR,
+ 0, PTR_LPT_REG_DIR);
+
+ p = parport_pc_probe_port(base, base + 0x400,
+ op->archdata.irqs[0],
+ slot,
+ op->dev.parent,
+ 0);
+ err = -ENOMEM;
+ if (!p)
+ goto out_disable_irq;
+
+ dev_set_drvdata(&op->dev, p);
+
+ return 0;
+
+out_disable_irq:
+ ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 0);
+ ebus_dma_unregister(&sparc_ebus_dmas[slot].info);
+
+out_unmap_regs:
+ of_iounmap(&op->resource[2], sparc_ebus_dmas[slot].info.regs, d_len);
+
+out_clear_map:
+ clear_bit(slot, dma_slot_map);
+
+out_err:
+ return err;
+}
+
+static int ecpp_remove(struct platform_device *op)
+{
+ struct parport *p = dev_get_drvdata(&op->dev);
+ int slot = p->dma;
+
+ parport_pc_unregister_port(p);
+
+ if (slot != PARPORT_DMA_NOFIFO) {
+ unsigned long d_base = op->resource[2].start;
+ unsigned long d_len;
+
+ d_len = (op->resource[2].end - d_base) + 1UL;
+
+ ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 0);
+ ebus_dma_unregister(&sparc_ebus_dmas[slot].info);
+ of_iounmap(&op->resource[2],
+ sparc_ebus_dmas[slot].info.regs,
+ d_len);
+ clear_bit(slot, dma_slot_map);
+ }
+
+ return 0;
+}
+
+static const struct of_device_id ecpp_match[] = {
+ {
+ .name = "ecpp",
+ },
+ {
+ .name = "parallel",
+ .compatible = "ecpp",
+ },
+ {
+ .name = "parallel",
+ .compatible = "ns87317-ecpp",
+ },
+ {
+ .name = "parallel",
+ .compatible = "pnpALI,1533,3",
+ },
+ {},
+};
+
+static struct platform_driver ecpp_driver = {
+ .driver = {
+ .name = "ecpp",
+ .of_match_table = ecpp_match,
+ },
+ .probe = ecpp_probe,
+ .remove = ecpp_remove,
+};
+
+static int parport_pc_find_nonpci_ports(int autoirq, int autodma)
+{
+ return platform_driver_register(&ecpp_driver);
+}
+
+#endif /* !(_ASM_SPARC64_PARPORT_H */
diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h
index a8c871b7d786..4d1bafaba942 100644
--- a/arch/sparc/include/asm/pgtable_64.h
+++ b/arch/sparc/include/asm/pgtable_64.h
@@ -680,8 +680,8 @@ static inline unsigned long pte_special(pte_t pte)
return pte_val(pte) & _PAGE_SPECIAL;
}
-#define pmd_leaf pmd_large
-static inline unsigned long pmd_large(pmd_t pmd)
+#define pmd_leaf pmd_leaf
+static inline bool pmd_leaf(pmd_t pmd)
{
pte_t pte = __pte(pmd_val(pmd));
@@ -867,8 +867,8 @@ static inline pmd_t *pud_pgtable(pud_t pud)
/* only used by the stubbed out hugetlb gup code, should never be called */
#define p4d_page(p4d) NULL
-#define pud_leaf pud_large
-static inline unsigned long pud_large(pud_t pud)
+#define pud_leaf pud_leaf
+static inline bool pud_leaf(pud_t pud)
{
pte_t pte = __pte(pud_val(pud));
@@ -929,6 +929,8 @@ static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
maybe_tlb_batch_add(mm, addr, ptep, orig, fullmm, PAGE_SHIFT);
}
+#define PFN_PTE_SHIFT PAGE_SHIFT
+
static inline void set_ptes(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte, unsigned int nr)
{
diff --git a/arch/sparc/include/asm/switch_to_64.h b/arch/sparc/include/asm/switch_to_64.h
index 14f3c49bfdbc..d93963ff7caa 100644
--- a/arch/sparc/include/asm/switch_to_64.h
+++ b/arch/sparc/include/asm/switch_to_64.h
@@ -15,7 +15,7 @@ do { \
* for l0/l1. It will use one for 'next' and the other to hold
* the output value of 'last'. 'next' is not referenced again
* past the invocation of switch_to in the scheduler, so we need
- * not preserve it's value. Hairy, but it lets us remove 2 loads
+ * not preserve its value. Hairy, but it lets us remove 2 loads
* and 2 stores in this critical code path. -DaveM
*/
#define switch_to(prev, next, last) \
diff --git a/arch/sparc/kernel/btext.c b/arch/sparc/kernel/btext.c
index e2d3f0d2971f..2bf558a0c568 100644
--- a/arch/sparc/kernel/btext.c
+++ b/arch/sparc/kernel/btext.c
@@ -8,6 +8,7 @@
#include <linux/string.h>
#include <linux/init.h>
#include <linux/console.h>
+#include <linux/font.h>
#include <asm/btext.h>
#include <asm/oplib.h>
@@ -20,9 +21,9 @@ static void scrollscreen(void);
#endif
static void draw_byte(unsigned char c, long locX, long locY);
-static void draw_byte_32(unsigned char *bits, unsigned int *base, int rb);
-static void draw_byte_16(unsigned char *bits, unsigned int *base, int rb);
-static void draw_byte_8(unsigned char *bits, unsigned int *base, int rb);
+static void draw_byte_32(const unsigned char *bits, unsigned int *base, int rb);
+static void draw_byte_16(const unsigned char *bits, unsigned int *base, int rb);
+static void draw_byte_8(const unsigned char *bits, unsigned int *base, int rb);
#define __force_data __section(".data")
@@ -36,10 +37,6 @@ static int dispDeviceDepth __force_data;
static int dispDeviceRect[4] __force_data;
static unsigned char *dispDeviceBase __force_data;
-#define cmapsz (16*256)
-
-static unsigned char vga_font[cmapsz];
-
static int __init btext_initialize(phandle node)
{
unsigned int width, height, depth, pitch;
@@ -194,7 +191,8 @@ static void btext_drawtext(const char *c, unsigned int len)
static void draw_byte(unsigned char c, long locX, long locY)
{
unsigned char *base = calc_base(locX << 3, locY << 4);
- unsigned char *font = &vga_font[((unsigned int)c) * 16];
+ unsigned int font_index = c * 16;
+ const unsigned char *font = font_sun_8x16.data + font_index;
int rb = dispDeviceRowBytes;
switch(dispDeviceDepth) {
@@ -239,7 +237,7 @@ static unsigned int expand_bits_16[4] = {
};
-static void draw_byte_32(unsigned char *font, unsigned int *base, int rb)
+static void draw_byte_32(const unsigned char *font, unsigned int *base, int rb)
{
int l, bits;
int fg = 0xFFFFFFFFUL;
@@ -260,7 +258,7 @@ static void draw_byte_32(unsigned char *font, unsigned int *base, int rb)
}
}
-static void draw_byte_16(unsigned char *font, unsigned int *base, int rb)
+static void draw_byte_16(const unsigned char *font, unsigned int *base, int rb)
{
int l, bits;
int fg = 0xFFFFFFFFUL;
@@ -278,7 +276,7 @@ static void draw_byte_16(unsigned char *font, unsigned int *base, int rb)
}
}
-static void draw_byte_8(unsigned char *font, unsigned int *base, int rb)
+static void draw_byte_8(const unsigned char *font, unsigned int *base, int rb)
{
int l, bits;
int fg = 0x0F0F0F0FUL;
@@ -326,348 +324,3 @@ int __init btext_find_display(void)
}
return ret;
}
-
-static unsigned char vga_font[cmapsz] = {
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd,
-0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff,
-0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe,
-0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
-0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
-0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
-0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00,
-0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd,
-0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e,
-0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30,
-0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63,
-0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8,
-0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e,
-0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
-0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb,
-0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6,
-0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
-0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0,
-0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c,
-0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c,
-0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
-0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c,
-0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18,
-0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c,
-0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30,
-0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18,
-0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e,
-0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18,
-0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
-0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe,
-0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
-0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18,
-0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
-0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
-0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
-0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
-0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde,
-0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38,
-0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0,
-0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c,
-0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68,
-0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
-0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18,
-0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c,
-0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60,
-0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xe7,
-0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
-0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66,
-0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c,
-0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c,
-0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
-0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
-0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3,
-0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18,
-0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3,
-0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30,
-0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
-0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c,
-0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
-0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c,
-0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60,
-0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc,
-0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc,
-0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60,
-0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06,
-0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60,
-0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb,
-0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66,
-0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60,
-0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30,
-0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3,
-0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6,
-0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18,
-0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18,
-0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6,
-0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
-0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00,
-0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe,
-0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c,
-0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c,
-0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38,
-0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06,
-0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe,
-0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00,
-0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18,
-0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66,
-0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
-0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6,
-0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00,
-0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
-0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b,
-0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c,
-0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6,
-0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18,
-0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc,
-0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00,
-0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,
-0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
-0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
-0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e,
-0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18,
-0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66,
-0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18,
-0xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c,
-0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30,
-0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc,
-0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc,
-0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
-0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c,
-0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
-0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06,
-0x0c, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30,
-0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
-0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36,
-0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44,
-0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
-0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
-0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
-0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18,
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18,
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8,
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
-0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36,
-0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8,
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
-0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6,
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
-0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
-0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
-0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37,
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
-0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36,
-0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36,
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
-0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
-0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18,
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
-0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0,
-0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
-0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0,
-0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8,
-0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66,
-0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
-0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66,
-0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60,
-0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
-0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18,
-0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
-0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x1b, 0x18, 0x18,
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00,
-0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c,
-0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c,
-0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00,
-};
diff --git a/arch/sparc/kernel/chmc.c b/arch/sparc/kernel/chmc.c
index d5fad5fb04c1..00e571c30bb5 100644
--- a/arch/sparc/kernel/chmc.c
+++ b/arch/sparc/kernel/chmc.c
@@ -30,7 +30,7 @@
#define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "0.2"
-MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
+MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
MODULE_DESCRIPTION("UltraSPARC-III memory controller driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_MODULE_VERSION);
diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c
index 4a5bdb0df779..ffdc15588ac2 100644
--- a/arch/sparc/kernel/ds.c
+++ b/arch/sparc/kernel/ds.c
@@ -33,7 +33,7 @@
static char version[] =
DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
-MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
+MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
MODULE_DESCRIPTION("Sun LDOM domain services driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_MODULE_VERSION);
diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c
index e8452be5123b..8605dd710f3c 100644
--- a/arch/sparc/kernel/irq_32.c
+++ b/arch/sparc/kernel/irq_32.c
@@ -268,11 +268,11 @@ int sparc_floppy_request_irq(unsigned int irq, irq_handler_t irq_handler)
if (sparc_cpu_model != sparc_leon) {
struct tt_entry *trap_table;
- trap_table = &trapbase_cpu1;
+ trap_table = &trapbase_cpu1[0];
INSTANTIATE(trap_table)
- trap_table = &trapbase_cpu2;
+ trap_table = &trapbase_cpu2[0];
INSTANTIATE(trap_table)
- trap_table = &trapbase_cpu3;
+ trap_table = &trapbase_cpu3[0];
INSTANTIATE(trap_table)
}
#endif
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c
index 72da2e10e255..5280e325d4d6 100644
--- a/arch/sparc/kernel/irq_64.c
+++ b/arch/sparc/kernel/irq_64.c
@@ -980,7 +980,7 @@ void notrace init_irqwork_curcpu(void)
*
* On SMP this gets invoked from the CPU trampoline before
* the cpu has fully taken over the trap table from OBP,
- * and it's kernel stack + %g6 thread register state is
+ * and its kernel stack + %g6 thread register state is
* not fully cooked yet.
*
* Therefore you cannot make any OBP calls, not even prom_printf,
diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h
index 15da3c0597a5..a8fb7c0bf053 100644
--- a/arch/sparc/kernel/kernel.h
+++ b/arch/sparc/kernel/kernel.h
@@ -138,10 +138,10 @@ extern unsigned int t_nmi[];
extern unsigned int linux_trap_ipi15_sun4d[];
extern unsigned int linux_trap_ipi15_sun4m[];
-extern struct tt_entry trapbase;
-extern struct tt_entry trapbase_cpu1;
-extern struct tt_entry trapbase_cpu2;
-extern struct tt_entry trapbase_cpu3;
+extern struct tt_entry trapbase[];
+extern struct tt_entry trapbase_cpu1[];
+extern struct tt_entry trapbase_cpu2[];
+extern struct tt_entry trapbase_cpu3[];
extern char cputypval[];
diff --git a/arch/sparc/kernel/kgdb_32.c b/arch/sparc/kernel/kgdb_32.c
index 58ad3f7de1fb..3b2c673ec627 100644
--- a/arch/sparc/kernel/kgdb_32.c
+++ b/arch/sparc/kernel/kgdb_32.c
@@ -37,7 +37,7 @@ void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
gdb_regs[GDB_Y] = regs->y;
gdb_regs[GDB_PSR] = regs->psr;
gdb_regs[GDB_WIM] = 0;
- gdb_regs[GDB_TBR] = (unsigned long) &trapbase;
+ gdb_regs[GDB_TBR] = (unsigned long) &trapbase[0];
gdb_regs[GDB_PC] = regs->pc;
gdb_regs[GDB_NPC] = regs->npc;
gdb_regs[GDB_FSR] = 0;
@@ -72,7 +72,7 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
gdb_regs[GDB_PSR] = t->kpsr;
gdb_regs[GDB_WIM] = t->kwim;
- gdb_regs[GDB_TBR] = (unsigned long) &trapbase;
+ gdb_regs[GDB_TBR] = (unsigned long) &trapbase[0];
gdb_regs[GDB_PC] = t->kpc;
gdb_regs[GDB_NPC] = t->kpc + 4;
gdb_regs[GDB_FSR] = 0;
diff --git a/arch/sparc/kernel/kprobes.c b/arch/sparc/kernel/kprobes.c
index 535c7b35cb59..191bbaca9921 100644
--- a/arch/sparc/kernel/kprobes.c
+++ b/arch/sparc/kernel/kprobes.c
@@ -230,7 +230,7 @@ static unsigned long __kprobes relbranch_fixup(u32 insn, struct kprobe *p,
return regs->tnpc;
}
-/* If INSN is an instruction which writes it's PC location
+/* If INSN is an instruction which writes its PC location
* into a destination register, fix that up.
*/
static void __kprobes retpc_fixup(struct pt_regs *regs, u32 insn,
diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c
index c0fa3ef6cf01..7f3cdb6f644d 100644
--- a/arch/sparc/kernel/ldc.c
+++ b/arch/sparc/kernel/ldc.c
@@ -1854,7 +1854,7 @@ static int read_nonraw(struct ldc_channel *lp, void *buf, unsigned int size)
* This seems the best behavior because this allows
* a user of the LDC layer to start with a small
* RX buffer for ldc_read() calls and use -EMSGSIZE
- * as a cue to enlarge it's read buffer.
+ * as a cue to enlarge its read buffer.
*/
err = -EMSGSIZE;
break;
diff --git a/arch/sparc/kernel/leon_pci_grpci1.c b/arch/sparc/kernel/leon_pci_grpci1.c
index 8700a0e3b0df..b2b639bee068 100644
--- a/arch/sparc/kernel/leon_pci_grpci1.c
+++ b/arch/sparc/kernel/leon_pci_grpci1.c
@@ -697,7 +697,7 @@ err1:
return err;
}
-static const struct of_device_id grpci1_of_match[] __initconst = {
+static const struct of_device_id grpci1_of_match[] = {
{
.name = "GAISLER_PCIFBRG",
},
diff --git a/arch/sparc/kernel/leon_pci_grpci2.c b/arch/sparc/kernel/leon_pci_grpci2.c
index 60b6bdf7761f..9f662340b5b2 100644
--- a/arch/sparc/kernel/leon_pci_grpci2.c
+++ b/arch/sparc/kernel/leon_pci_grpci2.c
@@ -586,7 +586,7 @@ static void grpci2_hw_init(struct grpci2_priv *priv)
REGSTORE(regs->io_map, REGLOAD(regs->io_map) & 0x0000ffff);
/* set 1:1 mapping between AHB -> PCI memory space, for all Masters
- * Each AHB master has it's own mapping registers. Max 16 AHB masters.
+ * Each AHB master has its own mapping registers. Max 16 AHB masters.
*/
for (i = 0; i < 16; i++)
REGSTORE(regs->ahbmst_map[i], priv->pci_area);
@@ -889,7 +889,7 @@ err1:
return err;
}
-static const struct of_device_id grpci2_of_match[] __initconst = {
+static const struct of_device_id grpci2_of_match[] = {
{
.name = "GAISLER_GRPCI2",
},
diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c
index 991e9ad3d3e8..1ee393abc463 100644
--- a/arch/sparc/kernel/leon_smp.c
+++ b/arch/sparc/kernel/leon_smp.c
@@ -245,13 +245,13 @@ void __init leon_smp_done(void)
/* Free unneeded trap tables */
if (!cpu_present(1)) {
- free_reserved_page(virt_to_page(&trapbase_cpu1));
+ free_reserved_page(virt_to_page(&trapbase_cpu1[0]));
}
if (!cpu_present(2)) {
- free_reserved_page(virt_to_page(&trapbase_cpu2));
+ free_reserved_page(virt_to_page(&trapbase_cpu2[0]));
}
if (!cpu_present(3)) {
- free_reserved_page(virt_to_page(&trapbase_cpu3));
+ free_reserved_page(virt_to_page(&trapbase_cpu3[0]));
}
/* Ok, they are spinning and ready to go. */
smp_processors_ready = 1;
diff --git a/arch/sparc/kernel/nmi.c b/arch/sparc/kernel/nmi.c
index 17cdfdbf1f3b..149adc094753 100644
--- a/arch/sparc/kernel/nmi.c
+++ b/arch/sparc/kernel/nmi.c
@@ -279,7 +279,7 @@ static int __init setup_nmi_watchdog(char *str)
if (!strncmp(str, "panic", 5))
panic_on_timeout = 1;
- return 0;
+ return 1;
}
__setup("nmi_watchdog=", setup_nmi_watchdog);
diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c
index d3842821a5a0..c350c58c7f69 100644
--- a/arch/sparc/kernel/of_device_64.c
+++ b/arch/sparc/kernel/of_device_64.c
@@ -560,7 +560,7 @@ static unsigned int __init build_one_device_irq(struct platform_device *op,
*
* If we hit a bus type or situation we cannot handle, we
* stop and assume that the original IRQ number was in a
- * format which has special meaning to it's immediate parent.
+ * format which has special meaning to its immediate parent.
*/
pp = dp->parent;
ip = NULL;
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index f66005ce4cb5..50a0927a84a6 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -311,7 +311,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
/* We can't actually use the firmware value, we have
* to read what is in the register right now. One
* reason is that in the case of IDE interfaces the
- * firmware can sample the value before the the IDE
+ * firmware can sample the value before the IDE
* interface is programmed into native mode.
*/
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class);
diff --git a/arch/sparc/kernel/pci_impl.h b/arch/sparc/kernel/pci_impl.h
index f31761f51757..83718876f1d4 100644
--- a/arch/sparc/kernel/pci_impl.h
+++ b/arch/sparc/kernel/pci_impl.h
@@ -19,9 +19,9 @@
* each with one (Sabre) or two (PSYCHO/SCHIZO) PCI bus modules
* underneath. Each PCI bus module uses an IOMMU (shared by both
* PBMs of a controller, or per-PBM), and if a streaming buffer
- * is present, each PCI bus module has it's own. (ie. the IOMMU
+ * is present, each PCI bus module has its own. (ie. the IOMMU
* might be shared between PBMs, the STC is never shared)
- * Furthermore, each PCI bus module controls it's own autonomous
+ * Furthermore, each PCI bus module controls its own autonomous
* PCI bus.
*/
diff --git a/arch/sparc/kernel/pci_schizo.c b/arch/sparc/kernel/pci_schizo.c
index 5d8dd4949586..93cd9e5a8099 100644
--- a/arch/sparc/kernel/pci_schizo.c
+++ b/arch/sparc/kernel/pci_schizo.c
@@ -145,7 +145,7 @@ static void __schizo_check_stc_error_pbm(struct pci_pbm_info *pbm,
/* This is __REALLY__ dangerous. When we put the
* streaming buffer into diagnostic mode to probe
- * it's tags and error status, we _must_ clear all
+ * its tags and error status, we _must_ clear all
* of the line tag valid bits before re-enabling
* the streaming buffer. If any dirty data lives
* in the STC when we do this, we will end up
@@ -275,7 +275,7 @@ static void schizo_check_iommu_error_pbm(struct pci_pbm_info *pbm,
pbm->name, type_string);
/* Put the IOMMU into diagnostic mode and probe
- * it's TLB for entries with error status.
+ * its TLB for entries with error status.
*
* It is very possible for another DVMA to occur
* while we do this probe, and corrupt the system
diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c
index a58ae9c42803..f02a283a8e8f 100644
--- a/arch/sparc/kernel/perf_event.c
+++ b/arch/sparc/kernel/perf_event.c
@@ -979,7 +979,7 @@ out:
static void sparc_pmu_start(struct perf_event *event, int flags);
-/* On this PMU each PIC has it's own PCR control register. */
+/* On this PMU each PIC has its own PCR control register. */
static void calculate_multiple_pcrs(struct cpu_hw_events *cpuc)
{
int i;
diff --git a/arch/sparc/kernel/prom_irqtrans.c b/arch/sparc/kernel/prom_irqtrans.c
index 426bd08cb2ab..5752bfd73ac0 100644
--- a/arch/sparc/kernel/prom_irqtrans.c
+++ b/arch/sparc/kernel/prom_irqtrans.c
@@ -394,7 +394,7 @@ static unsigned int schizo_irq_build(struct device_node *dp,
iclr = schizo_ino_to_iclr(pbm_regs, ino);
/* On Schizo, no inofixup occurs. This is because each
- * INO has it's own IMAP register. On Psycho and Sabre
+ * INO has its own IMAP register. On Psycho and Sabre
* there is only one IMAP register for each PCI slot even
* though four different INOs can be generated by each
* PCI slot.
diff --git a/arch/sparc/kernel/psycho_common.c b/arch/sparc/kernel/psycho_common.c
index 5ee74b4c0cf4..4557ef18f371 100644
--- a/arch/sparc/kernel/psycho_common.c
+++ b/arch/sparc/kernel/psycho_common.c
@@ -50,7 +50,7 @@ static void psycho_check_stc_error(struct pci_pbm_info *pbm)
spin_lock(&stc_buf_lock);
/* This is __REALLY__ dangerous. When we put the streaming
- * buffer into diagnostic mode to probe it's tags and error
+ * buffer into diagnostic mode to probe its tags and error
* status, we _must_ clear all of the line tag valid bits
* before re-enabling the streaming buffer. If any dirty data
* lives in the STC when we do this, we will end up
diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c
index e3b72a7b46d3..704375c061e7 100644
--- a/arch/sparc/kernel/setup_32.c
+++ b/arch/sparc/kernel/setup_32.c
@@ -67,7 +67,7 @@ static void prom_sync_me(void)
__asm__ __volatile__("wr %0, 0x0, %%tbr\n\t"
"nop\n\t"
"nop\n\t"
- "nop\n\t" : : "r" (&trapbase));
+ "nop\n\t" : : "r" (&trapbase[0]));
prom_printf("PROM SYNC COMMAND...\n");
show_mem();
@@ -285,7 +285,7 @@ void __init setup_arch(char **cmdline_p)
int i;
unsigned long highest_paddr;
- sparc_ttable = &trapbase;
+ sparc_ttable = &trapbase[0];
/* Initialize PROM console and command line. */
*cmdline_p = prom_getbootargs();
diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c
index 89b93c7136e7..478014d2e59b 100644
--- a/arch/sparc/kernel/signal_32.c
+++ b/arch/sparc/kernel/signal_32.c
@@ -473,7 +473,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
*
* %g7 is used as the "thread register". %g6 is not used in
* any fixed manner. %g6 is used as a scratch register and
- * a compiler temporary, but it's value is never used across
+ * a compiler temporary, but its value is never used across
* a system call. Therefore %g6 is usable for orig_i0 storage.
*/
if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C))
diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c
index b4e410976e0d..2d64566a1f88 100644
--- a/arch/sparc/kernel/signal_64.c
+++ b/arch/sparc/kernel/signal_64.c
@@ -494,7 +494,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
*
* %g7 is used as the "thread register". %g6 is not used in
* any fixed manner. %g6 is used as a scratch register and
- * a compiler temporary, but it's value is never used across
+ * a compiler temporary, but its value is never used across
* a system call. Therefore %g6 is usable for orig_i0 storage.
*/
if (pt_regs_is_syscall(regs) &&
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c
index f3969a3600db..a0cc9bb41a92 100644
--- a/arch/sparc/kernel/smp_64.c
+++ b/arch/sparc/kernel/smp_64.c
@@ -1206,10 +1206,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
{
}
-void smp_prepare_boot_cpu(void)
-{
-}
-
void __init smp_setup_processor_id(void)
{
if (tlb_type == spitfire)
diff --git a/arch/sparc/kernel/vio.c b/arch/sparc/kernel/vio.c
index b78df3a15a72..846a55f942d4 100644
--- a/arch/sparc/kernel/vio.c
+++ b/arch/sparc/kernel/vio.c
@@ -149,7 +149,7 @@ static struct attribute *vio_dev_attrs[] = {
};
ATTRIBUTE_GROUPS(vio_dev);
-static struct bus_type vio_bus_type = {
+static const struct bus_type vio_bus_type = {
.name = "vio",
.dev_groups = vio_dev_groups,
.uevent = vio_hotplug,
diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile
index 59669ebddd4e..ee5091dd67ed 100644
--- a/arch/sparc/lib/Makefile
+++ b/arch/sparc/lib/Makefile
@@ -14,7 +14,7 @@ lib-$(CONFIG_SPARC32) += divdi3.o udivdi3.o
lib-$(CONFIG_SPARC32) += copy_user.o locks.o
lib-$(CONFIG_SPARC64) += atomic_64.o
lib-$(CONFIG_SPARC32) += lshrdi3.o ashldi3.o
-lib-$(CONFIG_SPARC32) += muldi3.o bitext.o cmpdi2.o
+lib-$(CONFIG_SPARC32) += muldi3.o bitext.o
lib-$(CONFIG_SPARC64) += multi3.o
lib-$(CONFIG_SPARC64) += fls.o
lib-$(CONFIG_SPARC64) += fls64.o
@@ -51,5 +51,5 @@ lib-$(CONFIG_SPARC64) += copy_in_user.o memmove.o
lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o hweight.o ffs.o
obj-$(CONFIG_SPARC64) += iomap.o
-obj-$(CONFIG_SPARC32) += atomic32.o ucmpdi2.o
+obj-$(CONFIG_SPARC32) += atomic32.o
obj-$(CONFIG_SPARC64) += PeeCeeI.o
diff --git a/arch/sparc/lib/cmpdi2.c b/arch/sparc/lib/cmpdi2.c
deleted file mode 100644
index 333367fe7353..000000000000
--- a/arch/sparc/lib/cmpdi2.c
+++ /dev/null
@@ -1,28 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <linux/module.h>
-
-#include "libgcc.h"
-
-word_type __cmpdi2(long long a, long long b)
-{
- const DWunion au = {
- .ll = a
- };
- const DWunion bu = {
- .ll = b
- };
-
- if (au.s.high < bu.s.high)
- return 0;
- else if (au.s.high > bu.s.high)
- return 2;
-
- if ((unsigned int) au.s.low < (unsigned int) bu.s.low)
- return 0;
- else if ((unsigned int) au.s.low > (unsigned int) bu.s.low)
- return 2;
-
- return 1;
-}
-
-EXPORT_SYMBOL(__cmpdi2);
diff --git a/arch/sparc/lib/ucmpdi2.c b/arch/sparc/lib/ucmpdi2.c
deleted file mode 100644
index 82c1cccb1264..000000000000
--- a/arch/sparc/lib/ucmpdi2.c
+++ /dev/null
@@ -1,20 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <linux/module.h>
-#include "libgcc.h"
-
-word_type __ucmpdi2(unsigned long long a, unsigned long long b)
-{
- const DWunion au = {.ll = a};
- const DWunion bu = {.ll = b};
-
- if ((unsigned int) au.s.high < (unsigned int) bu.s.high)
- return 0;
- else if ((unsigned int) au.s.high > (unsigned int) bu.s.high)
- return 2;
- if ((unsigned int) au.s.low < (unsigned int) bu.s.low)
- return 0;
- else if ((unsigned int) au.s.low > (unsigned int) bu.s.low)
- return 2;
- return 1;
-}
-EXPORT_SYMBOL(__ucmpdi2);
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index f83017992eaa..1ca9054d9b97 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -1665,14 +1665,14 @@ bool kern_addr_valid(unsigned long addr)
if (pud_none(*pud))
return false;
- if (pud_large(*pud))
+ if (pud_leaf(*pud))
return pfn_valid(pud_pfn(*pud));
pmd = pmd_offset(pud, addr);
if (pmd_none(*pmd))
return false;
- if (pmd_large(*pmd))
+ if (pmd_leaf(*pmd))
return pfn_valid(pmd_pfn(*pmd));
pte = pte_offset_kernel(pmd, addr);
@@ -2968,7 +2968,7 @@ void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr,
struct mm_struct *mm;
pmd_t entry = *pmd;
- if (!pmd_large(entry) || !pmd_young(entry))
+ if (!pmd_leaf(entry) || !pmd_young(entry))
return;
pte = pmd_val(entry);
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index 8393faa3e596..852085ada368 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -1513,7 +1513,7 @@ static void __init init_viking(void)
/*
* We need this to make sure old viking takes no hits
- * on it's cache for dma snoops to workaround the
+ * on its cache for dma snoops to workaround the
* "load from non-cacheable memory" interrupt bug.
* This is only necessary because of the new way in
* which we use the IOMMU.
diff --git a/arch/sparc/mm/tsb.c b/arch/sparc/mm/tsb.c
index 6acd8a4c1e2a..5fe52a64c7e7 100644
--- a/arch/sparc/mm/tsb.c
+++ b/arch/sparc/mm/tsb.c
@@ -385,7 +385,7 @@ static unsigned long tsb_size_to_rss_limit(unsigned long new_size)
* will not trigger any longer.
*
* The TSB can be anywhere from 8K to 1MB in size, in increasing powers
- * of two. The TSB must be aligned to it's size, so f.e. a 512K TSB
+ * of two. The TSB must be aligned to its size, so f.e. a 512K TSB
* must be 512K aligned. It also must be physically contiguous, so we
* cannot use vmalloc().
*
diff --git a/arch/sparc/net/bpf_jit_comp_32.c b/arch/sparc/net/bpf_jit_comp_32.c
index a74e5004c6c8..da2df1e84ed4 100644
--- a/arch/sparc/net/bpf_jit_comp_32.c
+++ b/arch/sparc/net/bpf_jit_comp_32.c
@@ -300,7 +300,7 @@ do { *prog++ = BR_OPC | WDISP22(OFF); \
*
* The most common case is to emit a branch at the end of such
* a code sequence. So this would be two instructions, the
- * branch and it's delay slot.
+ * branch and its delay slot.
*
* Therefore by default the branch emitters calculate the branch
* offset field as:
@@ -309,13 +309,13 @@ do { *prog++ = BR_OPC | WDISP22(OFF); \
*
* This "addrs[i] - 8" is the address of the branch itself or
* what "." would be in assembler notation. The "8" part is
- * how we take into consideration the branch and it's delay
+ * how we take into consideration the branch and its delay
* slot mentioned above.
*
* Sometimes we need to emit a branch earlier in the code
* sequence. And in these situations we adjust "destination"
* to accommodate this difference. For example, if we needed
- * to emit a branch (and it's delay slot) right before the
+ * to emit a branch (and its delay slot) right before the
* final instruction emitted for a BPF opcode, we'd use
* "destination + 4" instead of just plain "destination" above.
*
diff --git a/arch/sparc/vdso/Makefile b/arch/sparc/vdso/Makefile
index 7f5eedf1f5e0..e8aef2c8ae99 100644
--- a/arch/sparc/vdso/Makefile
+++ b/arch/sparc/vdso/Makefile
@@ -2,6 +2,7 @@
#
# Building vDSO images for sparc.
#
+UBSAN_SANITIZE := n
# files to link into the vdso
vobjs-y := vdso-note.o vclock_gettime.o
diff --git a/arch/sparc/vdso/vma.c b/arch/sparc/vdso/vma.c
index 136c78f28f8b..1bbf4335de45 100644
--- a/arch/sparc/vdso/vma.c
+++ b/arch/sparc/vdso/vma.c
@@ -449,9 +449,8 @@ static __init int vdso_setup(char *s)
unsigned long val;
err = kstrtoul(s, 10, &val);
- if (err)
- return err;
- vdso_enabled = val;
- return 0;
+ if (!err)
+ vdso_enabled = val;
+ return 1;
}
__setup("vdso=", vdso_setup);
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index b5e179360534..93a5a8999b07 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -20,6 +20,7 @@ config UML
select HAVE_UID16
select HAVE_DEBUG_KMEMLEAK
select HAVE_DEBUG_BUGVERBOSE
+ select HAVE_PAGE_SIZE_4KB
select NO_DMA if !UML_DMA_EMULATION
select OF_EARLY_FLATTREE if OF
select GENERIC_IRQ_SHOW
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index cabcc501b448..77c4afb8ab90 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -265,7 +265,7 @@ static void uml_net_poll_controller(struct net_device *dev)
static void uml_net_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
{
- strscpy(info->driver, DRIVER_NAME, sizeof(info->driver));
+ strscpy(info->driver, DRIVER_NAME);
}
static const struct ethtool_ops uml_net_ethtool_ops = {
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 92ee2697ff39..63fc062add70 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -108,8 +108,6 @@ static inline void ubd_set_bit(__u64 bit, unsigned char *data)
static DEFINE_MUTEX(ubd_lock);
static DEFINE_MUTEX(ubd_mutex); /* replaces BKL, might not be needed */
-static int ubd_open(struct gendisk *disk, blk_mode_t mode);
-static void ubd_release(struct gendisk *disk);
static int ubd_ioctl(struct block_device *bdev, blk_mode_t mode,
unsigned int cmd, unsigned long arg);
static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo);
@@ -118,16 +116,11 @@ static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo);
static const struct block_device_operations ubd_blops = {
.owner = THIS_MODULE,
- .open = ubd_open,
- .release = ubd_release,
.ioctl = ubd_ioctl,
.compat_ioctl = blkdev_compat_ptr_ioctl,
.getgeo = ubd_getgeo,
};
-/* Protected by ubd_lock */
-static struct gendisk *ubd_gendisk[MAX_DEV];
-
#ifdef CONFIG_BLK_DEV_UBD_SYNC
#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 1, .c = 0, \
.cl = 1 })
@@ -155,7 +148,6 @@ struct ubd {
* backing or the cow file. */
char *file;
char *serial;
- int count;
int fd;
__u64 size;
struct openflags boot_openflags;
@@ -165,7 +157,7 @@ struct ubd {
unsigned no_trim:1;
struct cow cow;
struct platform_device pdev;
- struct request_queue *queue;
+ struct gendisk *disk;
struct blk_mq_tag_set tag_set;
spinlock_t lock;
};
@@ -181,7 +173,6 @@ struct ubd {
#define DEFAULT_UBD { \
.file = NULL, \
.serial = NULL, \
- .count = 0, \
.fd = -1, \
.size = -1, \
.boot_openflags = OPEN_FLAGS, \
@@ -774,8 +765,6 @@ static int ubd_open_dev(struct ubd *ubd_dev)
ubd_dev->fd = fd;
if(ubd_dev->cow.file != NULL){
- blk_queue_max_hw_sectors(ubd_dev->queue, 8 * sizeof(long));
-
err = -ENOMEM;
ubd_dev->cow.bitmap = vmalloc(ubd_dev->cow.bitmap_len);
if(ubd_dev->cow.bitmap == NULL){
@@ -797,11 +786,6 @@ static int ubd_open_dev(struct ubd *ubd_dev)
if(err < 0) goto error;
ubd_dev->cow.fd = err;
}
- if (ubd_dev->no_trim == 0) {
- blk_queue_max_discard_sectors(ubd_dev->queue, UBD_MAX_REQUEST);
- blk_queue_max_write_zeroes_sectors(ubd_dev->queue, UBD_MAX_REQUEST);
- }
- blk_queue_flag_set(QUEUE_FLAG_NONROT, ubd_dev->queue);
return 0;
error:
os_close_file(ubd_dev->fd);
@@ -851,27 +835,6 @@ static const struct attribute_group *ubd_attr_groups[] = {
NULL,
};
-static int ubd_disk_register(int major, u64 size, int unit,
- struct gendisk *disk)
-{
- disk->major = major;
- disk->first_minor = unit << UBD_SHIFT;
- disk->minors = 1 << UBD_SHIFT;
- disk->fops = &ubd_blops;
- set_capacity(disk, size / 512);
- sprintf(disk->disk_name, "ubd%c", 'a' + unit);
-
- ubd_devs[unit].pdev.id = unit;
- ubd_devs[unit].pdev.name = DRIVER_NAME;
- ubd_devs[unit].pdev.dev.release = ubd_device_release;
- dev_set_drvdata(&ubd_devs[unit].pdev.dev, &ubd_devs[unit]);
- platform_device_register(&ubd_devs[unit].pdev);
-
- disk->private_data = &ubd_devs[unit];
- disk->queue = ubd_devs[unit].queue;
- return device_add_disk(&ubd_devs[unit].pdev.dev, disk, ubd_attr_groups);
-}
-
#define ROUND_BLOCK(n) ((n + (SECTOR_SIZE - 1)) & (-SECTOR_SIZE))
static const struct blk_mq_ops ubd_mq_ops = {
@@ -881,18 +844,36 @@ static const struct blk_mq_ops ubd_mq_ops = {
static int ubd_add(int n, char **error_out)
{
struct ubd *ubd_dev = &ubd_devs[n];
+ struct queue_limits lim = {
+ .max_segments = MAX_SG,
+ .seg_boundary_mask = PAGE_SIZE - 1,
+ };
struct gendisk *disk;
int err = 0;
if(ubd_dev->file == NULL)
goto out;
+ if (ubd_dev->cow.file)
+ lim.max_hw_sectors = 8 * sizeof(long);
+ if (!ubd_dev->no_trim) {
+ lim.max_hw_discard_sectors = UBD_MAX_REQUEST;
+ lim.max_write_zeroes_sectors = UBD_MAX_REQUEST;
+ }
+
err = ubd_file_size(ubd_dev, &ubd_dev->size);
if(err < 0){
*error_out = "Couldn't determine size of device's file";
goto out;
}
+ err = ubd_open_dev(ubd_dev);
+ if (err) {
+ pr_err("ubd%c: Can't open \"%s\": errno = %d\n",
+ 'a' + n, ubd_dev->file, -err);
+ goto out;
+ }
+
ubd_dev->size = ROUND_BLOCK(ubd_dev->size);
ubd_dev->tag_set.ops = &ubd_mq_ops;
@@ -904,29 +885,43 @@ static int ubd_add(int n, char **error_out)
err = blk_mq_alloc_tag_set(&ubd_dev->tag_set);
if (err)
- goto out;
+ goto out_close;
- disk = blk_mq_alloc_disk(&ubd_dev->tag_set, ubd_dev);
+ disk = blk_mq_alloc_disk(&ubd_dev->tag_set, &lim, ubd_dev);
if (IS_ERR(disk)) {
err = PTR_ERR(disk);
goto out_cleanup_tags;
}
- ubd_dev->queue = disk->queue;
- blk_queue_write_cache(ubd_dev->queue, true, false);
- blk_queue_max_segments(ubd_dev->queue, MAX_SG);
- blk_queue_segment_boundary(ubd_dev->queue, PAGE_SIZE - 1);
- err = ubd_disk_register(UBD_MAJOR, ubd_dev->size, n, disk);
+ 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;
+ disk->fops = &ubd_blops;
+ set_capacity(disk, ubd_dev->size / 512);
+ sprintf(disk->disk_name, "ubd%c", 'a' + n);
+ disk->private_data = ubd_dev;
+ set_disk_ro(disk, !ubd_dev->openflags.w);
+
+ ubd_dev->pdev.id = n;
+ ubd_dev->pdev.name = DRIVER_NAME;
+ ubd_dev->pdev.dev.release = ubd_device_release;
+ dev_set_drvdata(&ubd_dev->pdev.dev, ubd_dev);
+ platform_device_register(&ubd_dev->pdev);
+
+ err = device_add_disk(&ubd_dev->pdev.dev, disk, ubd_attr_groups);
if (err)
goto out_cleanup_disk;
- ubd_gendisk[n] = disk;
return 0;
out_cleanup_disk:
put_disk(disk);
out_cleanup_tags:
blk_mq_free_tag_set(&ubd_dev->tag_set);
+out_close:
+ ubd_close_dev(ubd_dev);
out:
return err;
}
@@ -1012,7 +1007,6 @@ static int ubd_id(char **str, int *start_out, int *end_out)
static int ubd_remove(int n, char **error_out)
{
- struct gendisk *disk = ubd_gendisk[n];
struct ubd *ubd_dev;
int err = -ENODEV;
@@ -1023,15 +1017,15 @@ static int ubd_remove(int n, char **error_out)
if(ubd_dev->file == NULL)
goto out;
- /* you cannot remove a open disk */
- err = -EBUSY;
- if(ubd_dev->count > 0)
- goto out;
+ if (ubd_dev->disk) {
+ /* you cannot remove a open disk */
+ err = -EBUSY;
+ if (disk_openers(ubd_dev->disk))
+ goto out;
- ubd_gendisk[n] = NULL;
- if(disk != NULL){
- del_gendisk(disk);
- put_disk(disk);
+ del_gendisk(ubd_dev->disk);
+ ubd_close_dev(ubd_dev);
+ put_disk(ubd_dev->disk);
}
err = 0;
@@ -1153,37 +1147,6 @@ static int __init ubd_driver_init(void){
device_initcall(ubd_driver_init);
-static int ubd_open(struct gendisk *disk, blk_mode_t mode)
-{
- struct ubd *ubd_dev = disk->private_data;
- int err = 0;
-
- mutex_lock(&ubd_mutex);
- if(ubd_dev->count == 0){
- err = ubd_open_dev(ubd_dev);
- if(err){
- printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n",
- disk->disk_name, ubd_dev->file, -err);
- goto out;
- }
- }
- ubd_dev->count++;
- set_disk_ro(disk, !ubd_dev->openflags.w);
-out:
- mutex_unlock(&ubd_mutex);
- return err;
-}
-
-static void ubd_release(struct gendisk *disk)
-{
- struct ubd *ubd_dev = disk->private_data;
-
- mutex_lock(&ubd_mutex);
- if(--ubd_dev->count == 0)
- ubd_close_dev(ubd_dev);
- mutex_unlock(&ubd_mutex);
-}
-
static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask,
__u64 *cow_offset, unsigned long *bitmap,
__u64 bitmap_offset, unsigned long *bitmap_words,
diff --git a/arch/um/drivers/vector_kern.c b/arch/um/drivers/vector_kern.c
index 131b7cb29576..dc2feae789cb 100644
--- a/arch/um/drivers/vector_kern.c
+++ b/arch/um/drivers/vector_kern.c
@@ -1373,7 +1373,7 @@ static void vector_net_poll_controller(struct net_device *dev)
static void vector_net_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
{
- strscpy(info->driver, DRIVER_NAME, sizeof(info->driver));
+ strscpy(info->driver, DRIVER_NAME);
}
static int vector_net_load_bpf_flash(struct net_device *dev,
diff --git a/arch/um/drivers/vector_user.c b/arch/um/drivers/vector_user.c
index c719e1ec4645..b16a5e5619d3 100644
--- a/arch/um/drivers/vector_user.c
+++ b/arch/um/drivers/vector_user.c
@@ -141,7 +141,7 @@ static int create_tap_fd(char *iface)
}
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR;
- strscpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name));
+ strscpy(ifr.ifr_name, iface);
err = ioctl(fd, TUNSETIFF, (void *) &ifr);
if (err != 0) {
@@ -171,7 +171,7 @@ static int create_raw_fd(char *iface, int flags, int proto)
goto raw_fd_cleanup;
}
memset(&ifr, 0, sizeof(ifr));
- strscpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name));
+ strscpy(ifr.ifr_name, iface);
if (ioctl(fd, SIOCGIFINDEX, (void *) &ifr) < 0) {
err = -errno;
goto raw_fd_cleanup;
diff --git a/arch/um/include/asm/page.h b/arch/um/include/asm/page.h
index 84866127d074..9ef9a8aedfa6 100644
--- a/arch/um/include/asm/page.h
+++ b/arch/um/include/asm/page.h
@@ -10,7 +10,7 @@
#include <linux/const.h>
/* PAGE_SHIFT determines the page size */
-#define PAGE_SHIFT 12
+#define PAGE_SHIFT CONFIG_PAGE_SHIFT
#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
diff --git a/arch/um/include/shared/user.h b/arch/um/include/shared/user.h
index 981e11d8e025..326e52450e41 100644
--- a/arch/um/include/shared/user.h
+++ b/arch/um/include/shared/user.h
@@ -51,7 +51,8 @@ static inline int printk(const char *fmt, ...)
extern int in_aton(char *str);
extern size_t strlcat(char *, const char *, size_t);
-extern size_t strscpy(char *, const char *, size_t);
+extern size_t sized_strscpy(char *, const char *, size_t);
+#define strscpy(dst, src) sized_strscpy(dst, src, sizeof(dst))
/* Copied from linux/compiler-gcc.h since we can't include it directly */
#define barrier() __asm__ __volatile__("": : :"memory")
diff --git a/arch/um/kernel/dtb.c b/arch/um/kernel/dtb.c
index 484141b06938..4954188a6a09 100644
--- a/arch/um/kernel/dtb.c
+++ b/arch/um/kernel/dtb.c
@@ -16,16 +16,16 @@ void uml_dtb_init(void)
void *area;
area = uml_load_file(dtb, &size);
- if (!area)
- return;
-
- if (!early_init_dt_scan(area)) {
- pr_err("invalid DTB %s\n", dtb);
- memblock_free(area, size);
- return;
+ if (area) {
+ if (!early_init_dt_scan(area)) {
+ pr_err("invalid DTB %s\n", dtb);
+ memblock_free(area, size);
+ return;
+ }
+
+ early_init_fdt_scan_reserved_mem();
}
- early_init_fdt_scan_reserved_mem();
unflatten_device_tree();
}
diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c
index 3363851a4ae8..bdf215c0eca7 100644
--- a/arch/um/os-Linux/drivers/ethertap_user.c
+++ b/arch/um/os-Linux/drivers/ethertap_user.c
@@ -105,7 +105,7 @@ static int etap_tramp(char *dev, char *gate, int control_me,
sprintf(data_fd_buf, "%d", data_remote);
sprintf(version_buf, "%d", UML_NET_VERSION);
if (gate != NULL) {
- strscpy(gate_buf, gate, sizeof(gate_buf));
+ strscpy(gate_buf, gate);
args = setup_args;
}
else args = nosetup_args;
diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c
index 2284e9c1cbbb..91f0e27ca3a6 100644
--- a/arch/um/os-Linux/drivers/tuntap_user.c
+++ b/arch/um/os-Linux/drivers/tuntap_user.c
@@ -146,7 +146,7 @@ static int tuntap_open(void *data)
}
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
- strscpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name));
+ strscpy(ifr.ifr_name, pri->dev_name);
if (ioctl(pri->fd, TUNSETIFF, &ifr) < 0) {
err = -errno;
printk(UM_KERN_ERR "TUNSETIFF failed, errno = %d\n",
diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c
index 288c422bfa96..e09d65b05d1c 100644
--- a/arch/um/os-Linux/umid.c
+++ b/arch/um/os-Linux/umid.c
@@ -40,7 +40,7 @@ static int __init make_uml_dir(void)
__func__);
goto err;
}
- strscpy(dir, home, sizeof(dir));
+ strscpy(dir, home);
uml_dir++;
}
strlcat(dir, uml_dir, sizeof(dir));
@@ -243,7 +243,7 @@ int __init set_umid(char *name)
if (strlen(name) > UMID_LEN - 1)
return -E2BIG;
- strscpy(umid, name, sizeof(umid));
+ strscpy(umid, name);
return 0;
}
@@ -262,7 +262,7 @@ static int __init make_umid(void)
make_uml_dir();
if (*umid == '\0') {
- strscpy(tmp, uml_dir, sizeof(tmp));
+ strscpy(tmp, uml_dir);
strlcat(tmp, "XXXXXX", sizeof(tmp));
fd = mkstemp(tmp);
if (fd < 0) {
diff --git a/arch/x86/Kbuild b/arch/x86/Kbuild
index 5a83da703e87..cf0ad89f5639 100644
--- a/arch/x86/Kbuild
+++ b/arch/x86/Kbuild
@@ -28,5 +28,7 @@ obj-y += net/
obj-$(CONFIG_KEXEC_FILE) += purgatory/
+obj-y += virt/
+
# for cleaning
subdir- += boot tools
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 5edec175b9bf..10a6251f58f3 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -100,7 +100,7 @@ config X86
select ARCH_HAS_STRICT_MODULE_RWX
select ARCH_HAS_SYNC_CORE_BEFORE_USERMODE
select ARCH_HAS_SYSCALL_WRAPPER
- select ARCH_HAS_UBSAN_SANITIZE_ALL
+ select ARCH_HAS_UBSAN
select ARCH_HAS_DEBUG_WX
select ARCH_HAS_ZONE_DMA_SET if EXPERT
select ARCH_HAVE_NMI_SAFE_CMPXCHG
@@ -147,6 +147,7 @@ config X86
select EDAC_ATOMIC_SCRUB
select EDAC_SUPPORT
select GENERIC_CLOCKEVENTS_BROADCAST if X86_64 || (X86_32 && X86_LOCAL_APIC)
+ select GENERIC_CLOCKEVENTS_BROADCAST_IDLE if GENERIC_CLOCKEVENTS_BROADCAST
select GENERIC_CLOCKEVENTS_MIN_ADJUST
select GENERIC_CMOS_UPDATE
select GENERIC_CPU_AUTOPROBE
@@ -244,7 +245,6 @@ config X86
select HAVE_FUNCTION_ERROR_INJECTION
select HAVE_KRETPROBES
select HAVE_RETHOOK
- select HAVE_KVM
select HAVE_LIVEPATCH if X86_64
select HAVE_MIXED_BREAKPOINTS_REGS
select HAVE_MOD_ARCH_SPECIFIC
@@ -255,6 +255,7 @@ config X86
select HAVE_NOINSTR_VALIDATION if HAVE_OBJTOOL
select HAVE_OBJTOOL if X86_64
select HAVE_OPTPROBES
+ select HAVE_PAGE_SIZE_4KB
select HAVE_PCSPKR_PLATFORM
select HAVE_PERF_EVENTS
select HAVE_PERF_EVENTS_NMI
@@ -471,10 +472,6 @@ config X86_MPPARSE
For old smp systems that do not have proper acpi support. Newer systems
(esp with 64bit cpus) with acpi support, MADT and DSDT will override it
-config GOLDFISH
- def_bool y
- depends on X86_GOLDFISH
-
config X86_CPU_RESCTRL
bool "x86 CPU resource control support"
depends on X86 && (CPU_SUP_INTEL || CPU_SUP_AMD)
@@ -496,6 +493,15 @@ config X86_CPU_RESCTRL
Say N if unsure.
+config X86_FRED
+ bool "Flexible Return and Event Delivery"
+ depends on X86_64
+ help
+ 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.
+
if X86_32
config X86_BIGSMP
bool "Support for big SMP systems with more than 8 CPUs"
@@ -1054,8 +1060,9 @@ config SCHED_MC
config SCHED_MC_PRIO
bool "CPU core priorities scheduler support"
- depends on SCHED_MC && CPU_SUP_INTEL
- select X86_INTEL_PSTATE
+ depends on SCHED_MC
+ select X86_INTEL_PSTATE if CPU_SUP_INTEL
+ select X86_AMD_PSTATE if CPU_SUP_AMD && ACPI
select CPU_FREQ
default y
help
@@ -1539,19 +1546,6 @@ config AMD_MEM_ENCRYPT
This requires an AMD processor that supports Secure Memory
Encryption (SME).
-config AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT
- bool "Activate AMD Secure Memory Encryption (SME) by default"
- depends on AMD_MEM_ENCRYPT
- help
- Say yes to have system memory encrypted by default if running on
- an AMD processor that supports Secure Memory Encryption (SME).
-
- If set to Y, then the encryption of system memory can be
- deactivated with the mem_encrypt=off command line option.
-
- If set to N, then the encryption of system memory can be
- activated with the mem_encrypt=on command line option.
-
# Common NUMA Features
config NUMA
bool "NUMA Memory Allocation and Scheduler Support"
@@ -2106,7 +2100,7 @@ config ARCH_SUPPORTS_CRASH_HOTPLUG
def_bool y
config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
- def_bool CRASH_CORE
+ def_bool CRASH_RESERVE
config PHYSICAL_START
hex "Physical address where the kernel is loaded" if (EXPERT || CRASH_DUMP)
@@ -2114,11 +2108,11 @@ config PHYSICAL_START
help
This gives the physical address where the kernel is loaded.
- If kernel is a not relocatable (CONFIG_RELOCATABLE=n) then
- bzImage will decompress itself to above physical address and
- run from there. Otherwise, bzImage will run from the address where
- it has been loaded by the boot loader and will ignore above physical
- address.
+ If the kernel is not relocatable (CONFIG_RELOCATABLE=n) then bzImage
+ will decompress itself to above physical address and run from there.
+ Otherwise, bzImage will run from the address where it has been loaded
+ by the boot loader. The only exception is if it is loaded below the
+ above physical address, in which case it will relocate itself there.
In normal kdump cases one does not have to set/change this option
as now bzImage can be compiled as a completely relocatable image
@@ -2434,6 +2428,20 @@ source "kernel/livepatch/Kconfig"
endmenu
+config CC_HAS_NAMED_AS
+ def_bool CC_IS_GCC && GCC_VERSION >= 120100
+
+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.
+ #
+ depends on !KASAN
+ # -fsanitize=thread (KCSAN) is also incompatible.
+ depends on !KCSAN
+
config CC_HAS_SLS
def_bool $(cc-option,-mharden-sls=all)
@@ -2465,12 +2473,12 @@ config CALL_PADDING
config FINEIBT
def_bool y
- depends on X86_KERNEL_IBT && CFI_CLANG && RETPOLINE
+ depends on X86_KERNEL_IBT && CFI_CLANG && MITIGATION_RETPOLINE
select CALL_PADDING
config HAVE_CALL_THUNKS
def_bool y
- depends on CC_HAS_ENTRY_PADDING && RETHUNK && OBJTOOL
+ depends on CC_HAS_ENTRY_PADDING && MITIGATION_RETHUNK && OBJTOOL
config CALL_THUNKS
def_bool n
@@ -2492,7 +2500,7 @@ menuconfig SPECULATION_MITIGATIONS
if SPECULATION_MITIGATIONS
-config PAGE_TABLE_ISOLATION
+config MITIGATION_PAGE_TABLE_ISOLATION
bool "Remove the kernel mapping in user mode"
default y
depends on (X86_64 || X86_PAE)
@@ -2503,7 +2511,7 @@ config PAGE_TABLE_ISOLATION
See Documentation/arch/x86/pti.rst for more details.
-config RETPOLINE
+config MITIGATION_RETPOLINE
bool "Avoid speculative indirect branches in kernel"
select OBJTOOL if HAVE_OBJTOOL
default y
@@ -2513,9 +2521,9 @@ config RETPOLINE
branches. Requires a compiler with -mindirect-branch=thunk-extern
support for full protection. The kernel may run slower.
-config RETHUNK
+config MITIGATION_RETHUNK
bool "Enable return-thunks"
- depends on RETPOLINE && CC_HAS_RETURN_THUNK
+ depends on MITIGATION_RETPOLINE && CC_HAS_RETURN_THUNK
select OBJTOOL if HAVE_OBJTOOL
default y if X86_64
help
@@ -2524,14 +2532,14 @@ config RETHUNK
Requires a compiler with -mfunction-return=thunk-extern
support for full protection. The kernel may run slower.
-config CPU_UNRET_ENTRY
+config MITIGATION_UNRET_ENTRY
bool "Enable UNRET on kernel entry"
- depends on CPU_SUP_AMD && RETHUNK && X86_64
+ depends on CPU_SUP_AMD && MITIGATION_RETHUNK && X86_64
default y
help
Compile the kernel with support for the retbleed=unret mitigation.
-config CALL_DEPTH_TRACKING
+config MITIGATION_CALL_DEPTH_TRACKING
bool "Mitigate RSB underflow with call depth tracking"
depends on CPU_SUP_INTEL && HAVE_CALL_THUNKS
select HAVE_DYNAMIC_FTRACE_NO_PATCHABLE
@@ -2551,7 +2559,7 @@ config CALL_DEPTH_TRACKING
config CALL_THUNKS_DEBUG
bool "Enable call thunks and call depth tracking debugging"
- depends on CALL_DEPTH_TRACKING
+ depends on MITIGATION_CALL_DEPTH_TRACKING
select FUNCTION_ALIGNMENT_32B
default n
help
@@ -2562,14 +2570,14 @@ config CALL_THUNKS_DEBUG
Only enable this when you are debugging call thunks as this
creates a noticeable runtime overhead. If unsure say N.
-config CPU_IBPB_ENTRY
+config MITIGATION_IBPB_ENTRY
bool "Enable IBPB on kernel entry"
depends on CPU_SUP_AMD && X86_64
default y
help
Compile the kernel with support for the retbleed=ibpb mitigation.
-config CPU_IBRS_ENTRY
+config MITIGATION_IBRS_ENTRY
bool "Enable IBRS on kernel entry"
depends on CPU_SUP_INTEL && X86_64
default y
@@ -2578,14 +2586,14 @@ config CPU_IBRS_ENTRY
This mitigates both spectre_v2 and retbleed at great cost to
performance.
-config CPU_SRSO
+config MITIGATION_SRSO
bool "Mitigate speculative RAS overflow on AMD"
- depends on CPU_SUP_AMD && X86_64 && RETHUNK
+ depends on CPU_SUP_AMD && X86_64 && MITIGATION_RETHUNK
default y
help
Enable the SRSO mitigation needed on AMD Zen1-4 machines.
-config SLS
+config MITIGATION_SLS
bool "Mitigate Straight-Line-Speculation"
depends on CC_HAS_SLS && X86_64
select OBJTOOL if HAVE_OBJTOOL
@@ -2595,7 +2603,7 @@ config SLS
against straight line speculation. The kernel image might be slightly
larger.
-config GDS_FORCE_MITIGATION
+config MITIGATION_GDS_FORCE
bool "Force GDS Mitigation"
depends on CPU_SUP_INTEL
default n
@@ -2614,6 +2622,43 @@ config GDS_FORCE_MITIGATION
If in doubt, say N.
+config MITIGATION_RFDS
+ bool "RFDS Mitigation"
+ depends on CPU_SUP_INTEL
+ default y
+ help
+ Enable mitigation for Register File Data Sampling (RFDS) by default.
+ RFDS is a hardware vulnerability which affects Intel Atom CPUs. It
+ allows unprivileged speculative access to stale data previously
+ stored in floating point, vector and integer registers.
+ See also <file:Documentation/admin-guide/hw-vuln/reg-file-data-sampling.rst>
+
+choice
+ prompt "Clear branch history"
+ depends on CPU_SUP_INTEL
+ default SPECTRE_BHI_ON
+ help
+ Enable BHI mitigations. BHI attacks are a form of Spectre V2 attacks
+ where the branch history buffer is poisoned to speculatively steer
+ indirect branches.
+ See <file:Documentation/admin-guide/hw-vuln/spectre.rst>
+
+config SPECTRE_BHI_ON
+ bool "on"
+ help
+ Equivalent to setting spectre_bhi=on command line parameter.
+config SPECTRE_BHI_OFF
+ bool "off"
+ help
+ Equivalent to setting spectre_bhi=off command line parameter.
+config SPECTRE_BHI_AUTO
+ bool "auto"
+ depends on BROKEN
+ help
+ Equivalent to setting spectre_bhi=auto command line parameter.
+
+endchoice
+
endif
config ARCH_HAS_ADD_PAGES
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index da8f3caf2781..5ab93fcdd691 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -22,7 +22,7 @@ RETPOLINE_VDSO_CFLAGS := -mretpoline
endif
RETPOLINE_CFLAGS += $(call cc-option,-mindirect-branch-cs-prefix)
-ifdef CONFIG_RETHUNK
+ifdef CONFIG_MITIGATION_RETHUNK
RETHUNK_CFLAGS := -mfunction-return=thunk-extern
RETPOLINE_CFLAGS += $(RETHUNK_CFLAGS)
endif
@@ -53,6 +53,9 @@ REALMODE_CFLAGS += -fno-stack-protector
REALMODE_CFLAGS += -Wno-address-of-packed-member
REALMODE_CFLAGS += $(cc_stack_align4)
REALMODE_CFLAGS += $(CLANG_FLAGS)
+ifdef CONFIG_CC_IS_CLANG
+REALMODE_CFLAGS += -Wno-gnu
+endif
export REALMODE_CFLAGS
# BITS is used as extension for files which are available in a 32 bit
@@ -68,6 +71,7 @@ export BITS
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53383
#
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
ifeq ($(CONFIG_X86_KERNEL_IBT),y)
@@ -192,7 +196,7 @@ KBUILD_CFLAGS += -Wno-sign-compare
KBUILD_CFLAGS += -fno-asynchronous-unwind-tables
# Avoid indirect branches in kernel to deal with Spectre
-ifdef CONFIG_RETPOLINE
+ifdef CONFIG_MITIGATION_RETPOLINE
KBUILD_CFLAGS += $(RETPOLINE_CFLAGS)
# Additionally, avoid generating expensive indirect jumps which
# are subject to retpolines for small number of switch cases.
@@ -205,7 +209,7 @@ ifdef CONFIG_RETPOLINE
endif
endif
-ifdef CONFIG_SLS
+ifdef CONFIG_MITIGATION_SLS
KBUILD_CFLAGS += -mharden-sls=all
endif
@@ -217,12 +221,6 @@ endif
KBUILD_LDFLAGS += -m elf_$(UTS_MACHINE)
-ifdef CONFIG_LTO_CLANG
-ifeq ($(call test-lt, $(CONFIG_LLD_VERSION), 130000),y)
-KBUILD_LDFLAGS += -plugin-opt=-stack-alignment=$(if $(CONFIG_X86_32),4,8)
-endif
-endif
-
ifdef CONFIG_X86_NEED_RELOCS
LDFLAGS_vmlinux := --emit-relocs --discard-none
else
@@ -253,8 +251,6 @@ archheaders:
libs-y += arch/x86/lib/
-core-y += arch/x86/virt/
-
# drivers-y are linked after core-y
drivers-$(CONFIG_MATH_EMULATION) += arch/x86/math-emu/
drivers-$(CONFIG_PCI) += arch/x86/pci/
@@ -296,12 +292,11 @@ install:
vdso-install-$(CONFIG_X86_64) += arch/x86/entry/vdso/vdso64.so.dbg
vdso-install-$(CONFIG_X86_X32_ABI) += arch/x86/entry/vdso/vdsox32.so.dbg
-vdso-install-$(CONFIG_X86_32) += arch/x86/entry/vdso/vdso32.so.dbg
-vdso-install-$(CONFIG_IA32_EMULATION) += arch/x86/entry/vdso/vdso32.so.dbg
+vdso-install-$(CONFIG_COMPAT_32) += arch/x86/entry/vdso/vdso32.so.dbg
archprepare: checkbin
checkbin:
-ifdef CONFIG_RETPOLINE
+ifdef CONFIG_MITIGATION_RETPOLINE
ifeq ($(RETPOLINE_CFLAGS),)
@echo "You are building kernel with non-retpoline compiler." >&2
@echo "Please update your compiler." >&2
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
index f19c038409aa..e9522c6893be 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -84,7 +84,7 @@ LDFLAGS_vmlinux += -T
hostprogs := mkpiggy
HOST_EXTRACFLAGS += -I$(srctree)/tools/include
-sed-voffset := -e 's/^\([0-9a-fA-F]*\) [ABCDGRSTVW] \(_text\|__bss_start\|_end\)$$/\#define VO_\2 _AC(0x\1,UL)/p'
+sed-voffset := -e 's/^\([0-9a-fA-F]*\) [ABCDGRSTVW] \(_text\|__start_rodata\|__bss_start\|_end\)$$/\#define VO_\2 _AC(0x\1,UL)/p'
quiet_cmd_voffset = VOFFSET $@
cmd_voffset = $(NM) $< | sed -n $(sed-voffset) > $@
diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c
index 18d15d1ce87d..f196b1d1ddf8 100644
--- a/arch/x86/boot/compressed/acpi.c
+++ b/arch/x86/boot/compressed/acpi.c
@@ -5,6 +5,8 @@
#include "../string.h"
#include "efi.h"
+#include <asm/bootparam.h>
+
#include <linux/numa.h>
/*
diff --git a/arch/x86/boot/compressed/cmdline.c b/arch/x86/boot/compressed/cmdline.c
index c1bb180973ea..e162d7f59cc5 100644
--- a/arch/x86/boot/compressed/cmdline.c
+++ b/arch/x86/boot/compressed/cmdline.c
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
#include "misc.h"
+#include <asm/bootparam.h>
+
static unsigned long fs;
static inline void set_fs(unsigned long seg)
{
diff --git a/arch/x86/boot/compressed/efi.c b/arch/x86/boot/compressed/efi.c
index 6edd034b0b30..f2e50f9758e6 100644
--- a/arch/x86/boot/compressed/efi.c
+++ b/arch/x86/boot/compressed/efi.c
@@ -7,6 +7,8 @@
#include "misc.h"
+#include <asm/bootparam.h>
+
/**
* efi_get_type - Given a pointer to boot_params, determine the type of EFI environment.
*
diff --git a/arch/x86/boot/compressed/efi.h b/arch/x86/boot/compressed/efi.h
index 866c0af8b5b9..b22300970f97 100644
--- a/arch/x86/boot/compressed/efi.h
+++ b/arch/x86/boot/compressed/efi.h
@@ -97,15 +97,6 @@ typedef struct {
u32 tables;
} efi_system_table_32_t;
-/* kexec external ABI */
-struct efi_setup_data {
- u64 fw_vendor;
- u64 __unused;
- u64 tables;
- u64 smbios;
- u64 reserved[8];
-};
-
struct efi_unaccepted_memory {
u32 version;
u32 unit_size;
diff --git a/arch/x86/boot/compressed/efi_mixed.S b/arch/x86/boot/compressed/efi_mixed.S
index f4e22ef774ab..876fc6d46a13 100644
--- a/arch/x86/boot/compressed/efi_mixed.S
+++ b/arch/x86/boot/compressed/efi_mixed.S
@@ -15,10 +15,12 @@
*/
#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
#include <asm/msr.h>
#include <asm/page_types.h>
#include <asm/processor-flags.h>
#include <asm/segment.h>
+#include <asm/setup.h>
.code64
.text
@@ -49,6 +51,11 @@ SYM_FUNC_START(startup_64_mixed_mode)
lea efi32_boot_args(%rip), %rdx
mov 0(%rdx), %edi
mov 4(%rdx), %esi
+
+ /* Switch to the firmware's stack */
+ movl efi32_boot_sp(%rip), %esp
+ andl $~7, %esp
+
#ifdef CONFIG_EFI_HANDOVER_PROTOCOL
mov 8(%rdx), %edx // saved bootparams pointer
test %edx, %edx
@@ -144,6 +151,7 @@ SYM_FUNC_END(__efi64_thunk)
SYM_FUNC_START(efi32_stub_entry)
call 1f
1: popl %ecx
+ leal (efi32_boot_args - 1b)(%ecx), %ebx
/* Clear BSS */
xorl %eax, %eax
@@ -158,6 +166,7 @@ SYM_FUNC_START(efi32_stub_entry)
popl %ecx
popl %edx
popl %esi
+ movl %esi, 8(%ebx)
jmp efi32_entry
SYM_FUNC_END(efi32_stub_entry)
#endif
@@ -234,8 +243,6 @@ SYM_FUNC_END(efi_enter32)
*
* Arguments: %ecx image handle
* %edx EFI system table pointer
- * %esi struct bootparams pointer (or NULL when not using
- * the EFI handover protocol)
*
* Since this is the point of no return for ordinary execution, no registers
* are considered live except for the function parameters. [Note that the EFI
@@ -254,13 +261,25 @@ SYM_FUNC_START_LOCAL(efi32_entry)
/* Store firmware IDT descriptor */
sidtl (efi32_boot_idt - 1b)(%ebx)
+ /* Store firmware stack pointer */
+ movl %esp, (efi32_boot_sp - 1b)(%ebx)
+
/* Store boot arguments */
leal (efi32_boot_args - 1b)(%ebx), %ebx
movl %ecx, 0(%ebx)
movl %edx, 4(%ebx)
- movl %esi, 8(%ebx)
movb $0x0, 12(%ebx) // efi_is64
+ /*
+ * Allocate some memory for a temporary struct boot_params, which only
+ * needs the minimal pieces that startup_32() relies on.
+ */
+ subl $PARAM_SIZE, %esp
+ movl %esp, %esi
+ movl $PAGE_SIZE, BP_kernel_alignment(%esi)
+ movl $_end - 1b, BP_init_size(%esi)
+ subl $startup_32 - 1b, BP_init_size(%esi)
+
/* Disable paging */
movl %cr0, %eax
btrl $X86_CR0_PG_BIT, %eax
@@ -286,8 +305,7 @@ SYM_FUNC_START(efi32_pe_entry)
movl 8(%ebp), %ecx // image_handle
movl 12(%ebp), %edx // sys_table
- xorl %esi, %esi
- jmp efi32_entry // pass %ecx, %edx, %esi
+ jmp efi32_entry // pass %ecx, %edx
// no other registers remain live
2: popl %edi // restore callee-save registers
@@ -318,5 +336,6 @@ SYM_DATA_END(efi32_boot_idt)
SYM_DATA_LOCAL(efi32_boot_cs, .word 0)
SYM_DATA_LOCAL(efi32_boot_ds, .word 0)
+SYM_DATA_LOCAL(efi32_boot_sp, .long 0)
SYM_DATA_LOCAL(efi32_boot_args, .long 0, 0, 0)
SYM_DATA(efi_is64, .byte 1)
diff --git a/arch/x86/boot/compressed/ident_map_64.c b/arch/x86/boot/compressed/ident_map_64.c
index d040080d7edb..dfb9c2deb77c 100644
--- a/arch/x86/boot/compressed/ident_map_64.c
+++ b/arch/x86/boot/compressed/ident_map_64.c
@@ -8,8 +8,8 @@
* Copyright (C) 2016 Kees Cook
*/
-/* No PAGE_TABLE_ISOLATION support needed either: */
-#undef CONFIG_PAGE_TABLE_ISOLATION
+/* No MITIGATION_PAGE_TABLE_ISOLATION support needed either: */
+#undef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
#include "error.h"
#include "misc.h"
@@ -284,7 +284,7 @@ static int set_clr_page_flags(struct x86_mapping_info *info,
pudp = pud_offset(p4dp, address);
pmdp = pmd_offset(pudp, address);
- if (pmd_large(*pmdp))
+ if (pmd_leaf(*pmdp))
ptep = split_large_pmd(info, pmdp, address);
else
ptep = pte_offset_kernel(pmdp, address);
@@ -389,5 +389,5 @@ void do_boot_page_fault(struct pt_regs *regs, unsigned long error_code)
void do_boot_nmi_trap(struct pt_regs *regs, unsigned long error_code)
{
- /* Empty handler to ignore NMI during early boot */
+ spurious_nmi_count++;
}
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
index b99e08e6815b..b70e4a21c15f 100644
--- a/arch/x86/boot/compressed/misc.c
+++ b/arch/x86/boot/compressed/misc.c
@@ -52,6 +52,7 @@ struct port_io_ops pio_ops;
memptr free_mem_ptr;
memptr free_mem_end_ptr;
+int spurious_nmi_count;
static char *vidmem;
static int vidport;
@@ -164,21 +165,34 @@ void __putstr(const char *s)
outb(0xff & (pos >> 1), vidport+1);
}
-void __puthex(unsigned long value)
+static noinline void __putnum(unsigned long value, unsigned int base,
+ int mindig)
{
- char alpha[2] = "0";
- int bits;
+ char buf[8*sizeof(value)+1];
+ char *p;
- for (bits = sizeof(value) * 8 - 4; bits >= 0; bits -= 4) {
- unsigned long digit = (value >> bits) & 0xf;
+ p = buf + sizeof(buf);
+ *--p = '\0';
- if (digit < 0xA)
- alpha[0] = '0' + digit;
- else
- alpha[0] = 'a' + (digit - 0xA);
+ while (mindig-- > 0 || value) {
+ unsigned char digit = value % base;
+ digit += (digit >= 10) ? ('a'-10) : '0';
+ *--p = digit;
- __putstr(alpha);
+ value /= base;
}
+
+ __putstr(p);
+}
+
+void __puthex(unsigned long value)
+{
+ __putnum(value, 16, sizeof(value)*2);
+}
+
+void __putdec(unsigned long value)
+{
+ __putnum(value, 10, 1);
}
#ifdef CONFIG_X86_NEED_RELOCS
@@ -330,6 +344,7 @@ static size_t parse_elf(void *output)
return ehdr.e_entry - LOAD_PHYSICAL_ADDR;
}
+const unsigned long kernel_text_size = VO___start_rodata - VO__text;
const unsigned long kernel_total_size = VO__end - VO__text;
static u8 boot_heap[BOOT_HEAP_SIZE] __aligned(4);
@@ -358,6 +373,19 @@ unsigned long decompress_kernel(unsigned char *outbuf, unsigned long virt_addr,
}
/*
+ * Set the memory encryption xloadflag based on the mem_encrypt= command line
+ * parameter, if provided.
+ */
+static void parse_mem_encrypt(struct setup_header *hdr)
+{
+ int on = cmdline_find_option_bool("mem_encrypt=on");
+ int off = cmdline_find_option_bool("mem_encrypt=off");
+
+ if (on > off)
+ hdr->xloadflags |= XLF_MEM_ENCRYPTION;
+}
+
+/*
* The compressed kernel image (ZO), has been moved so that its position
* is against the end of the buffer used to hold the uncompressed kernel
* image (VO) and the execution environment (.bss, .brk), which makes sure
@@ -387,6 +415,8 @@ asmlinkage __visible void *extract_kernel(void *rmode, unsigned char *output)
/* Clear flags intended for solely in-kernel use. */
boot_params_ptr->hdr.loadflags &= ~KASLR_FLAG;
+ parse_mem_encrypt(&boot_params_ptr->hdr);
+
sanitize_boot_params(boot_params_ptr);
if (boot_params_ptr->screen_info.orig_video_mode == 7) {
@@ -493,10 +523,16 @@ asmlinkage __visible void *extract_kernel(void *rmode, unsigned char *output)
/* Disable exception handling before booting the kernel */
cleanup_exception_handling();
+ if (spurious_nmi_count) {
+ error_putstr("Spurious early NMIs ignored: ");
+ error_putdec(spurious_nmi_count);
+ error_putstr("\n");
+ }
+
return output + entry_offset;
}
-void fortify_panic(const char *name)
+void __fortify_panic(const u8 reason, size_t avail, size_t size)
{
error("detected buffer overflow");
}
diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h
index bc2f0f17fb90..b353a7be380c 100644
--- a/arch/x86/boot/compressed/misc.h
+++ b/arch/x86/boot/compressed/misc.h
@@ -59,12 +59,15 @@ extern char _head[], _end[];
/* misc.c */
extern memptr free_mem_ptr;
extern memptr free_mem_end_ptr;
+extern int spurious_nmi_count;
void *malloc(int size);
void free(void *where);
void __putstr(const char *s);
void __puthex(unsigned long value);
+void __putdec(unsigned long value);
#define error_putstr(__x) __putstr(__x)
#define error_puthex(__x) __puthex(__x)
+#define error_putdec(__x) __putdec(__x)
#ifdef CONFIG_X86_VERBOSE_BOOTUP
diff --git a/arch/x86/boot/compressed/pgtable_64.c b/arch/x86/boot/compressed/pgtable_64.c
index 51f957b24ba7..c882e1f67af0 100644
--- a/arch/x86/boot/compressed/pgtable_64.c
+++ b/arch/x86/boot/compressed/pgtable_64.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#include "misc.h"
+#include <asm/bootparam.h>
#include <asm/e820/types.h>
#include <asm/processor.h>
#include "pgtable.h"
diff --git a/arch/x86/boot/compressed/sev.c b/arch/x86/boot/compressed/sev.c
index 454acd7a2daf..ec71846d28c9 100644
--- a/arch/x86/boot/compressed/sev.c
+++ b/arch/x86/boot/compressed/sev.c
@@ -12,6 +12,7 @@
*/
#include "misc.h"
+#include <asm/bootparam.h>
#include <asm/pgtable_types.h>
#include <asm/sev.h>
#include <asm/trapnr.h>
@@ -116,6 +117,9 @@ static bool fault_in_kernel_space(unsigned long address)
#undef __init
#define __init
+#undef __head
+#define __head
+
#define __BOOT_COMPRESSED
/* Basic instruction decoding support needed */
@@ -304,6 +308,10 @@ void do_boot_stage2_vc(struct pt_regs *regs, unsigned long exit_code)
if (result != ES_OK)
goto finish;
+ result = vc_check_opcode_bytes(&ctxt, exit_code);
+ if (result != ES_OK)
+ goto finish;
+
switch (exit_code) {
case SVM_EXIT_RDTSC:
case SVM_EXIT_RDTSCP:
@@ -365,7 +373,7 @@ static void enforce_vmpl0(void)
MSR_AMD64_SNP_VMPL_SSS | \
MSR_AMD64_SNP_SECURE_TSC | \
MSR_AMD64_SNP_VMGEXIT_PARAM | \
- MSR_AMD64_SNP_VMSA_REG_PROTECTION | \
+ MSR_AMD64_SNP_VMSA_REG_PROT | \
MSR_AMD64_SNP_RESERVED_BIT13 | \
MSR_AMD64_SNP_RESERVED_BIT15 | \
MSR_AMD64_SNP_RESERVED_MASK)
diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
index a1bbedd989e4..b5c79f43359b 100644
--- a/arch/x86/boot/header.S
+++ b/arch/x86/boot/header.S
@@ -111,11 +111,7 @@ extra_header_fields:
.long salign # SizeOfHeaders
.long 0 # CheckSum
.word IMAGE_SUBSYSTEM_EFI_APPLICATION # Subsystem (EFI application)
-#ifdef CONFIG_EFI_DXE_MEM_ATTRIBUTES
.word IMAGE_DLL_CHARACTERISTICS_NX_COMPAT # DllCharacteristics
-#else
- .word 0 # DllCharacteristics
-#endif
#ifdef CONFIG_X86_32
.long 0 # SizeOfStackReserve
.long 0 # SizeOfStackCommit
diff --git a/arch/x86/coco/core.c b/arch/x86/coco/core.c
index eeec9986570e..b31ef2424d19 100644
--- a/arch/x86/coco/core.c
+++ b/arch/x86/coco/core.c
@@ -3,18 +3,27 @@
* Confidential Computing Platform Capability checks
*
* Copyright (C) 2021 Advanced Micro Devices, Inc.
+ * Copyright (C) 2024 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
*
* Author: Tom Lendacky <thomas.lendacky@amd.com>
*/
#include <linux/export.h>
#include <linux/cc_platform.h>
+#include <linux/string.h>
+#include <linux/random.h>
+#include <asm/archrandom.h>
#include <asm/coco.h>
#include <asm/processor.h>
enum cc_vendor cc_vendor __ro_after_init = CC_VENDOR_NONE;
-static u64 cc_mask __ro_after_init;
+u64 cc_mask __ro_after_init;
+
+static struct cc_attr_flags {
+ __u64 host_sev_snp : 1,
+ __resv : 63;
+} cc_flags;
static bool noinstr intel_cc_platform_has(enum cc_attr attr)
{
@@ -89,6 +98,9 @@ static bool noinstr amd_cc_platform_has(enum cc_attr attr)
case CC_ATTR_GUEST_SEV_SNP:
return sev_status & MSR_AMD64_SEV_SNP_ENABLED;
+ case CC_ATTR_HOST_SEV_SNP:
+ return cc_flags.host_sev_snp;
+
default:
return false;
}
@@ -149,7 +161,83 @@ u64 cc_mkdec(u64 val)
}
EXPORT_SYMBOL_GPL(cc_mkdec);
-__init void cc_set_mask(u64 mask)
+static void amd_cc_platform_clear(enum cc_attr attr)
+{
+ switch (attr) {
+ case CC_ATTR_HOST_SEV_SNP:
+ cc_flags.host_sev_snp = 0;
+ break;
+ default:
+ break;
+ }
+}
+
+void cc_platform_clear(enum cc_attr attr)
+{
+ switch (cc_vendor) {
+ case CC_VENDOR_AMD:
+ amd_cc_platform_clear(attr);
+ break;
+ default:
+ break;
+ }
+}
+
+static void amd_cc_platform_set(enum cc_attr attr)
{
- cc_mask = mask;
+ switch (attr) {
+ case CC_ATTR_HOST_SEV_SNP:
+ cc_flags.host_sev_snp = 1;
+ break;
+ default:
+ break;
+ }
+}
+
+void cc_platform_set(enum cc_attr attr)
+{
+ switch (cc_vendor) {
+ case CC_VENDOR_AMD:
+ amd_cc_platform_set(attr);
+ break;
+ default:
+ break;
+ }
+}
+
+__init void cc_random_init(void)
+{
+ /*
+ * The seed is 32 bytes (in units of longs), which is 256 bits, which
+ * is the security level that the RNG is targeting.
+ */
+ unsigned long rng_seed[32 / sizeof(long)];
+ size_t i, longs;
+
+ if (!cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
+ return;
+
+ /*
+ * Since the CoCo threat model includes the host, the only reliable
+ * source of entropy that can be neither observed nor manipulated is
+ * RDRAND. Usually, RDRAND failure is considered tolerable, but since
+ * CoCo guests have no other unobservable source of entropy, it's
+ * important to at least ensure the RNG gets some initial random seeds.
+ */
+ for (i = 0; i < ARRAY_SIZE(rng_seed); i += longs) {
+ longs = arch_get_random_longs(&rng_seed[i], ARRAY_SIZE(rng_seed) - i);
+
+ /*
+ * A zero return value means that the guest doesn't have RDRAND
+ * or the CPU is physically broken, and in both cases that
+ * means most crypto inside of the CoCo instance will be
+ * broken, defeating the purpose of CoCo in the first place. So
+ * just panic here because it's absolutely unsafe to continue
+ * executing.
+ */
+ if (longs == 0)
+ panic("RDRAND is defective.");
+ }
+ add_device_randomness(rng_seed, sizeof(rng_seed));
+ memzero_explicit(rng_seed, sizeof(rng_seed));
}
diff --git a/arch/x86/configs/i386_defconfig b/arch/x86/configs/i386_defconfig
index 73abbbdd26f8..91801138b10b 100644
--- a/arch/x86/configs/i386_defconfig
+++ b/arch/x86/configs/i386_defconfig
@@ -42,7 +42,7 @@ CONFIG_EFI_STUB=y
CONFIG_HZ_1000=y
CONFIG_KEXEC=y
CONFIG_CRASH_DUMP=y
-# CONFIG_RETHUNK is not set
+# CONFIG_MITIGATION_RETHUNK is not set
CONFIG_HIBERNATION=y
CONFIG_PM_DEBUG=y
CONFIG_PM_TRACE_RTC=y
diff --git a/arch/x86/configs/tiny.config b/arch/x86/configs/tiny.config
index 66c9e2aab16c..be3ee4294903 100644
--- a/arch/x86/configs/tiny.config
+++ b/arch/x86/configs/tiny.config
@@ -1,5 +1,6 @@
CONFIG_NOHIGHMEM=y
# CONFIG_HIGHMEM4G is not set
# CONFIG_HIGHMEM64G is not set
+# CONFIG_UNWINDER_ORC is not set
CONFIG_UNWINDER_GUESS=y
# CONFIG_UNWINDER_FRAME_POINTER is not set
diff --git a/arch/x86/entry/Makefile b/arch/x86/entry/Makefile
index ca2fe186994b..c93e7f5c2a06 100644
--- a/arch/x86/entry/Makefile
+++ b/arch/x86/entry/Makefile
@@ -18,6 +18,9 @@ obj-y += vdso/
obj-y += vsyscall/
obj-$(CONFIG_PREEMPTION) += thunk_$(BITS).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
+
obj-$(CONFIG_IA32_EMULATION) += entry_64_compat.o syscall_32.o
obj-$(CONFIG_X86_X32_ABI) += syscall_x32.o
-
diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h
index 9f1d94790a54..ea81770629ee 100644
--- a/arch/x86/entry/calling.h
+++ b/arch/x86/entry/calling.h
@@ -65,7 +65,7 @@ For 32-bit we have the following conventions - kernel is built with
* for assembly code:
*/
-.macro PUSH_REGS rdx=%rdx rcx=%rcx rax=%rax save_ret=0
+.macro PUSH_REGS rdx=%rdx rcx=%rcx rax=%rax save_ret=0 unwind_hint=1
.if \save_ret
pushq %rsi /* pt_regs->si */
movq 8(%rsp), %rsi /* temporarily store the return address in %rsi */
@@ -87,14 +87,17 @@ For 32-bit we have the following conventions - kernel is built with
pushq %r13 /* pt_regs->r13 */
pushq %r14 /* pt_regs->r14 */
pushq %r15 /* pt_regs->r15 */
+
+ .if \unwind_hint
UNWIND_HINT_REGS
+ .endif
.if \save_ret
pushq %rsi /* return address on top of stack */
.endif
.endm
-.macro CLEAR_REGS
+.macro CLEAR_REGS clear_bp=1
/*
* Sanitize registers of values that a speculation attack might
* otherwise want to exploit. The lower registers are likely clobbered
@@ -109,7 +112,9 @@ For 32-bit we have the following conventions - kernel is built with
xorl %r10d, %r10d /* nospec r10 */
xorl %r11d, %r11d /* nospec r11 */
xorl %ebx, %ebx /* nospec rbx */
+ .if \clear_bp
xorl %ebp, %ebp /* nospec rbp */
+ .endif
xorl %r12d, %r12d /* nospec r12 */
xorl %r13d, %r13d /* nospec r13 */
xorl %r14d, %r14d /* nospec r14 */
@@ -117,9 +122,9 @@ For 32-bit we have the following conventions - kernel is built with
.endm
-.macro PUSH_AND_CLEAR_REGS rdx=%rdx rcx=%rcx rax=%rax save_ret=0
- PUSH_REGS rdx=\rdx, rcx=\rcx, rax=\rax, save_ret=\save_ret
- CLEAR_REGS
+.macro PUSH_AND_CLEAR_REGS rdx=%rdx rcx=%rcx rax=%rax save_ret=0 clear_bp=1 unwind_hint=1
+ PUSH_REGS rdx=\rdx, rcx=\rcx, rax=\rax, save_ret=\save_ret unwind_hint=\unwind_hint
+ CLEAR_REGS clear_bp=\clear_bp
.endm
.macro POP_REGS pop_rdi=1
@@ -142,10 +147,10 @@ For 32-bit we have the following conventions - kernel is built with
.endif
.endm
-#ifdef CONFIG_PAGE_TABLE_ISOLATION
+#ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
/*
- * PAGE_TABLE_ISOLATION PGDs are 8k. Flip bit 12 to switch between the two
+ * MITIGATION_PAGE_TABLE_ISOLATION PGDs are 8k. Flip bit 12 to switch between the two
* halves:
*/
#define PTI_USER_PGTABLE_BIT PAGE_SHIFT
@@ -160,7 +165,7 @@ For 32-bit we have the following conventions - kernel is built with
.macro ADJUST_KERNEL_CR3 reg:req
ALTERNATIVE "", "SET_NOFLUSH_BIT \reg", X86_FEATURE_PCID
- /* Clear PCID and "PAGE_TABLE_ISOLATION bit", point CR3 at kernel pagetables: */
+ /* Clear PCID and "MITIGATION_PAGE_TABLE_ISOLATION bit", point CR3 at kernel pagetables: */
andq $(~PTI_USER_PGTABLE_AND_PCID_MASK), \reg
.endm
@@ -173,7 +178,7 @@ For 32-bit we have the following conventions - kernel is built with
.endm
#define THIS_CPU_user_pcid_flush_mask \
- PER_CPU_VAR(cpu_tlbstate) + TLB_STATE_user_pcid_flush_mask
+ PER_CPU_VAR(cpu_tlbstate + TLB_STATE_user_pcid_flush_mask)
.macro SWITCH_TO_USER_CR3 scratch_reg:req scratch_reg2:req
mov %cr3, \scratch_reg
@@ -239,17 +244,19 @@ For 32-bit we have the following conventions - kernel is built with
.Ldone_\@:
.endm
-.macro RESTORE_CR3 scratch_reg:req save_reg:req
+/* Restore CR3 from a kernel context. May restore a user CR3 value. */
+.macro PARANOID_RESTORE_CR3 scratch_reg:req save_reg:req
ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_PTI
- ALTERNATIVE "jmp .Lwrcr3_\@", "", X86_FEATURE_PCID
-
/*
- * KERNEL pages can always resume with NOFLUSH as we do
- * explicit flushes.
+ * If CR3 contained the kernel page tables at the paranoid exception
+ * entry, then there is nothing to restore as CR3 is not modified while
+ * handling the exception.
*/
bt $PTI_USER_PGTABLE_BIT, \save_reg
- jnc .Lnoflush_\@
+ jnc .Lend_\@
+
+ ALTERNATIVE "jmp .Lwrcr3_\@", "", X86_FEATURE_PCID
/*
* Check if there's a pending flush for the user ASID we're
@@ -257,25 +264,17 @@ For 32-bit we have the following conventions - kernel is built with
*/
movq \save_reg, \scratch_reg
andq $(0x7FF), \scratch_reg
- bt \scratch_reg, THIS_CPU_user_pcid_flush_mask
- jnc .Lnoflush_\@
-
btr \scratch_reg, THIS_CPU_user_pcid_flush_mask
- jmp .Lwrcr3_\@
+ jc .Lwrcr3_\@
-.Lnoflush_\@:
SET_NOFLUSH_BIT \save_reg
.Lwrcr3_\@:
- /*
- * The CR3 write could be avoided when not changing its value,
- * but would require a CR3 read *and* a scratch register.
- */
movq \save_reg, %cr3
.Lend_\@:
.endm
-#else /* CONFIG_PAGE_TABLE_ISOLATION=n: */
+#else /* CONFIG_MITIGATION_PAGE_TABLE_ISOLATION=n: */
.macro SWITCH_TO_KERNEL_CR3 scratch_reg:req
.endm
@@ -285,7 +284,7 @@ For 32-bit we have the following conventions - kernel is built with
.endm
.macro SAVE_AND_SWITCH_TO_KERNEL_CR3 scratch_reg:req save_reg:req
.endm
-.macro RESTORE_CR3 scratch_reg:req save_reg:req
+.macro PARANOID_RESTORE_CR3 scratch_reg:req save_reg:req
.endm
#endif
@@ -303,7 +302,7 @@ For 32-bit we have the following conventions - kernel is built with
* Assumes x86_spec_ctrl_{base,current} to have SPEC_CTRL_IBRS set.
*/
.macro IBRS_ENTER save_reg
-#ifdef CONFIG_CPU_IBRS_ENTRY
+#ifdef CONFIG_MITIGATION_IBRS_ENTRY
ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_KERNEL_IBRS
movl $MSR_IA32_SPEC_CTRL, %ecx
@@ -332,7 +331,7 @@ For 32-bit we have the following conventions - kernel is built with
* regs. Must be called after the last RET.
*/
.macro IBRS_EXIT save_reg
-#ifdef CONFIG_CPU_IBRS_ENTRY
+#ifdef CONFIG_MITIGATION_IBRS_ENTRY
ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_KERNEL_IBRS
movl $MSR_IA32_SPEC_CTRL, %ecx
@@ -426,3 +425,63 @@ For 32-bit we have the following conventions - kernel is built with
.endm
#endif /* CONFIG_SMP */
+
+#ifdef CONFIG_X86_64
+
+/* rdi: arg1 ... normal C conventions. rax is saved/restored. */
+.macro THUNK name, func
+SYM_FUNC_START(\name)
+ pushq %rbp
+ movq %rsp, %rbp
+
+ pushq %rdi
+ pushq %rsi
+ pushq %rdx
+ pushq %rcx
+ pushq %rax
+ pushq %r8
+ pushq %r9
+ pushq %r10
+ pushq %r11
+
+ call \func
+
+ popq %r11
+ popq %r10
+ popq %r9
+ popq %r8
+ popq %rax
+ popq %rcx
+ popq %rdx
+ popq %rsi
+ popq %rdi
+ popq %rbp
+ RET
+SYM_FUNC_END(\name)
+ _ASM_NOKPROBE(\name)
+.endm
+
+#else /* CONFIG_X86_32 */
+
+/* put return address in eax (arg1) */
+.macro THUNK name, func, put_ret_addr_in_eax=0
+SYM_CODE_START_NOALIGN(\name)
+ pushl %eax
+ pushl %ecx
+ pushl %edx
+
+ .if \put_ret_addr_in_eax
+ /* Place EIP in the arg1 */
+ movl 3*4(%esp), %eax
+ .endif
+
+ call \func
+ popl %edx
+ popl %ecx
+ popl %eax
+ RET
+ _ASM_NOKPROBE(\name)
+SYM_CODE_END(\name)
+ .endm
+
+#endif
diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c
index 6356060caaf3..6de50b80702e 100644
--- a/arch/x86/entry/common.c
+++ b/arch/x86/entry/common.c
@@ -49,7 +49,7 @@ static __always_inline bool do_syscall_x64(struct pt_regs *regs, int nr)
if (likely(unr < NR_syscalls)) {
unr = array_index_nospec(unr, NR_syscalls);
- regs->ax = sys_call_table[unr](regs);
+ regs->ax = x64_sys_call(regs, unr);
return true;
}
return false;
@@ -66,7 +66,7 @@ static __always_inline bool do_syscall_x32(struct pt_regs *regs, int nr)
if (IS_ENABLED(CONFIG_X86_X32_ABI) && likely(xnr < X32_NR_syscalls)) {
xnr = array_index_nospec(xnr, X32_NR_syscalls);
- regs->ax = x32_sys_call_table[xnr](regs);
+ regs->ax = x32_sys_call(regs, xnr);
return true;
}
return false;
@@ -162,7 +162,7 @@ static __always_inline void do_syscall_32_irqs_on(struct pt_regs *regs, int nr)
if (likely(unr < IA32_NR_syscalls)) {
unr = array_index_nospec(unr, IA32_NR_syscalls);
- regs->ax = ia32_sys_call_table[unr](regs);
+ regs->ax = ia32_sys_call(regs, unr);
} else if (nr != -1) {
regs->ax = __ia32_sys_ni_syscall(regs);
}
@@ -189,7 +189,7 @@ static __always_inline bool int80_is_external(void)
}
/**
- * int80_emulation - 32-bit legacy syscall entry
+ * do_int80_emulation - 32-bit legacy syscall C entry from asm
*
* This entry point can be used by 32-bit and 64-bit programs to perform
* 32-bit system calls. Instances of INT $0x80 can be found inline in
@@ -207,7 +207,7 @@ static __always_inline bool int80_is_external(void)
* eax: system call number
* ebx, ecx, edx, esi, edi, ebp: arg1 - arg 6
*/
-DEFINE_IDTENTRY_RAW(int80_emulation)
+__visible noinstr void do_int80_emulation(struct pt_regs *regs)
{
int nr;
diff --git a/arch/x86/entry/entry.S b/arch/x86/entry/entry.S
index 003379049924..d9feadffa972 100644
--- a/arch/x86/entry/entry.S
+++ b/arch/x86/entry/entry.S
@@ -10,6 +10,8 @@
#include <asm/segment.h>
#include <asm/cache.h>
+#include "calling.h"
+
.pushsection .noinstr.text, "ax"
SYM_FUNC_START(entry_ibpb)
@@ -43,3 +45,4 @@ EXPORT_SYMBOL_GPL(mds_verw_sel);
.popsection
+THUNK warn_thunk_thunk, __warn_thunk
diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
index fba427646805..d3a814efbff6 100644
--- a/arch/x86/entry/entry_32.S
+++ b/arch/x86/entry/entry_32.S
@@ -305,7 +305,7 @@
.macro CHECK_AND_APPLY_ESPFIX
#ifdef CONFIG_X86_ESPFIX32
#define GDT_ESPFIX_OFFSET (GDT_ENTRY_ESPFIX_SS * 8)
-#define GDT_ESPFIX_SS PER_CPU_VAR(gdt_page) + GDT_ESPFIX_OFFSET
+#define GDT_ESPFIX_SS PER_CPU_VAR(gdt_page + GDT_ESPFIX_OFFSET)
ALTERNATIVE "jmp .Lend_\@", "", X86_BUG_ESPFIX
@@ -649,10 +649,6 @@ SYM_CODE_START_LOCAL(asm_\cfunc)
SYM_CODE_END(asm_\cfunc)
.endm
-.macro idtentry_sysvec vector cfunc
- idtentry \vector asm_\cfunc \cfunc has_error_code=0
-.endm
-
/*
* Include the defines which emit the idt entries which are shared
* shared between 32 and 64 bit and emit the __irqentry_text_* markers
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 9bb485977629..1b5be07f8669 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -116,6 +116,7 @@ SYM_INNER_LABEL(entry_SYSCALL_64_after_hwframe, SYM_L_GLOBAL)
/* clobbers %rax, make sure it is after saving the syscall nr */
IBRS_ENTER
UNTRAIN_RET
+ CLEAR_BRANCH_HISTORY
call do_syscall_64 /* returns with IRQs disabled */
@@ -191,7 +192,7 @@ SYM_FUNC_START(__switch_to_asm)
#ifdef CONFIG_STACKPROTECTOR
movq TASK_stack_canary(%rsi), %rbx
- movq %rbx, PER_CPU_VAR(fixed_percpu_data) + FIXED_stack_canary
+ movq %rbx, PER_CPU_VAR(fixed_percpu_data + FIXED_stack_canary)
#endif
/*
@@ -248,7 +249,13 @@ SYM_CODE_START(ret_from_fork_asm)
* and unwind should work normally.
*/
UNWIND_HINT_REGS
+
+#ifdef CONFIG_X86_FRED
+ ALTERNATIVE "jmp swapgs_restore_regs_and_return_to_usermode", \
+ "jmp asm_fred_exit_user", X86_FEATURE_FRED
+#else
jmp swapgs_restore_regs_and_return_to_usermode
+#endif
SYM_CODE_END(ret_from_fork_asm)
.popsection
@@ -371,14 +378,6 @@ SYM_CODE_END(\asmsym)
idtentry \vector asm_\cfunc \cfunc has_error_code=1
.endm
-/*
- * System vectors which invoke their handlers directly and are not
- * going through the regular common device interrupt handling code.
- */
-.macro idtentry_sysvec vector cfunc
- idtentry \vector asm_\cfunc \cfunc has_error_code=0
-.endm
-
/**
* idtentry_mce_db - Macro to generate entry stubs for #MC and #DB
* @vector: Vector number
@@ -563,7 +562,7 @@ SYM_INNER_LABEL(swapgs_restore_regs_and_return_to_usermode, SYM_L_GLOBAL)
#ifdef CONFIG_XEN_PV
ALTERNATIVE "", "jmp xenpv_restore_regs_and_return_to_usermode", X86_FEATURE_XENPV
#endif
-#ifdef CONFIG_PAGE_TABLE_ISOLATION
+#ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
ALTERNATIVE "", "jmp .Lpti_restore_regs_and_return_to_usermode", X86_FEATURE_PTI
#endif
@@ -580,7 +579,7 @@ SYM_INNER_LABEL(swapgs_restore_regs_and_return_to_usermode, SYM_L_GLOBAL)
jnz .Lnative_iret
ud2
-#ifdef CONFIG_PAGE_TABLE_ISOLATION
+#ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
.Lpti_restore_regs_and_return_to_usermode:
POP_REGS pop_rdi=0
@@ -972,14 +971,14 @@ SYM_CODE_START_LOCAL(paranoid_exit)
IBRS_EXIT save_reg=%r15
/*
- * The order of operations is important. RESTORE_CR3 requires
+ * The order of operations is important. PARANOID_RESTORE_CR3 requires
* kernel GSBASE.
*
* NB to anyone to try to optimize this code: this code does
* not execute at all for exceptions from user mode. Those
* exceptions go through error_return instead.
*/
- RESTORE_CR3 scratch_reg=%rax save_reg=%r14
+ PARANOID_RESTORE_CR3 scratch_reg=%rax save_reg=%r14
/* Handle the three GSBASE cases */
ALTERNATIVE "jmp .Lparanoid_exit_checkgs", "", X86_FEATURE_FSGSBASE
@@ -1100,7 +1099,7 @@ SYM_CODE_END(error_return)
*
* Registers:
* %r14: Used to save/restore the CR3 of the interrupted context
- * when PAGE_TABLE_ISOLATION is in use. Do not clobber.
+ * when MITIGATION_PAGE_TABLE_ISOLATION is in use. Do not clobber.
*/
SYM_CODE_START(asm_exc_nmi)
UNWIND_HINT_IRET_ENTRY
@@ -1408,8 +1407,7 @@ end_repeat_nmi:
/* Always restore stashed SPEC_CTRL value (see paranoid_entry) */
IBRS_EXIT save_reg=%r15
- /* Always restore stashed CR3 value (see paranoid_entry) */
- RESTORE_CR3 scratch_reg=%r15 save_reg=%r14
+ PARANOID_RESTORE_CR3 scratch_reg=%r15 save_reg=%r14
/*
* The above invocation of paranoid_entry stored the GSBASE
@@ -1494,3 +1492,63 @@ SYM_CODE_START_NOALIGN(rewind_stack_and_make_dead)
call make_task_dead
SYM_CODE_END(rewind_stack_and_make_dead)
.popsection
+
+/*
+ * This sequence executes branches in order to remove user branch information
+ * from the branch history tracker in the Branch Predictor, therefore removing
+ * user influence on subsequent BTB lookups.
+ *
+ * It should be used on parts prior to Alder Lake. Newer parts should use the
+ * BHI_DIS_S hardware control instead. If a pre-Alder Lake part is being
+ * virtualized on newer hardware the VMM should protect against BHI attacks by
+ * setting BHI_DIS_S for the guests.
+ *
+ * CALLs/RETs are necessary to prevent Loop Stream Detector(LSD) from engaging
+ * and not clearing the branch history. The call tree looks like:
+ *
+ * call 1
+ * call 2
+ * call 2
+ * call 2
+ * call 2
+ * call 2
+ * ret
+ * ret
+ * ret
+ * ret
+ * ret
+ * ret
+ *
+ * This means that the stack is non-constant and ORC can't unwind it with %rsp
+ * alone. Therefore we unconditionally set up the frame pointer, which allows
+ * ORC to unwind properly.
+ *
+ * The alignment is for performance and not for safety, and may be safely
+ * refactored in the future if needed.
+ */
+SYM_FUNC_START(clear_bhb_loop)
+ push %rbp
+ mov %rsp, %rbp
+ movl $5, %ecx
+ ANNOTATE_INTRA_FUNCTION_CALL
+ call 1f
+ jmp 5f
+ .align 64, 0xcc
+ ANNOTATE_INTRA_FUNCTION_CALL
+1: call 2f
+ RET
+ .align 64, 0xcc
+2: movl $5, %eax
+3: jmp 4f
+ nop
+4: sub $1, %eax
+ jnz 3b
+ sub $1, %ecx
+ jnz 1b
+ RET
+5: lfence
+ pop %rbp
+ RET
+SYM_FUNC_END(clear_bhb_loop)
+EXPORT_SYMBOL_GPL(clear_bhb_loop)
+STACK_FRAME_NON_STANDARD(clear_bhb_loop)
diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S
index eabf48c4d4b4..c779046cc3fe 100644
--- a/arch/x86/entry/entry_64_compat.S
+++ b/arch/x86/entry/entry_64_compat.S
@@ -92,6 +92,7 @@ SYM_INNER_LABEL(entry_SYSENTER_compat_after_hwframe, SYM_L_GLOBAL)
IBRS_ENTER
UNTRAIN_RET
+ CLEAR_BRANCH_HISTORY
/*
* SYSENTER doesn't filter flags, so we need to clear NT and AC
@@ -206,6 +207,7 @@ SYM_INNER_LABEL(entry_SYSCALL_compat_after_hwframe, SYM_L_GLOBAL)
IBRS_ENTER
UNTRAIN_RET
+ CLEAR_BRANCH_HISTORY
movq %rsp, %rdi
call do_fast_syscall_32
@@ -276,3 +278,17 @@ SYM_INNER_LABEL(entry_SYSRETL_compat_end, SYM_L_GLOBAL)
ANNOTATE_NOENDBR
int3
SYM_CODE_END(entry_SYSCALL_compat)
+
+/*
+ * int 0x80 is used by 32 bit mode as a system call entry. Normally idt entries
+ * point to C routines, however since this is a system call interface the branch
+ * history needs to be scrubbed to protect against BHI attacks, and that
+ * scrubbing needs to take place in assembly code prior to entering any C
+ * routines.
+ */
+SYM_CODE_START(int80_emulation)
+ ANNOTATE_NOENDBR
+ UNWIND_HINT_FUNC
+ CLEAR_BRANCH_HISTORY
+ jmp do_int80_emulation
+SYM_CODE_END(int80_emulation)
diff --git a/arch/x86/entry/entry_64_fred.S b/arch/x86/entry/entry_64_fred.S
new file mode 100644
index 000000000000..a02bc6f3d2e6
--- /dev/null
+++ b/arch/x86/entry/entry_64_fred.S
@@ -0,0 +1,131 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * The actual FRED entry points.
+ */
+
+#include <linux/export.h>
+
+#include <asm/asm.h>
+#include <asm/fred.h>
+#include <asm/segment.h>
+
+#include "calling.h"
+
+ .code64
+ .section .noinstr.text, "ax"
+
+.macro FRED_ENTER
+ UNWIND_HINT_END_OF_STACK
+ ENDBR
+ PUSH_AND_CLEAR_REGS
+ movq %rsp, %rdi /* %rdi -> pt_regs */
+.endm
+
+.macro FRED_EXIT
+ UNWIND_HINT_REGS
+ POP_REGS
+.endm
+
+/*
+ * The new RIP value that FRED event delivery establishes is
+ * IA32_FRED_CONFIG & ~FFFH for events that occur in ring 3.
+ * Thus the FRED ring 3 entry point must be 4K page aligned.
+ */
+ .align 4096
+
+SYM_CODE_START_NOALIGN(asm_fred_entrypoint_user)
+ FRED_ENTER
+ call fred_entry_from_user
+SYM_INNER_LABEL(asm_fred_exit_user, SYM_L_GLOBAL)
+ FRED_EXIT
+1: ERETU
+
+ _ASM_EXTABLE_TYPE(1b, asm_fred_entrypoint_user, EX_TYPE_ERETU)
+SYM_CODE_END(asm_fred_entrypoint_user)
+
+/*
+ * The new RIP value that FRED event delivery establishes is
+ * (IA32_FRED_CONFIG & ~FFFH) + 256 for events that occur in
+ * ring 0, i.e., asm_fred_entrypoint_user + 256.
+ */
+ .org asm_fred_entrypoint_user + 256, 0xcc
+SYM_CODE_START_NOALIGN(asm_fred_entrypoint_kernel)
+ FRED_ENTER
+ call fred_entry_from_kernel
+ FRED_EXIT
+ ERETS
+SYM_CODE_END(asm_fred_entrypoint_kernel)
+
+#if IS_ENABLED(CONFIG_KVM_INTEL)
+SYM_FUNC_START(asm_fred_entry_from_kvm)
+ push %rbp
+ mov %rsp, %rbp
+
+ UNWIND_HINT_SAVE
+
+ /*
+ * Both IRQ and NMI from VMX can be handled on current task stack
+ * because there is no need to protect from reentrancy and the call
+ * stack leading to this helper is effectively constant and shallow
+ * (relatively speaking). Do the same when FRED is active, i.e., no
+ * need to check current stack level for a stack switch.
+ *
+ * Emulate the FRED-defined redzone and stack alignment.
+ */
+ sub $(FRED_CONFIG_REDZONE_AMOUNT << 6), %rsp
+ and $FRED_STACK_FRAME_RSP_MASK, %rsp
+
+ /*
+ * Start to push a FRED stack frame, which is always 64 bytes:
+ *
+ * +--------+-----------------+
+ * | Bytes | Usage |
+ * +--------+-----------------+
+ * | 63:56 | Reserved |
+ * | 55:48 | Event Data |
+ * | 47:40 | SS + Event Info |
+ * | 39:32 | RSP |
+ * | 31:24 | RFLAGS |
+ * | 23:16 | CS + Aux Info |
+ * | 15:8 | RIP |
+ * | 7:0 | Error Code |
+ * +--------+-----------------+
+ */
+ push $0 /* Reserved, must be 0 */
+ push $0 /* Event data, 0 for IRQ/NMI */
+ push %rdi /* fred_ss handed in by the caller */
+ push %rbp
+ pushf
+ mov $__KERNEL_CS, %rax
+ push %rax
+
+ /*
+ * Unlike the IDT event delivery, FRED _always_ pushes an error code
+ * after pushing the return RIP, thus the CALL instruction CANNOT be
+ * used here to push the return RIP, otherwise there is no chance to
+ * push an error code before invoking the IRQ/NMI handler.
+ *
+ * Use LEA to get the return RIP and push it, then push an error code.
+ */
+ lea 1f(%rip), %rax
+ push %rax /* Return RIP */
+ push $0 /* Error code, 0 for IRQ/NMI */
+
+ PUSH_AND_CLEAR_REGS clear_bp=0 unwind_hint=0
+ movq %rsp, %rdi /* %rdi -> pt_regs */
+ call __fred_entry_from_kvm /* Call the C entry point */
+ POP_REGS
+ ERETS
+1:
+ /*
+ * Objtool doesn't understand what ERETS does, this hint tells it that
+ * yes, we'll reach here and with what stack state. A save/restore pair
+ * isn't strictly needed, but it's the simplest form.
+ */
+ UNWIND_HINT_RESTORE
+ pop %rbp
+ RET
+
+SYM_FUNC_END(asm_fred_entry_from_kvm)
+EXPORT_SYMBOL_GPL(asm_fred_entry_from_kvm);
+#endif
diff --git a/arch/x86/entry/entry_fred.c b/arch/x86/entry/entry_fred.c
new file mode 100644
index 000000000000..ac120cbdaaf2
--- /dev/null
+++ b/arch/x86/entry/entry_fred.c
@@ -0,0 +1,294 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * The FRED specific kernel/user entry functions which are invoked from
+ * assembly code and dispatch to the associated handlers.
+ */
+#include <linux/kernel.h>
+#include <linux/kdebug.h>
+#include <linux/nospec.h>
+
+#include <asm/desc.h>
+#include <asm/fred.h>
+#include <asm/idtentry.h>
+#include <asm/syscall.h>
+#include <asm/trapnr.h>
+#include <asm/traps.h>
+
+/* FRED EVENT_TYPE_OTHER vector numbers */
+#define FRED_SYSCALL 1
+#define FRED_SYSENTER 2
+
+static noinstr void fred_bad_type(struct pt_regs *regs, unsigned long error_code)
+{
+ irqentry_state_t irq_state = irqentry_nmi_enter(regs);
+
+ instrumentation_begin();
+
+ /* Panic on events from a high stack level */
+ if (regs->fred_cs.sl > 0) {
+ pr_emerg("PANIC: invalid or fatal FRED event; event type %u "
+ "vector %u error 0x%lx aux 0x%lx at %04x:%016lx\n",
+ regs->fred_ss.type, regs->fred_ss.vector, regs->orig_ax,
+ fred_event_data(regs), regs->cs, regs->ip);
+ die("invalid or fatal FRED event", regs, regs->orig_ax);
+ panic("invalid or fatal FRED event");
+ } else {
+ unsigned long flags = oops_begin();
+ int sig = SIGKILL;
+
+ pr_alert("BUG: invalid or fatal FRED event; event type %u "
+ "vector %u error 0x%lx aux 0x%lx at %04x:%016lx\n",
+ regs->fred_ss.type, regs->fred_ss.vector, regs->orig_ax,
+ fred_event_data(regs), regs->cs, regs->ip);
+
+ if (__die("Invalid or fatal FRED event", regs, regs->orig_ax))
+ sig = 0;
+
+ oops_end(flags, regs, sig);
+ }
+
+ instrumentation_end();
+ irqentry_nmi_exit(regs, irq_state);
+}
+
+static noinstr void fred_intx(struct pt_regs *regs)
+{
+ switch (regs->fred_ss.vector) {
+ /* Opcode 0xcd, 0x3, NOT INT3 (opcode 0xcc) */
+ case X86_TRAP_BP:
+ return exc_int3(regs);
+
+ /* Opcode 0xcd, 0x4, NOT INTO (opcode 0xce) */
+ case X86_TRAP_OF:
+ return exc_overflow(regs);
+
+#ifdef CONFIG_IA32_EMULATION
+ /* INT80 */
+ case IA32_SYSCALL_VECTOR:
+ if (ia32_enabled())
+ return int80_emulation(regs);
+ fallthrough;
+#endif
+
+ default:
+ return exc_general_protection(regs, 0);
+ }
+}
+
+static __always_inline void fred_other(struct pt_regs *regs)
+{
+ /* The compiler can fold these conditions into a single test */
+ if (likely(regs->fred_ss.vector == FRED_SYSCALL && regs->fred_ss.lm)) {
+ regs->orig_ax = regs->ax;
+ regs->ax = -ENOSYS;
+ do_syscall_64(regs, regs->orig_ax);
+ return;
+ } else if (ia32_enabled() &&
+ likely(regs->fred_ss.vector == FRED_SYSENTER && !regs->fred_ss.lm)) {
+ regs->orig_ax = regs->ax;
+ regs->ax = -ENOSYS;
+ do_fast_syscall_32(regs);
+ return;
+ } else {
+ exc_invalid_op(regs);
+ return;
+ }
+}
+
+#define SYSVEC(_vector, _function) [_vector - FIRST_SYSTEM_VECTOR] = fred_sysvec_##_function
+
+static idtentry_t sysvec_table[NR_SYSTEM_VECTORS] __ro_after_init = {
+ SYSVEC(ERROR_APIC_VECTOR, error_interrupt),
+ SYSVEC(SPURIOUS_APIC_VECTOR, spurious_apic_interrupt),
+ SYSVEC(LOCAL_TIMER_VECTOR, apic_timer_interrupt),
+ SYSVEC(X86_PLATFORM_IPI_VECTOR, x86_platform_ipi),
+
+ SYSVEC(RESCHEDULE_VECTOR, reschedule_ipi),
+ SYSVEC(CALL_FUNCTION_SINGLE_VECTOR, call_function_single),
+ SYSVEC(CALL_FUNCTION_VECTOR, call_function),
+ SYSVEC(REBOOT_VECTOR, reboot),
+
+ SYSVEC(THRESHOLD_APIC_VECTOR, threshold),
+ SYSVEC(DEFERRED_ERROR_VECTOR, deferred_error),
+ SYSVEC(THERMAL_APIC_VECTOR, thermal),
+
+ SYSVEC(IRQ_WORK_VECTOR, irq_work),
+
+ 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),
+};
+
+static bool fred_setup_done __initdata;
+
+void __init fred_install_sysvec(unsigned int sysvec, idtentry_t handler)
+{
+ if (WARN_ON_ONCE(sysvec < FIRST_SYSTEM_VECTOR))
+ return;
+
+ if (WARN_ON_ONCE(fred_setup_done))
+ return;
+
+ if (!WARN_ON_ONCE(sysvec_table[sysvec - FIRST_SYSTEM_VECTOR]))
+ sysvec_table[sysvec - FIRST_SYSTEM_VECTOR] = handler;
+}
+
+static noinstr void fred_handle_spurious_interrupt(struct pt_regs *regs)
+{
+ spurious_interrupt(regs, regs->fred_ss.vector);
+}
+
+void __init fred_complete_exception_setup(void)
+{
+ unsigned int vector;
+
+ for (vector = 0; vector < FIRST_EXTERNAL_VECTOR; vector++)
+ set_bit(vector, system_vectors);
+
+ for (vector = 0; vector < NR_SYSTEM_VECTORS; vector++) {
+ if (sysvec_table[vector])
+ set_bit(vector + FIRST_SYSTEM_VECTOR, system_vectors);
+ else
+ sysvec_table[vector] = fred_handle_spurious_interrupt;
+ }
+ fred_setup_done = true;
+}
+
+static noinstr void fred_extint(struct pt_regs *regs)
+{
+ unsigned int vector = regs->fred_ss.vector;
+ unsigned int index = array_index_nospec(vector - FIRST_SYSTEM_VECTOR,
+ NR_SYSTEM_VECTORS);
+
+ if (WARN_ON_ONCE(vector < FIRST_EXTERNAL_VECTOR))
+ return;
+
+ if (likely(vector >= FIRST_SYSTEM_VECTOR)) {
+ irqentry_state_t state = irqentry_enter(regs);
+
+ instrumentation_begin();
+ sysvec_table[index](regs);
+ instrumentation_end();
+ irqentry_exit(regs, state);
+ } else {
+ common_interrupt(regs, vector);
+ }
+}
+
+static noinstr void fred_hwexc(struct pt_regs *regs, unsigned long error_code)
+{
+ /* Optimize for #PF. That's the only exception which matters performance wise */
+ if (likely(regs->fred_ss.vector == X86_TRAP_PF))
+ return exc_page_fault(regs, error_code);
+
+ switch (regs->fred_ss.vector) {
+ case X86_TRAP_DE: return exc_divide_error(regs);
+ case X86_TRAP_DB: return fred_exc_debug(regs);
+ case X86_TRAP_BR: return exc_bounds(regs);
+ case X86_TRAP_UD: return exc_invalid_op(regs);
+ case X86_TRAP_NM: return exc_device_not_available(regs);
+ case X86_TRAP_DF: return exc_double_fault(regs, error_code);
+ case X86_TRAP_TS: return exc_invalid_tss(regs, error_code);
+ case X86_TRAP_NP: return exc_segment_not_present(regs, error_code);
+ case X86_TRAP_SS: return exc_stack_segment(regs, error_code);
+ case X86_TRAP_GP: return exc_general_protection(regs, error_code);
+ case X86_TRAP_MF: return exc_coprocessor_error(regs);
+ case X86_TRAP_AC: return exc_alignment_check(regs, error_code);
+ case X86_TRAP_XF: return exc_simd_coprocessor_error(regs);
+
+#ifdef CONFIG_X86_MCE
+ case X86_TRAP_MC: return fred_exc_machine_check(regs);
+#endif
+#ifdef CONFIG_INTEL_TDX_GUEST
+ case X86_TRAP_VE: return exc_virtualization_exception(regs);
+#endif
+#ifdef CONFIG_X86_CET
+ case X86_TRAP_CP: return exc_control_protection(regs, error_code);
+#endif
+ default: return fred_bad_type(regs, error_code);
+ }
+
+}
+
+static noinstr void fred_swexc(struct pt_regs *regs, unsigned long error_code)
+{
+ switch (regs->fred_ss.vector) {
+ case X86_TRAP_BP: return exc_int3(regs);
+ case X86_TRAP_OF: return exc_overflow(regs);
+ default: return fred_bad_type(regs, error_code);
+ }
+}
+
+__visible noinstr void fred_entry_from_user(struct pt_regs *regs)
+{
+ unsigned long error_code = regs->orig_ax;
+
+ /* Invalidate orig_ax so that syscall_get_nr() works correctly */
+ regs->orig_ax = -1;
+
+ switch (regs->fred_ss.type) {
+ case EVENT_TYPE_EXTINT:
+ return fred_extint(regs);
+ case EVENT_TYPE_NMI:
+ if (likely(regs->fred_ss.vector == X86_TRAP_NMI))
+ return fred_exc_nmi(regs);
+ break;
+ case EVENT_TYPE_HWEXC:
+ return fred_hwexc(regs, error_code);
+ case EVENT_TYPE_SWINT:
+ return fred_intx(regs);
+ case EVENT_TYPE_PRIV_SWEXC:
+ if (likely(regs->fred_ss.vector == X86_TRAP_DB))
+ return fred_exc_debug(regs);
+ break;
+ case EVENT_TYPE_SWEXC:
+ return fred_swexc(regs, error_code);
+ case EVENT_TYPE_OTHER:
+ return fred_other(regs);
+ default: break;
+ }
+
+ return fred_bad_type(regs, error_code);
+}
+
+__visible noinstr void fred_entry_from_kernel(struct pt_regs *regs)
+{
+ unsigned long error_code = regs->orig_ax;
+
+ /* Invalidate orig_ax so that syscall_get_nr() works correctly */
+ regs->orig_ax = -1;
+
+ switch (regs->fred_ss.type) {
+ case EVENT_TYPE_EXTINT:
+ return fred_extint(regs);
+ case EVENT_TYPE_NMI:
+ if (likely(regs->fred_ss.vector == X86_TRAP_NMI))
+ return fred_exc_nmi(regs);
+ break;
+ case EVENT_TYPE_HWEXC:
+ return fred_hwexc(regs, error_code);
+ case EVENT_TYPE_PRIV_SWEXC:
+ if (likely(regs->fred_ss.vector == X86_TRAP_DB))
+ return fred_exc_debug(regs);
+ break;
+ case EVENT_TYPE_SWEXC:
+ return fred_swexc(regs, error_code);
+ default: break;
+ }
+
+ return fred_bad_type(regs, error_code);
+}
+
+#if IS_ENABLED(CONFIG_KVM_INTEL)
+__visible noinstr void __fred_entry_from_kvm(struct pt_regs *regs)
+{
+ switch (regs->fred_ss.type) {
+ case EVENT_TYPE_EXTINT:
+ return fred_extint(regs);
+ case EVENT_TYPE_NMI:
+ return fred_exc_nmi(regs);
+ default:
+ WARN_ON_ONCE(1);
+ }
+}
+#endif
diff --git a/arch/x86/entry/syscall_32.c b/arch/x86/entry/syscall_32.c
index 8cfc9bc73e7f..c2235bae17ef 100644
--- a/arch/x86/entry/syscall_32.c
+++ b/arch/x86/entry/syscall_32.c
@@ -18,8 +18,25 @@
#include <asm/syscalls_32.h>
#undef __SYSCALL
+/*
+ * The sys_call_table[] is no longer used for system calls, but
+ * kernel/trace/trace_syscalls.c still wants to know the system
+ * call address.
+ */
+#ifdef CONFIG_X86_32
#define __SYSCALL(nr, sym) __ia32_##sym,
-
-__visible const sys_call_ptr_t ia32_sys_call_table[] = {
+const sys_call_ptr_t sys_call_table[] = {
#include <asm/syscalls_32.h>
};
+#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) {
+ #include <asm/syscalls_32.h>
+ default: return __ia32_sys_ni_syscall(regs);
+ }
+};
diff --git a/arch/x86/entry/syscall_64.c b/arch/x86/entry/syscall_64.c
index be120eec1fc9..33b3f09e6f15 100644
--- a/arch/x86/entry/syscall_64.c
+++ b/arch/x86/entry/syscall_64.c
@@ -11,8 +11,23 @@
#include <asm/syscalls_64.h>
#undef __SYSCALL
+/*
+ * The sys_call_table[] is no longer used for system calls, but
+ * kernel/trace/trace_syscalls.c still wants to know the system
+ * call address.
+ */
#define __SYSCALL(nr, sym) __x64_##sym,
-
-asmlinkage const sys_call_ptr_t sys_call_table[] = {
+const sys_call_ptr_t sys_call_table[] = {
#include <asm/syscalls_64.h>
};
+#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) {
+ #include <asm/syscalls_64.h>
+ default: return __x64_sys_ni_syscall(regs);
+ }
+};
diff --git a/arch/x86/entry/syscall_x32.c b/arch/x86/entry/syscall_x32.c
index bdd0e03a1265..03de4a932131 100644
--- a/arch/x86/entry/syscall_x32.c
+++ b/arch/x86/entry/syscall_x32.c
@@ -11,8 +11,12 @@
#include <asm/syscalls_x32.h>
#undef __SYSCALL
-#define __SYSCALL(nr, sym) __x64_##sym,
+#define __SYSCALL(nr, sym) case nr: return __x64_##sym(regs);
-asmlinkage const sys_call_ptr_t x32_sys_call_table[] = {
-#include <asm/syscalls_x32.h>
+long x32_sys_call(const struct pt_regs *regs, unsigned int nr)
+{
+ switch (nr) {
+ #include <asm/syscalls_x32.h>
+ default: return __x64_sys_ni_syscall(regs);
+ }
};
diff --git a/arch/x86/entry/thunk_32.S b/arch/x86/entry/thunk_32.S
index 0103e103a657..da37f42f4549 100644
--- a/arch/x86/entry/thunk_32.S
+++ b/arch/x86/entry/thunk_32.S
@@ -4,33 +4,15 @@
* 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>
- /* put return address in eax (arg1) */
- .macro THUNK name, func, put_ret_addr_in_eax=0
-SYM_CODE_START_NOALIGN(\name)
- pushl %eax
- pushl %ecx
- pushl %edx
+#include <linux/export.h>
+#include <linux/linkage.h>
+#include <asm/asm.h>
- .if \put_ret_addr_in_eax
- /* Place EIP in the arg1 */
- movl 3*4(%esp), %eax
- .endif
+#include "calling.h"
- call \func
- popl %edx
- popl %ecx
- popl %eax
- RET
- _ASM_NOKPROBE(\name)
-SYM_CODE_END(\name)
- .endm
-
- 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)
+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/thunk_64.S b/arch/x86/entry/thunk_64.S
index 416b400f39db..119ebdc3d362 100644
--- a/arch/x86/entry/thunk_64.S
+++ b/arch/x86/entry/thunk_64.S
@@ -9,39 +9,6 @@
#include "calling.h"
#include <asm/asm.h>
- /* rdi: arg1 ... normal C conventions. rax is saved/restored. */
- .macro THUNK name, func
-SYM_FUNC_START(\name)
- pushq %rbp
- movq %rsp, %rbp
-
- pushq %rdi
- pushq %rsi
- pushq %rdx
- pushq %rcx
- pushq %rax
- pushq %r8
- pushq %r9
- pushq %r10
- pushq %r11
-
- call \func
-
- popq %r11
- popq %r10
- popq %r9
- popq %r8
- popq %rax
- popq %rcx
- popq %rdx
- popq %rsi
- popq %rdi
- popq %rbp
- RET
-SYM_FUNC_END(\name)
- _ASM_NOKPROBE(\name)
- .endm
-
THUNK preempt_schedule_thunk, preempt_schedule
THUNK preempt_schedule_notrace_thunk, preempt_schedule_notrace
EXPORT_SYMBOL(preempt_schedule_thunk)
diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile
index b1b8dd1608f7..3d64bcc403cf 100644
--- a/arch/x86/entry/vdso/Makefile
+++ b/arch/x86/entry/vdso/Makefile
@@ -3,13 +3,15 @@
# Building vDSO images for x86.
#
-# Include the generic Makefile to check the built vdso.
+# 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
@@ -18,48 +20,40 @@ OBJECT_FILES_NON_STANDARD := y
# Prevents link failures: __sanitizer_cov_trace_pc() is not linked in.
KCOV_INSTRUMENT := n
-VDSO64-$(CONFIG_X86_64) := y
-VDSOX32-$(CONFIG_X86_X32_ABI) := y
-VDSO32-$(CONFIG_X86_32) := y
-VDSO32-$(CONFIG_IA32_EMULATION) := y
-
-# files to link into the vdso
+# Files to link into the vDSO:
vobjs-y := vdso-note.o vclock_gettime.o vgetcpu.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 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
+# 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
-vdso_img-$(VDSO64-y) += 64
-vdso_img-$(VDSOX32-y) += x32
-vdso_img-$(VDSO32-y) += 32
+# 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
-obj-$(VDSO32-y) += vdso32-setup.o
-OBJECT_FILES_NON_STANDARD_vdso32-setup.o := n
+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 := $(foreach F,$(vobjs-y),$(obj)/$F)
-vobjs32 := $(foreach F,$(vobjs32-y),$(obj)/$F)
+vobjs := $(addprefix $(obj)/, $(vobjs-y))
+vobjs32 := $(addprefix $(obj)/, $(vobjs32-y))
$(obj)/vdso.o: $(obj)/vdso.so
targets += vdso.lds $(vobjs-y)
targets += vdso32/vdso32.lds $(vobjs32-y)
-# Build the vDSO image C files and link them in.
-vdso_img_objs := $(vdso_img-y:%=vdso-image-%.o)
-vdso_img_cfiles := $(vdso_img-y:%=vdso-image-%.c)
-vdso_img_sodbg := $(vdso_img-y:%=vdso%.so.dbg)
-obj-y += $(vdso_img_objs)
-targets += $(vdso_img_cfiles)
-targets += $(vdso_img_sodbg) $(vdso_img-y:%=vdso%.so)
+targets += $(foreach x, 64 x32 32, vdso-image-$(x).c vdso$(x).so vdso$(x).so.dbg)
CPPFLAGS_vdso.lds += -P -C
@@ -87,7 +81,7 @@ CFL := $(PROFILING) -mcmodel=small -fPIC -O2 -fasynchronous-unwind-tables -m64 \
-fno-omit-frame-pointer -foptimize-sibling-calls \
-DDISABLE_BRANCH_PROFILING -DBUILD_VDSO
-ifdef CONFIG_RETPOLINE
+ifdef CONFIG_MITIGATION_RETPOLINE
ifneq ($(RETPOLINE_VDSO_CFLAGS),)
CFL += $(RETPOLINE_VDSO_CFLAGS)
endif
@@ -123,7 +117,7 @@ VDSO_LDFLAGS_vdsox32.lds = -m elf32_x86_64 -soname linux-vdso.so.1 \
vobjx32s-y := $(vobjs-y:.o=-x32.o)
# same thing, but in the output directory
-vobjx32s := $(foreach F,$(vobjx32s-y),$(obj)/$F)
+vobjx32s := $(addprefix $(obj)/, $(vobjx32s-y))
# Convert 64bit object file to x32 for x32 vDSO.
quiet_cmd_x32 = X32 $@
@@ -164,7 +158,7 @@ KBUILD_CFLAGS_32 += $(call cc-option, -foptimize-sibling-calls)
KBUILD_CFLAGS_32 += -fno-omit-frame-pointer
KBUILD_CFLAGS_32 += -DDISABLE_BRANCH_PROFILING
-ifdef CONFIG_RETPOLINE
+ifdef CONFIG_MITIGATION_RETPOLINE
ifneq ($(RETPOLINE_VDSO_CFLAGS),)
KBUILD_CFLAGS_32 += $(RETPOLINE_VDSO_CFLAGS)
endif
@@ -190,5 +184,3 @@ GCOV_PROFILE := n
quiet_cmd_vdso_and_check = VDSO $@
cmd_vdso_and_check = $(cmd_vdso); $(cmd_vdso_check)
-
-clean-files := vdso32.so vdso32.so.dbg vdso64* vdso-image-*.c vdsox32.so*
diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
index 7645730dc228..6d83ceb7f1ba 100644
--- a/arch/x86/entry/vdso/vma.c
+++ b/arch/x86/entry/vdso/vma.c
@@ -274,59 +274,6 @@ up_fail:
return ret;
}
-#ifdef CONFIG_X86_64
-/*
- * Put the vdso above the (randomized) stack with another randomized
- * offset. This way there is no hole in the middle of address space.
- * To save memory make sure it is still in the same PTE as the stack
- * top. This doesn't give that many random bits.
- *
- * Note that this algorithm is imperfect: the distribution of the vdso
- * start address within a PMD is biased toward the end.
- *
- * Only used for the 64-bit and x32 vdsos.
- */
-static unsigned long vdso_addr(unsigned long start, unsigned len)
-{
- unsigned long addr, end;
- unsigned offset;
-
- /*
- * Round up the start address. It can start out unaligned as a result
- * of stack start randomization.
- */
- start = PAGE_ALIGN(start);
-
- /* Round the lowest possible end address up to a PMD boundary. */
- end = (start + len + PMD_SIZE - 1) & PMD_MASK;
- if (end >= DEFAULT_MAP_WINDOW)
- end = DEFAULT_MAP_WINDOW;
- end -= len;
-
- if (end > start) {
- offset = get_random_u32_below(((end - start) >> PAGE_SHIFT) + 1);
- addr = start + (offset << PAGE_SHIFT);
- } else {
- addr = start;
- }
-
- /*
- * Forcibly align the final address in case we have a hardware
- * issue that requires alignment for performance reasons.
- */
- addr = align_vdso_addr(addr);
-
- return addr;
-}
-
-static int map_vdso_randomized(const struct vdso_image *image)
-{
- unsigned long addr = vdso_addr(current->mm->start_stack, image->size-image->sym_vvar_start);
-
- return map_vdso(image, addr);
-}
-#endif
-
int map_vdso_once(const struct vdso_image *image, unsigned long addr)
{
struct mm_struct *mm = current->mm;
@@ -369,7 +316,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
if (!vdso64_enabled)
return 0;
- return map_vdso_randomized(&vdso_image_64);
+ return map_vdso(&vdso_image_64, 0);
}
#ifdef CONFIG_COMPAT
@@ -380,7 +327,7 @@ int compat_arch_setup_additional_pages(struct linux_binprm *bprm,
if (x32) {
if (!vdso64_enabled)
return 0;
- return map_vdso_randomized(&vdso_image_x32);
+ return map_vdso(&vdso_image_x32, 0);
}
#endif
#ifdef CONFIG_IA32_EMULATION
diff --git a/arch/x86/entry/vsyscall/vsyscall_64.c b/arch/x86/entry/vsyscall/vsyscall_64.c
index e0ca8120aea8..a3c0df11d0e6 100644
--- a/arch/x86/entry/vsyscall/vsyscall_64.c
+++ b/arch/x86/entry/vsyscall/vsyscall_64.c
@@ -76,7 +76,7 @@ static void warn_bad_vsyscall(const char *level, struct pt_regs *regs,
if (!show_unhandled_signals)
return;
- printk_ratelimited("%s%s[%d] %s ip:%lx cs:%lx sp:%lx ax:%lx si:%lx di:%lx\n",
+ printk_ratelimited("%s%s[%d] %s ip:%lx cs:%x sp:%lx ax:%lx si:%lx di:%lx\n",
level, current->comm, task_pid_nr(current),
message, regs->ip, regs->cs,
regs->sp, regs->ax, regs->si, regs->di);
diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c
index 81f6d8275b6b..985ef3b47919 100644
--- a/arch/x86/events/amd/core.c
+++ b/arch/x86/events/amd/core.c
@@ -250,7 +250,7 @@ static const u64 amd_perfmon_event_map[PERF_COUNT_HW_MAX] =
/*
* AMD Performance Monitor Family 17h and later:
*/
-static const u64 amd_f17h_perfmon_event_map[PERF_COUNT_HW_MAX] =
+static const u64 amd_zen1_perfmon_event_map[PERF_COUNT_HW_MAX] =
{
[PERF_COUNT_HW_CPU_CYCLES] = 0x0076,
[PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0,
@@ -262,10 +262,39 @@ static const u64 amd_f17h_perfmon_event_map[PERF_COUNT_HW_MAX] =
[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = 0x0187,
};
+static const u64 amd_zen2_perfmon_event_map[PERF_COUNT_HW_MAX] =
+{
+ [PERF_COUNT_HW_CPU_CYCLES] = 0x0076,
+ [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = 0xff60,
+ [PERF_COUNT_HW_CACHE_MISSES] = 0x0964,
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c2,
+ [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c3,
+ [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x00a9,
+};
+
+static const u64 amd_zen4_perfmon_event_map[PERF_COUNT_HW_MAX] =
+{
+ [PERF_COUNT_HW_CPU_CYCLES] = 0x0076,
+ [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = 0xff60,
+ [PERF_COUNT_HW_CACHE_MISSES] = 0x0964,
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c2,
+ [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c3,
+ [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x00a9,
+ [PERF_COUNT_HW_REF_CPU_CYCLES] = 0x100000120,
+};
+
static u64 amd_pmu_event_map(int hw_event)
{
- if (boot_cpu_data.x86 >= 0x17)
- return amd_f17h_perfmon_event_map[hw_event];
+ if (cpu_feature_enabled(X86_FEATURE_ZEN4) || boot_cpu_data.x86 >= 0x1a)
+ return amd_zen4_perfmon_event_map[hw_event];
+
+ if (cpu_feature_enabled(X86_FEATURE_ZEN2) || boot_cpu_data.x86 >= 0x19)
+ return amd_zen2_perfmon_event_map[hw_event];
+
+ if (cpu_feature_enabled(X86_FEATURE_ZEN1))
+ return amd_zen1_perfmon_event_map[hw_event];
return amd_perfmon_event_map[hw_event];
}
@@ -579,7 +608,7 @@ static void amd_pmu_cpu_starting(int cpu)
if (!x86_pmu.amd_nb_constraints)
return;
- nb_id = topology_die_id(cpu);
+ nb_id = topology_amd_node_id(cpu);
WARN_ON_ONCE(nb_id == BAD_APICID);
for_each_online_cpu(i) {
@@ -604,7 +633,6 @@ static void amd_pmu_cpu_dead(int cpu)
kfree(cpuhw->lbr_sel);
cpuhw->lbr_sel = NULL;
- amd_pmu_cpu_reset(cpu);
if (!x86_pmu.amd_nb_constraints)
return;
@@ -905,8 +933,8 @@ static int amd_pmu_v2_handle_irq(struct pt_regs *regs)
if (!status)
goto done;
- /* Read branch records before unfreezing */
- if (status & GLOBAL_STATUS_LBRS_FROZEN) {
+ /* Read branch records */
+ if (x86_pmu.lbr_nr) {
amd_pmu_lbr_read();
status &= ~GLOBAL_STATUS_LBRS_FROZEN;
}
diff --git a/arch/x86/events/amd/lbr.c b/arch/x86/events/amd/lbr.c
index eb31f850841a..5149830c7c4f 100644
--- a/arch/x86/events/amd/lbr.c
+++ b/arch/x86/events/amd/lbr.c
@@ -173,9 +173,11 @@ void amd_pmu_lbr_read(void)
/*
* Check if a branch has been logged; if valid = 0, spec = 0
- * then no branch was recorded
+ * then no branch was recorded; if reserved = 1 then an
+ * erroneous branch was recorded (see Erratum 1452)
*/
- if (!entry.to.split.valid && !entry.to.split.spec)
+ if ((!entry.to.split.valid && !entry.to.split.spec) ||
+ entry.to.split.reserved)
continue;
perf_clear_branch_entry_bitfields(br + out);
@@ -400,10 +402,12 @@ void amd_pmu_lbr_enable_all(void)
wrmsrl(MSR_AMD64_LBR_SELECT, lbr_select);
}
- rdmsrl(MSR_IA32_DEBUGCTLMSR, dbg_ctl);
- rdmsrl(MSR_AMD_DBG_EXTN_CFG, dbg_extn_cfg);
+ 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);
+ }
- wrmsrl(MSR_IA32_DEBUGCTLMSR, dbg_ctl | DEBUGCTLMSR_FREEZE_LBRS_ON_PMI);
+ rdmsrl(MSR_AMD_DBG_EXTN_CFG, dbg_extn_cfg);
wrmsrl(MSR_AMD_DBG_EXTN_CFG, dbg_extn_cfg | DBG_EXTN_CFG_LBRV2EN);
}
@@ -416,10 +420,12 @@ void amd_pmu_lbr_disable_all(void)
return;
rdmsrl(MSR_AMD_DBG_EXTN_CFG, dbg_extn_cfg);
- rdmsrl(MSR_IA32_DEBUGCTLMSR, dbg_ctl);
-
wrmsrl(MSR_AMD_DBG_EXTN_CFG, dbg_extn_cfg & ~DBG_EXTN_CFG_LBRV2EN);
- wrmsrl(MSR_IA32_DEBUGCTLMSR, dbg_ctl & ~DEBUGCTLMSR_FREEZE_LBRS_ON_PMI);
+
+ 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);
+ }
}
__init int amd_pmu_lbr_init(void)
diff --git a/arch/x86/events/amd/uncore.c b/arch/x86/events/amd/uncore.c
index 5bf03c575812..4ccb8fa483e6 100644
--- a/arch/x86/events/amd/uncore.c
+++ b/arch/x86/events/amd/uncore.c
@@ -71,7 +71,7 @@ union amd_uncore_info {
};
struct amd_uncore {
- union amd_uncore_info * __percpu info;
+ union amd_uncore_info __percpu *info;
struct amd_uncore_pmu *pmus;
unsigned int num_pmus;
bool init_done;
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 3804f21ab049..768d1414897f 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -17,6 +17,7 @@
#include <linux/kvm_host.h>
#include <asm/cpufeature.h>
+#include <asm/debugreg.h>
#include <asm/hardirq.h>
#include <asm/intel-family.h>
#include <asm/intel_pt.h>
diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c
index 4b50a3a9818a..326c8cd5aa2d 100644
--- a/arch/x86/events/intel/cstate.c
+++ b/arch/x86/events/intel/cstate.c
@@ -834,7 +834,7 @@ static int __init cstate_init(void)
}
if (has_cstate_pkg) {
- if (topology_max_die_per_package() > 1) {
+ if (topology_max_dies_per_package() > 1) {
err = perf_pmu_register(&cstate_pkg_pmu,
"cstate_die", -1);
} else {
diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
index d49d661ec0a7..e010bfed8417 100644
--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -5,6 +5,7 @@
#include <linux/sched/clock.h>
#include <asm/cpu_entry_area.h>
+#include <asm/debugreg.h>
#include <asm/perf_event.h>
#include <asm/tlbflush.h>
#include <asm/insn.h>
@@ -1236,11 +1237,11 @@ pebs_update_state(bool needed_cb, struct cpu_hw_events *cpuc,
struct pmu *pmu = event->pmu;
/*
- * Make sure we get updated with the first PEBS
- * event. It will trigger also during removal, but
- * that does not hurt:
+ * Make sure we get updated with the first PEBS event.
+ * During removal, ->pebs_data_cfg is still valid for
+ * the last PEBS event. Don't clear it.
*/
- if (cpuc->n_pebs == 1)
+ if ((cpuc->n_pebs == 1) && add)
cpuc->pebs_data_cfg = PEBS_UPDATE_DS_SW;
if (needed_cb != pebs_needs_sched_cb(cpuc)) {
diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
index 7927c0b832fa..258e2cdf28fa 100644
--- a/arch/x86/events/intel/uncore.c
+++ b/arch/x86/events/intel/uncore.c
@@ -1893,7 +1893,7 @@ static int __init intel_uncore_init(void)
return -ENODEV;
__uncore_max_dies =
- topology_max_packages() * topology_max_die_per_package();
+ topology_max_packages() * topology_max_dies_per_package();
id = x86_match_cpu(intel_uncore_match);
if (!id) {
diff --git a/arch/x86/events/intel/uncore_nhmex.c b/arch/x86/events/intel/uncore_nhmex.c
index 56eea2c66cfb..92da8aaa5966 100644
--- a/arch/x86/events/intel/uncore_nhmex.c
+++ b/arch/x86/events/intel/uncore_nhmex.c
@@ -1221,8 +1221,8 @@ void nhmex_uncore_cpu_init(void)
uncore_nhmex = true;
else
nhmex_uncore_mbox.event_descs = wsmex_uncore_mbox_events;
- if (nhmex_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
- nhmex_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
+ if (nhmex_uncore_cbox.num_boxes > topology_num_cores_per_package())
+ nhmex_uncore_cbox.num_boxes = topology_num_cores_per_package();
uncore_msr_uncores = nhmex_msr_uncores;
}
/* end of Nehalem-EX uncore support */
diff --git a/arch/x86/events/intel/uncore_snb.c b/arch/x86/events/intel/uncore_snb.c
index 7fd4334e12a1..9462fd9f3b7a 100644
--- a/arch/x86/events/intel/uncore_snb.c
+++ b/arch/x86/events/intel/uncore_snb.c
@@ -364,8 +364,8 @@ static struct intel_uncore_type *snb_msr_uncores[] = {
void snb_uncore_cpu_init(void)
{
uncore_msr_uncores = snb_msr_uncores;
- if (snb_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
- snb_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
+ if (snb_uncore_cbox.num_boxes > topology_num_cores_per_package())
+ snb_uncore_cbox.num_boxes = topology_num_cores_per_package();
}
static void skl_uncore_msr_init_box(struct intel_uncore_box *box)
@@ -428,8 +428,8 @@ static struct intel_uncore_type *skl_msr_uncores[] = {
void skl_uncore_cpu_init(void)
{
uncore_msr_uncores = skl_msr_uncores;
- if (skl_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
- skl_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
+ if (skl_uncore_cbox.num_boxes > topology_num_cores_per_package())
+ skl_uncore_cbox.num_boxes = topology_num_cores_per_package();
snb_uncore_arb.ops = &skl_uncore_msr_ops;
}
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
index a96496bef678..2eaf0f339849 100644
--- a/arch/x86/events/intel/uncore_snbep.c
+++ b/arch/x86/events/intel/uncore_snbep.c
@@ -1172,8 +1172,8 @@ static struct intel_uncore_type *snbep_msr_uncores[] = {
void snbep_uncore_cpu_init(void)
{
- if (snbep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
- snbep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
+ if (snbep_uncore_cbox.num_boxes > topology_num_cores_per_package())
+ snbep_uncore_cbox.num_boxes = topology_num_cores_per_package();
uncore_msr_uncores = snbep_msr_uncores;
}
@@ -1406,7 +1406,7 @@ static int topology_gidnid_map(int nodeid, u32 gidnid)
*/
for (i = 0; i < 8; i++) {
if (nodeid == GIDNIDMAP(gidnid, i)) {
- if (topology_max_die_per_package() > 1)
+ if (topology_max_dies_per_package() > 1)
die_id = i;
else
die_id = topology_phys_to_logical_pkg(i);
@@ -1845,8 +1845,8 @@ static struct intel_uncore_type *ivbep_msr_uncores[] = {
void ivbep_uncore_cpu_init(void)
{
- if (ivbep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
- ivbep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
+ if (ivbep_uncore_cbox.num_boxes > topology_num_cores_per_package())
+ ivbep_uncore_cbox.num_boxes = topology_num_cores_per_package();
uncore_msr_uncores = ivbep_msr_uncores;
}
@@ -2917,8 +2917,8 @@ static bool hswep_has_limit_sbox(unsigned int device)
void hswep_uncore_cpu_init(void)
{
- if (hswep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
- hswep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
+ if (hswep_uncore_cbox.num_boxes > topology_num_cores_per_package())
+ hswep_uncore_cbox.num_boxes = topology_num_cores_per_package();
/* Detect 6-8 core systems with only two SBOXes */
if (hswep_has_limit_sbox(HSWEP_PCU_DID))
@@ -3280,8 +3280,8 @@ static struct event_constraint bdx_uncore_pcu_constraints[] = {
void bdx_uncore_cpu_init(void)
{
- if (bdx_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
- bdx_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
+ if (bdx_uncore_cbox.num_boxes > topology_num_cores_per_package())
+ bdx_uncore_cbox.num_boxes = topology_num_cores_per_package();
uncore_msr_uncores = bdx_msr_uncores;
/* Detect systems with no SBOXes */
diff --git a/arch/x86/events/rapl.c b/arch/x86/events/rapl.c
index 8d98d468b976..fb2b1961e5a3 100644
--- a/arch/x86/events/rapl.c
+++ b/arch/x86/events/rapl.c
@@ -674,7 +674,7 @@ static const struct attribute_group *rapl_attr_update[] = {
static int __init init_rapl_pmus(void)
{
- int maxdie = topology_max_packages() * topology_max_die_per_package();
+ int maxdie = topology_max_packages() * topology_max_dies_per_package();
size_t size;
size = sizeof(*rapl_pmus) + maxdie * sizeof(struct rapl_pmu *);
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 8f3a4d16bb79..17a71e92a343 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -667,14 +667,14 @@ void hyperv_cleanup(void)
hv_hypercall_pg = NULL;
/* Reset the hypercall page */
- hypercall_msr.as_uint64 = hv_get_register(HV_X64_MSR_HYPERCALL);
+ hypercall_msr.as_uint64 = hv_get_msr(HV_X64_MSR_HYPERCALL);
hypercall_msr.enable = 0;
- hv_set_register(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
+ hv_set_msr(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
/* Reset the TSC page */
- tsc_msr.as_uint64 = hv_get_register(HV_X64_MSR_REFERENCE_TSC);
+ tsc_msr.as_uint64 = hv_get_msr(HV_X64_MSR_REFERENCE_TSC);
tsc_msr.enable = 0;
- hv_set_register(HV_X64_MSR_REFERENCE_TSC, tsc_msr.as_uint64);
+ hv_set_msr(HV_X64_MSR_REFERENCE_TSC, tsc_msr.as_uint64);
}
void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die)
diff --git a/arch/x86/hyperv/hv_spinlock.c b/arch/x86/hyperv/hv_spinlock.c
index 737d6f7a6155..151e851bef09 100644
--- a/arch/x86/hyperv/hv_spinlock.c
+++ b/arch/x86/hyperv/hv_spinlock.c
@@ -16,7 +16,7 @@
#include <asm/paravirt.h>
#include <asm/apic.h>
-static bool __initdata hv_pvspin = true;
+static bool hv_pvspin __initdata = true;
static void hv_qlock_kick(int cpu)
{
@@ -64,6 +64,7 @@ __visible bool hv_vcpu_is_preempted(int vcpu)
{
return false;
}
+
PV_CALLEE_SAVE_REGS_THUNK(hv_vcpu_is_preempted);
void __init hv_init_spinlocks(void)
diff --git a/arch/x86/hyperv/hv_vtl.c b/arch/x86/hyperv/hv_vtl.c
index cf1b78cb2d04..5c7de79423b8 100644
--- a/arch/x86/hyperv/hv_vtl.c
+++ b/arch/x86/hyperv/hv_vtl.c
@@ -12,6 +12,7 @@
#include <asm/i8259.h>
#include <asm/mshyperv.h>
#include <asm/realmode.h>
+#include <../kernel/smpboot.h>
extern struct boot_params boot_params;
static struct real_mode_header hv_vtl_real_mode_header;
@@ -31,8 +32,9 @@ void __init hv_vtl_init_platform(void)
x86_init.timers.timer_init = x86_init_noop;
/* Avoid searching for BIOS MP tables */
- x86_init.mpparse.find_smp_config = x86_init_noop;
- x86_init.mpparse.get_smp_config = x86_init_uint_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_init_noop;
x86_platform.get_wallclock = get_rtc_noop;
x86_platform.set_wallclock = set_rtc_noop;
@@ -64,7 +66,7 @@ static void hv_vtl_ap_entry(void)
((secondary_startup_64_fn)secondary_startup_64)(&boot_params, &boot_params);
}
-static int hv_vtl_bringup_vcpu(u32 target_vp_index, u64 eip_ignored)
+static int hv_vtl_bringup_vcpu(u32 target_vp_index, int cpu, u64 eip_ignored)
{
u64 status;
int ret = 0;
@@ -78,7 +80,9 @@ static int hv_vtl_bringup_vcpu(u32 target_vp_index, u64 eip_ignored)
struct ldttss_desc *ldt;
struct desc_struct *gdt;
- u64 rsp = current->thread.sp;
+ struct task_struct *idle = idle_thread_get(cpu);
+ u64 rsp = (unsigned long)idle->thread.sp;
+
u64 rip = (u64)&hv_vtl_ap_entry;
native_store_gdt(&gdt_ptr);
@@ -205,7 +209,15 @@ static int hv_vtl_apicid_to_vp_id(u32 apic_id)
static int hv_vtl_wakeup_secondary_cpu(u32 apicid, unsigned long start_eip)
{
- int vp_id;
+ int vp_id, cpu;
+
+ /* Find the logical CPU for the APIC ID */
+ for_each_present_cpu(cpu) {
+ if (arch_match_cpu_phys_id(cpu, apicid))
+ break;
+ }
+ if (cpu >= nr_cpu_ids)
+ return -EINVAL;
pr_debug("Bringing up CPU with APIC ID %d in VTL2...\n", apicid);
vp_id = hv_vtl_apicid_to_vp_id(apicid);
@@ -219,7 +231,7 @@ static int hv_vtl_wakeup_secondary_cpu(u32 apicid, unsigned long start_eip)
return -EINVAL;
}
- return hv_vtl_bringup_vcpu(vp_id, start_eip);
+ return hv_vtl_bringup_vcpu(vp_id, cpu, start_eip);
}
int __init hv_vtl_early_init(void)
diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h
index fcd20c6dc7f9..67b68d0d17d1 100644
--- a/arch/x86/include/asm/alternative.h
+++ b/arch/x86/include/asm/alternative.h
@@ -117,7 +117,7 @@ extern void callthunks_patch_builtin_calls(void);
extern void callthunks_patch_module_calls(struct callthunk_sites *sites,
struct module *mod);
extern void *callthunks_translate_call_dest(void *dest);
-extern int x86_call_depth_emit_accounting(u8 **pprog, void *func);
+extern int x86_call_depth_emit_accounting(u8 **pprog, void *func, void *ip);
#else
static __always_inline void callthunks_patch_builtin_calls(void) {}
static __always_inline void
@@ -128,7 +128,7 @@ static __always_inline void *callthunks_translate_call_dest(void *dest)
return dest;
}
static __always_inline int x86_call_depth_emit_accounting(u8 **pprog,
- void *func)
+ void *func, void *ip)
{
return 0;
}
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index 9d159b771dc8..94ce0f7c9d3a 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -46,6 +46,10 @@ extern void x86_32_probe_apic(void);
static inline void x86_32_probe_apic(void) { }
#endif
+extern u32 cpuid_to_apicid[];
+
+#define CPU_ACPIID_INVALID U32_MAX
+
#ifdef CONFIG_X86_LOCAL_APIC
extern int apic_verbosity;
@@ -54,8 +58,6 @@ extern int local_apic_timer_c2_ok;
extern bool apic_is_disabled;
extern unsigned int lapic_timer_period;
-extern u32 cpuid_to_apicid[];
-
extern enum apic_intr_mode_id apic_intr_mode;
enum apic_intr_mode_id {
APIC_PIC,
@@ -169,6 +171,14 @@ extern bool apic_needs_pit(void);
extern void apic_send_IPI_allbutself(unsigned int vector);
+extern void topology_register_apic(u32 apic_id, u32 acpi_id, bool present);
+extern void topology_register_boot_apic(u32 apic_id);
+extern int topology_hotplug_apic(u32 apic_id, u32 acpi_id);
+extern void topology_hotunplug_apic(unsigned int cpu);
+extern void topology_apply_cmdline_limits_early(void);
+extern void topology_init_possible_cpus(void);
+extern void topology_reset_possible_cpus_up(void);
+
#else /* !CONFIG_X86_LOCAL_APIC */
static inline void lapic_shutdown(void) { }
#define local_apic_timer_c2_ok 1
@@ -183,6 +193,8 @@ static inline void apic_intr_mode_init(void) { }
static inline void lapic_assign_system_vectors(void) { }
static inline void lapic_assign_legacy_vector(unsigned int i, bool r) { }
static inline bool apic_needs_pit(void) { return true; }
+static inline void topology_apply_cmdline_limits_early(void) { }
+static inline void topology_init_possible_cpus(void) { }
#endif /* !CONFIG_X86_LOCAL_APIC */
#ifdef CONFIG_X86_X2APIC
@@ -289,16 +301,11 @@ struct apic {
/* Probe, setup and smpboot functions */
int (*probe)(void);
int (*acpi_madt_oem_check)(char *oem_id, char *oem_table_id);
- bool (*apic_id_registered)(void);
- bool (*check_apicid_used)(physid_mask_t *map, u32 apicid);
void (*init_apic_ldr)(void);
- void (*ioapic_phys_id_map)(physid_mask_t *phys_map, physid_mask_t *retmap);
u32 (*cpu_present_to_apicid)(int mps_cpu);
- u32 (*phys_pkg_id)(u32 cpuid_apic, int index_msb);
u32 (*get_apic_id)(u32 id);
- u32 (*set_apic_id)(u32 apicid);
/* wakeup_secondary_cpu */
int (*wakeup_secondary_cpu)(u32 apicid, unsigned long start_eip);
@@ -527,7 +534,6 @@ extern int default_apic_id_valid(u32 apicid);
extern u32 apic_default_calc_apicid(unsigned int cpu);
extern u32 apic_flat_calc_apicid(unsigned int cpu);
-extern void default_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap);
extern u32 default_cpu_present_to_apicid(int mps_cpu);
void apic_send_nmi_to_offline_cpu(unsigned int cpu);
diff --git a/arch/x86/include/asm/asm-prototypes.h b/arch/x86/include/asm/asm-prototypes.h
index b1a98fa38828..25466c4d2134 100644
--- a/arch/x86/include/asm/asm-prototypes.h
+++ b/arch/x86/include/asm/asm-prototypes.h
@@ -12,7 +12,9 @@
#include <asm/special_insns.h>
#include <asm/preempt.h>
#include <asm/asm.h>
+#include <asm/fred.h>
#include <asm/gsseg.h>
+#include <asm/nospec-branch.h>
#ifndef CONFIG_X86_CMPXCHG64
extern void cmpxchg8b_emu(void);
diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h
index fbcfec4dc4cc..ca8eed1d496a 100644
--- a/arch/x86/include/asm/asm.h
+++ b/arch/x86/include/asm/asm.h
@@ -113,6 +113,20 @@
#endif
+#ifndef __ASSEMBLY__
+#ifndef __pic__
+static __always_inline __pure void *rip_rel_ptr(void *p)
+{
+ asm("leaq %c1(%%rip), %0" : "=r"(p) : "i"(p));
+
+ return p;
+}
+#define RIP_REL_REF(var) (*(typeof(&(var)))rip_rel_ptr(&(var)))
+#else
+#define RIP_REL_REF(var) (var)
+#endif
+#endif
+
/*
* Macros to generate condition code outputs from inline assembly,
* The output operand must be type "bool".
diff --git a/arch/x86/include/asm/barrier.h b/arch/x86/include/asm/barrier.h
index 0216f63a366b..fe1e7e3cc844 100644
--- a/arch/x86/include/asm/barrier.h
+++ b/arch/x86/include/asm/barrier.h
@@ -33,7 +33,7 @@
* Returns:
* 0 - (index < size)
*/
-static inline unsigned long array_index_mask_nospec(unsigned long index,
+static __always_inline unsigned long array_index_mask_nospec(unsigned long index,
unsigned long size)
{
unsigned long mask;
diff --git a/arch/x86/include/asm/boot.h b/arch/x86/include/asm/boot.h
index a38cc0afc90a..a3e0be0470a4 100644
--- a/arch/x86/include/asm/boot.h
+++ b/arch/x86/include/asm/boot.h
@@ -81,6 +81,7 @@
#ifndef __ASSEMBLY__
extern unsigned int output_len;
+extern const unsigned long kernel_text_size;
extern const unsigned long kernel_total_size;
unsigned long decompress_kernel(unsigned char *outbuf, unsigned long virt_addr,
diff --git a/arch/x86/include/asm/coco.h b/arch/x86/include/asm/coco.h
index 76c310b19b11..c086699b0d0c 100644
--- a/arch/x86/include/asm/coco.h
+++ b/arch/x86/include/asm/coco.h
@@ -2,6 +2,7 @@
#ifndef _ASM_X86_COCO_H
#define _ASM_X86_COCO_H
+#include <asm/asm.h>
#include <asm/types.h>
enum cc_vendor {
@@ -12,9 +13,16 @@ enum cc_vendor {
#ifdef CONFIG_ARCH_HAS_CC_PLATFORM
extern enum cc_vendor cc_vendor;
-void cc_set_mask(u64 mask);
+extern u64 cc_mask;
+
+static inline void cc_set_mask(u64 mask)
+{
+ RIP_REL_REF(cc_mask) = mask;
+}
+
u64 cc_mkenc(u64 val);
u64 cc_mkdec(u64 val);
+void cc_random_init(void);
#else
#define cc_vendor (CC_VENDOR_NONE)
@@ -27,6 +35,7 @@ static inline u64 cc_mkdec(u64 val)
{
return val;
}
+static inline void cc_random_init(void) { }
#endif
#endif /* _ASM_X86_COCO_H */
diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h
index f8f9a9b79395..aa30fd8cad7f 100644
--- a/arch/x86/include/asm/cpu.h
+++ b/arch/x86/include/asm/cpu.h
@@ -9,18 +9,10 @@
#include <linux/percpu.h>
#include <asm/ibt.h>
-#ifdef CONFIG_SMP
-
-extern void prefill_possible_map(void);
-
-#else /* CONFIG_SMP */
-
-static inline void prefill_possible_map(void) {}
-
+#ifndef CONFIG_SMP
#define cpu_physical_id(cpu) boot_cpu_physical_apicid
#define cpu_acpi_id(cpu) 0
#define safe_smp_processor_id() 0
-
#endif /* CONFIG_SMP */
#ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index a1273698fc43..686e92d2663e 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -33,6 +33,8 @@ enum cpuid_leafs
CPUID_7_EDX,
CPUID_8000_001F_EAX,
CPUID_8000_0021_EAX,
+ CPUID_LNX_5,
+ NR_CPUID_WORDS,
};
#define X86_CAP_FMT_NUM "%d:%d"
@@ -91,8 +93,9 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 18, feature_bit) || \
CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 19, feature_bit) || \
CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 20, feature_bit) || \
+ CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 21, feature_bit) || \
REQUIRED_MASK_CHECK || \
- BUILD_BUG_ON_ZERO(NCAPINTS != 21))
+ BUILD_BUG_ON_ZERO(NCAPINTS != 22))
#define DISABLED_MASK_BIT_SET(feature_bit) \
( CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 0, feature_bit) || \
@@ -116,8 +119,9 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 18, feature_bit) || \
CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 19, feature_bit) || \
CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 20, feature_bit) || \
+ CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 21, feature_bit) || \
DISABLED_MASK_CHECK || \
- BUILD_BUG_ON_ZERO(NCAPINTS != 21))
+ BUILD_BUG_ON_ZERO(NCAPINTS != 22))
#define cpu_has(c, bit) \
(__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index 2b62cdd8dd12..3c7434329661 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -13,7 +13,7 @@
/*
* Defines x86 CPU feature bits
*/
-#define NCAPINTS 21 /* N 32-bit words worth of info */
+#define NCAPINTS 22 /* N 32-bit words worth of info */
#define NBUGINTS 2 /* N 32-bit bug flags */
/*
@@ -324,7 +324,9 @@
#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 */
@@ -440,6 +442,7 @@
#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 */
@@ -457,6 +460,18 @@
#define X86_FEATURE_SRSO_NO (20*32+29) /* "" CPU is not affected by SRSO */
/*
+ * Extended auxiliary flags: Linux defined - for features scattered in various
+ * CPUID levels like 0x80000022, etc and Linux defined features.
+ *
+ * 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 */
+
+/*
* BUG word(s)
*/
#define X86_BUG(x) (NCAPINTS*32 + (x))
@@ -503,4 +518,6 @@
/* 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 */
#endif /* _ASM_X86_CPUFEATURES_H */
diff --git a/arch/x86/include/asm/cpuid.h b/arch/x86/include/asm/cpuid.h
index 9bee3e7bf973..6b122a31da06 100644
--- a/arch/x86/include/asm/cpuid.h
+++ b/arch/x86/include/asm/cpuid.h
@@ -127,6 +127,42 @@ static inline unsigned int cpuid_edx(unsigned int op)
return edx;
}
+static inline void __cpuid_read(unsigned int leaf, unsigned int subleaf, u32 *regs)
+{
+ regs[CPUID_EAX] = leaf;
+ regs[CPUID_ECX] = subleaf;
+ __cpuid(regs + CPUID_EAX, regs + CPUID_EBX, regs + CPUID_ECX, regs + CPUID_EDX);
+}
+
+#define cpuid_subleaf(leaf, subleaf, regs) { \
+ static_assert(sizeof(*(regs)) == 16); \
+ __cpuid_read(leaf, subleaf, (u32 *)(regs)); \
+}
+
+#define cpuid_leaf(leaf, regs) { \
+ static_assert(sizeof(*(regs)) == 16); \
+ __cpuid_read(leaf, 0, (u32 *)(regs)); \
+}
+
+static inline void __cpuid_read_reg(unsigned int leaf, unsigned int subleaf,
+ enum cpuid_regs_idx regidx, u32 *reg)
+{
+ u32 regs[4];
+
+ __cpuid_read(leaf, subleaf, regs);
+ *reg = regs[regidx];
+}
+
+#define cpuid_subleaf_reg(leaf, subleaf, regidx, reg) { \
+ static_assert(sizeof(*(reg)) == 4); \
+ __cpuid_read_reg(leaf, subleaf, regidx, (u32 *)(reg)); \
+}
+
+#define cpuid_leaf_reg(leaf, regidx, reg) { \
+ static_assert(sizeof(*(reg)) == 4); \
+ __cpuid_read_reg(leaf, 0, regidx, (u32 *)(reg)); \
+}
+
static __always_inline bool cpuid_function_is_indexed(u32 function)
{
switch (function) {
diff --git a/arch/x86/include/asm/crash_core.h b/arch/x86/include/asm/crash_reserve.h
index 76af98f4e801..7835b2cdff04 100644
--- a/arch/x86/include/asm/crash_core.h
+++ b/arch/x86/include/asm/crash_reserve.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _X86_CRASH_CORE_H
-#define _X86_CRASH_CORE_H
+#ifndef _X86_CRASH_RESERVE_H
+#define _X86_CRASH_RESERVE_H
/* 16M alignment for crash kernel regions */
#define CRASH_ALIGN SZ_16M
@@ -39,4 +39,6 @@ static inline unsigned long crash_low_size_default(void)
#endif
}
-#endif /* _X86_CRASH_CORE_H */
+#define HAVE_ARCH_ADD_CRASH_RES_TO_IOMEM_EARLY
+
+#endif /* _X86_CRASH_RESERVE_H */
diff --git a/arch/x86/include/asm/current.h b/arch/x86/include/asm/current.h
index dd4b67101bb7..bf5953883ec3 100644
--- a/arch/x86/include/asm/current.h
+++ b/arch/x86/include/asm/current.h
@@ -18,7 +18,7 @@ struct pcpu_hot {
struct task_struct *current_task;
int preempt_count;
int cpu_number;
-#ifdef CONFIG_CALL_DEPTH_TRACKING
+#ifdef CONFIG_MITIGATION_CALL_DEPTH_TRACKING
u64 call_depth;
#endif
unsigned long top_of_stack;
@@ -37,8 +37,15 @@ static_assert(sizeof(struct pcpu_hot) == 64);
DECLARE_PER_CPU_ALIGNED(struct pcpu_hot, pcpu_hot);
+/* const-qualified alias to pcpu_hot, aliased by linker. */
+DECLARE_PER_CPU_ALIGNED(const struct pcpu_hot __percpu_seg_override,
+ const_pcpu_hot);
+
static __always_inline struct task_struct *get_current(void)
{
+ if (IS_ENABLED(CONFIG_USE_X86_SEG_SUPPORT))
+ return this_cpu_read_const(const_pcpu_hot.current_task);
+
return this_cpu_read_stable(pcpu_hot.current_task);
}
diff --git a/arch/x86/include/asm/debugreg.h b/arch/x86/include/asm/debugreg.h
index 0cec92c430cc..fdbbbfec745a 100644
--- a/arch/x86/include/asm/debugreg.h
+++ b/arch/x86/include/asm/debugreg.h
@@ -5,7 +5,9 @@
#include <linux/bug.h>
#include <linux/percpu.h>
#include <uapi/asm/debugreg.h>
+
#include <asm/cpufeature.h>
+#include <asm/msr.h>
DECLARE_PER_CPU(unsigned long, cpu_dr7);
@@ -159,4 +161,26 @@ static inline unsigned long amd_get_dr_addr_mask(unsigned int dr)
}
#endif
+static inline unsigned long get_debugctlmsr(void)
+{
+ unsigned long debugctlmsr = 0;
+
+#ifndef CONFIG_X86_DEBUGCTLMSR
+ if (boot_cpu_data.x86 < 6)
+ return 0;
+#endif
+ rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctlmsr);
+
+ return debugctlmsr;
+}
+
+static inline void update_debugctlmsr(unsigned long debugctlmsr)
+{
+#ifndef CONFIG_X86_DEBUGCTLMSR
+ if (boot_cpu_data.x86 < 6)
+ return;
+#endif
+ wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctlmsr);
+}
+
#endif /* _ASM_X86_DEBUGREG_H */
diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h
index ab97b22ac04a..62dc9f59ea76 100644
--- a/arch/x86/include/asm/desc.h
+++ b/arch/x86/include/asm/desc.h
@@ -46,6 +46,7 @@ struct gdt_page {
} __attribute__((aligned(PAGE_SIZE)));
DECLARE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page);
+DECLARE_INIT_PER_CPU(gdt_page);
/* Provide the original GDT */
static inline struct desc_struct *get_cpu_gdt_rw(unsigned int cpu)
@@ -402,8 +403,6 @@ static inline void set_desc_limit(struct desc_struct *desc, unsigned long limit)
desc->limit1 = (limit >> 16) & 0xf;
}
-void alloc_intr_gate(unsigned int n, const void *addr);
-
static inline void init_idt_data(struct idt_data *data, unsigned int n,
const void *addr)
{
diff --git a/arch/x86/include/asm/disabled-features.h b/arch/x86/include/asm/disabled-features.h
index 702d93fdd10e..c492bdc97b05 100644
--- a/arch/x86/include/asm/disabled-features.h
+++ b/arch/x86/include/asm/disabled-features.h
@@ -44,32 +44,32 @@
# define DISABLE_LA57 (1<<(X86_FEATURE_LA57 & 31))
#endif
-#ifdef CONFIG_PAGE_TABLE_ISOLATION
+#ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
# define DISABLE_PTI 0
#else
# define DISABLE_PTI (1 << (X86_FEATURE_PTI & 31))
#endif
-#ifdef CONFIG_RETPOLINE
+#ifdef CONFIG_MITIGATION_RETPOLINE
# define DISABLE_RETPOLINE 0
#else
# define DISABLE_RETPOLINE ((1 << (X86_FEATURE_RETPOLINE & 31)) | \
(1 << (X86_FEATURE_RETPOLINE_LFENCE & 31)))
#endif
-#ifdef CONFIG_RETHUNK
+#ifdef CONFIG_MITIGATION_RETHUNK
# define DISABLE_RETHUNK 0
#else
# define DISABLE_RETHUNK (1 << (X86_FEATURE_RETHUNK & 31))
#endif
-#ifdef CONFIG_CPU_UNRET_ENTRY
+#ifdef CONFIG_MITIGATION_UNRET_ENTRY
# define DISABLE_UNRET 0
#else
# define DISABLE_UNRET (1 << (X86_FEATURE_UNRET & 31))
#endif
-#ifdef CONFIG_CALL_DEPTH_TRACKING
+#ifdef CONFIG_MITIGATION_CALL_DEPTH_TRACKING
# define DISABLE_CALL_DEPTH_TRACKING 0
#else
# define DISABLE_CALL_DEPTH_TRACKING (1 << (X86_FEATURE_CALL_DEPTH & 31))
@@ -117,6 +117,18 @@
#define DISABLE_IBT (1 << (X86_FEATURE_IBT & 31))
#endif
+#ifdef CONFIG_X86_FRED
+# define DISABLE_FRED 0
+#else
+# define DISABLE_FRED (1 << (X86_FEATURE_FRED & 31))
+#endif
+
+#ifdef CONFIG_KVM_AMD_SEV
+#define DISABLE_SEV_SNP 0
+#else
+#define DISABLE_SEV_SNP (1 << (X86_FEATURE_SEV_SNP & 31))
+#endif
+
/*
* Make sure to add features to the correct mask
*/
@@ -133,7 +145,7 @@
#define DISABLED_MASK10 0
#define DISABLED_MASK11 (DISABLE_RETPOLINE|DISABLE_RETHUNK|DISABLE_UNRET| \
DISABLE_CALL_DEPTH_TRACKING|DISABLE_USER_SHSTK)
-#define DISABLED_MASK12 (DISABLE_LAM)
+#define DISABLED_MASK12 (DISABLE_FRED|DISABLE_LAM)
#define DISABLED_MASK13 0
#define DISABLED_MASK14 0
#define DISABLED_MASK15 0
@@ -141,8 +153,9 @@
DISABLE_ENQCMD)
#define DISABLED_MASK17 0
#define DISABLED_MASK18 (DISABLE_IBT)
-#define DISABLED_MASK19 0
+#define DISABLED_MASK19 (DISABLE_SEV_SNP)
#define DISABLED_MASK20 0
-#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 21)
+#define DISABLED_MASK21 0
+#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 22)
#endif /* _ASM_X86_DISABLED_FEATURES_H */
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index c4555b269a1b..1dc600fa3ba5 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -143,15 +143,6 @@ extern void efi_free_boot_services(void);
void arch_efi_call_virt_setup(void);
void arch_efi_call_virt_teardown(void);
-/* kexec external ABI */
-struct efi_setup_data {
- u64 fw_vendor;
- u64 __unused;
- u64 tables;
- u64 smbios;
- u64 reserved[8];
-};
-
extern u64 efi_setup;
#ifdef CONFIG_EFI
@@ -418,8 +409,9 @@ extern int __init efi_memmap_split_count(efi_memory_desc_t *md,
extern void __init efi_memmap_insert(struct efi_memory_map *old_memmap,
void *buf, struct efi_mem_range *mem);
-#define arch_ima_efi_boot_mode \
- ({ extern struct boot_params boot_params; boot_params.secure_boot; })
+extern enum efi_secureboot_mode __x86_ima_efi_boot_mode(void);
+
+#define arch_ima_efi_boot_mode __x86_ima_efi_boot_mode()
#ifdef CONFIG_EFI_RUNTIME_MAP
int efi_get_runtime_map_size(void);
diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
index 1e16bd5ac781..1fb83d47711f 100644
--- a/arch/x86/include/asm/elf.h
+++ b/arch/x86/include/asm/elf.h
@@ -392,5 +392,4 @@ struct va_alignment {
} ____cacheline_aligned;
extern struct va_alignment va_align;
-extern unsigned long align_vdso_addr(unsigned long);
#endif /* _ASM_X86_ELF_H */
diff --git a/arch/x86/include/asm/extable_fixup_types.h b/arch/x86/include/asm/extable_fixup_types.h
index fe6312045042..7acf0383be80 100644
--- a/arch/x86/include/asm/extable_fixup_types.h
+++ b/arch/x86/include/asm/extable_fixup_types.h
@@ -64,6 +64,8 @@
#define EX_TYPE_UCOPY_LEN4 (EX_TYPE_UCOPY_LEN | EX_DATA_IMM(4))
#define EX_TYPE_UCOPY_LEN8 (EX_TYPE_UCOPY_LEN | EX_DATA_IMM(8))
-#define EX_TYPE_ZEROPAD 20 /* longword load with zeropad on fault */
+#define EX_TYPE_ZEROPAD 20 /* longword load with zeropad on fault */
+
+#define EX_TYPE_ERETU 21
#endif
diff --git a/arch/x86/include/asm/fpu/sched.h b/arch/x86/include/asm/fpu/sched.h
index ca6e5e5f16b2..c485f1944c5f 100644
--- a/arch/x86/include/asm/fpu/sched.h
+++ b/arch/x86/include/asm/fpu/sched.h
@@ -37,10 +37,12 @@ extern void fpu_flush_thread(void);
* The FPU context is only stored/restored for a user task and
* PF_KTHREAD is used to distinguish between kernel and user threads.
*/
-static inline void switch_fpu_prepare(struct fpu *old_fpu, int cpu)
+static inline void switch_fpu_prepare(struct task_struct *old, int cpu)
{
if (cpu_feature_enabled(X86_FEATURE_FPU) &&
- !(current->flags & (PF_KTHREAD | PF_USER_WORKER))) {
+ !(old->flags & (PF_KTHREAD | PF_USER_WORKER))) {
+ struct fpu *old_fpu = &old->thread.fpu;
+
save_fpregs_to_fpstate(old_fpu);
/*
* The save operation preserved register state, so the
@@ -60,10 +62,10 @@ static inline void switch_fpu_prepare(struct fpu *old_fpu, int cpu)
* Delay loading of the complete FPU state until the return to userland.
* PKRU is handled separately.
*/
-static inline void switch_fpu_finish(void)
+static inline void switch_fpu_finish(struct task_struct *new)
{
if (cpu_feature_enabled(X86_FEATURE_FPU))
- set_thread_flag(TIF_NEED_FPU_LOAD);
+ set_tsk_thread_flag(new, TIF_NEED_FPU_LOAD);
}
#endif /* _ASM_X86_FPU_SCHED_H */
diff --git a/arch/x86/include/asm/fred.h b/arch/x86/include/asm/fred.h
new file mode 100644
index 000000000000..e86c7ba32435
--- /dev/null
+++ b/arch/x86/include/asm/fred.h
@@ -0,0 +1,97 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Macros for Flexible Return and Event Delivery (FRED)
+ */
+
+#ifndef ASM_X86_FRED_H
+#define ASM_X86_FRED_H
+
+#include <linux/const.h>
+
+#include <asm/asm.h>
+#include <asm/trapnr.h>
+
+/*
+ * FRED event return instruction opcodes for ERET{S,U}; supported in
+ * binutils >= 2.41.
+ */
+#define ERETS _ASM_BYTES(0xf2,0x0f,0x01,0xca)
+#define ERETU _ASM_BYTES(0xf3,0x0f,0x01,0xca)
+
+/*
+ * RSP is aligned to a 64-byte boundary before used to push a new stack frame
+ */
+#define FRED_STACK_FRAME_RSP_MASK _AT(unsigned long, (~0x3f))
+
+/*
+ * Used for the return address for call emulation during code patching,
+ * and measured in 64-byte cache lines.
+ */
+#define FRED_CONFIG_REDZONE_AMOUNT 1
+#define FRED_CONFIG_REDZONE (_AT(unsigned long, FRED_CONFIG_REDZONE_AMOUNT) << 6)
+#define FRED_CONFIG_INT_STKLVL(l) (_AT(unsigned long, l) << 9)
+#define FRED_CONFIG_ENTRYPOINT(p) _AT(unsigned long, (p))
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_X86_FRED
+#include <linux/kernel.h>
+
+#include <asm/ptrace.h>
+
+struct fred_info {
+ /* Event data: CR2, DR6, ... */
+ unsigned long edata;
+ unsigned long resv;
+};
+
+/* Full format of the FRED stack frame */
+struct fred_frame {
+ struct pt_regs regs;
+ struct fred_info info;
+};
+
+static __always_inline struct fred_info *fred_info(struct pt_regs *regs)
+{
+ return &container_of(regs, struct fred_frame, regs)->info;
+}
+
+static __always_inline unsigned long fred_event_data(struct pt_regs *regs)
+{
+ return fred_info(regs)->edata;
+}
+
+void asm_fred_entrypoint_user(void);
+void asm_fred_entrypoint_kernel(void);
+void asm_fred_entry_from_kvm(struct fred_ss);
+
+__visible void fred_entry_from_user(struct pt_regs *regs);
+__visible void fred_entry_from_kernel(struct pt_regs *regs);
+__visible void __fred_entry_from_kvm(struct pt_regs *regs);
+
+/* Can be called from noinstr code, thus __always_inline */
+static __always_inline void fred_entry_from_kvm(unsigned int type, unsigned int vector)
+{
+ struct fred_ss ss = {
+ .ss =__KERNEL_DS,
+ .type = type,
+ .vector = vector,
+ .nmi = type == EVENT_TYPE_NMI,
+ .lm = 1,
+ };
+
+ asm_fred_entry_from_kvm(ss);
+}
+
+void cpu_init_fred_exceptions(void);
+void fred_complete_exception_setup(void);
+
+#else /* CONFIG_X86_FRED */
+static __always_inline unsigned long fred_event_data(struct pt_regs *regs) { return 0; }
+static inline void cpu_init_fred_exceptions(void) { }
+static inline void fred_complete_exception_setup(void) { }
+static __always_inline void fred_entry_from_kvm(unsigned int type, unsigned int vector) { }
+#endif /* CONFIG_X86_FRED */
+#endif /* !__ASSEMBLY__ */
+
+#endif /* ASM_X86_FRED_H */
diff --git a/arch/x86/include/asm/fsgsbase.h b/arch/x86/include/asm/fsgsbase.h
index 35cff5f2becf..9e7e8ca8e299 100644
--- a/arch/x86/include/asm/fsgsbase.h
+++ b/arch/x86/include/asm/fsgsbase.h
@@ -6,7 +6,7 @@
#ifdef CONFIG_X86_64
-#include <asm/msr-index.h>
+#include <asm/msr.h>
/*
* Read/write a task's FSBASE or GSBASE. This returns the value that
diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h
index 66837b8c67f1..fbc7722b87d1 100644
--- a/arch/x86/include/asm/hardirq.h
+++ b/arch/x86/include/asm/hardirq.h
@@ -15,7 +15,7 @@ typedef struct {
unsigned int irq_spurious_count;
unsigned int icr_read_retry_count;
#endif
-#ifdef CONFIG_HAVE_KVM
+#if IS_ENABLED(CONFIG_KVM)
unsigned int kvm_posted_intr_ipis;
unsigned int kvm_posted_intr_wakeup_ipis;
unsigned int kvm_posted_intr_nested_ipis;
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index b02c3cd3c0f6..edebf1020e04 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -16,8 +16,6 @@
#include <asm/irq_vectors.h>
-#define IRQ_MATRIX_BITS NR_VECTORS
-
#ifndef __ASSEMBLY__
#include <linux/percpu.h>
diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h
index 2ff26f53cd62..3787d26810c1 100644
--- a/arch/x86/include/asm/hyperv-tlfs.h
+++ b/arch/x86/include/asm/hyperv-tlfs.h
@@ -182,7 +182,7 @@ enum hv_isolation_type {
#define HV_X64_MSR_HYPERCALL 0x40000001
/* MSR used to provide vcpu index */
-#define HV_REGISTER_VP_INDEX 0x40000002
+#define HV_X64_MSR_VP_INDEX 0x40000002
/* MSR used to reset the guest OS. */
#define HV_X64_MSR_RESET 0x40000003
@@ -191,10 +191,10 @@ enum hv_isolation_type {
#define HV_X64_MSR_VP_RUNTIME 0x40000010
/* MSR used to read the per-partition time reference counter */
-#define HV_REGISTER_TIME_REF_COUNT 0x40000020
+#define HV_X64_MSR_TIME_REF_COUNT 0x40000020
/* A partition's reference time stamp counter (TSC) page */
-#define HV_REGISTER_REFERENCE_TSC 0x40000021
+#define HV_X64_MSR_REFERENCE_TSC 0x40000021
/* MSR used to retrieve the TSC frequency */
#define HV_X64_MSR_TSC_FREQUENCY 0x40000022
@@ -209,61 +209,61 @@ enum hv_isolation_type {
#define HV_X64_MSR_VP_ASSIST_PAGE 0x40000073
/* Define synthetic interrupt controller model specific registers. */
-#define HV_REGISTER_SCONTROL 0x40000080
-#define HV_REGISTER_SVERSION 0x40000081
-#define HV_REGISTER_SIEFP 0x40000082
-#define HV_REGISTER_SIMP 0x40000083
-#define HV_REGISTER_EOM 0x40000084
-#define HV_REGISTER_SINT0 0x40000090
-#define HV_REGISTER_SINT1 0x40000091
-#define HV_REGISTER_SINT2 0x40000092
-#define HV_REGISTER_SINT3 0x40000093
-#define HV_REGISTER_SINT4 0x40000094
-#define HV_REGISTER_SINT5 0x40000095
-#define HV_REGISTER_SINT6 0x40000096
-#define HV_REGISTER_SINT7 0x40000097
-#define HV_REGISTER_SINT8 0x40000098
-#define HV_REGISTER_SINT9 0x40000099
-#define HV_REGISTER_SINT10 0x4000009A
-#define HV_REGISTER_SINT11 0x4000009B
-#define HV_REGISTER_SINT12 0x4000009C
-#define HV_REGISTER_SINT13 0x4000009D
-#define HV_REGISTER_SINT14 0x4000009E
-#define HV_REGISTER_SINT15 0x4000009F
+#define HV_X64_MSR_SCONTROL 0x40000080
+#define HV_X64_MSR_SVERSION 0x40000081
+#define HV_X64_MSR_SIEFP 0x40000082
+#define HV_X64_MSR_SIMP 0x40000083
+#define HV_X64_MSR_EOM 0x40000084
+#define HV_X64_MSR_SINT0 0x40000090
+#define HV_X64_MSR_SINT1 0x40000091
+#define HV_X64_MSR_SINT2 0x40000092
+#define HV_X64_MSR_SINT3 0x40000093
+#define HV_X64_MSR_SINT4 0x40000094
+#define HV_X64_MSR_SINT5 0x40000095
+#define HV_X64_MSR_SINT6 0x40000096
+#define HV_X64_MSR_SINT7 0x40000097
+#define HV_X64_MSR_SINT8 0x40000098
+#define HV_X64_MSR_SINT9 0x40000099
+#define HV_X64_MSR_SINT10 0x4000009A
+#define HV_X64_MSR_SINT11 0x4000009B
+#define HV_X64_MSR_SINT12 0x4000009C
+#define HV_X64_MSR_SINT13 0x4000009D
+#define HV_X64_MSR_SINT14 0x4000009E
+#define HV_X64_MSR_SINT15 0x4000009F
/*
* Define synthetic interrupt controller model specific registers for
* nested hypervisor.
*/
-#define HV_REGISTER_NESTED_SCONTROL 0x40001080
-#define HV_REGISTER_NESTED_SVERSION 0x40001081
-#define HV_REGISTER_NESTED_SIEFP 0x40001082
-#define HV_REGISTER_NESTED_SIMP 0x40001083
-#define HV_REGISTER_NESTED_EOM 0x40001084
-#define HV_REGISTER_NESTED_SINT0 0x40001090
+#define HV_X64_MSR_NESTED_SCONTROL 0x40001080
+#define HV_X64_MSR_NESTED_SVERSION 0x40001081
+#define HV_X64_MSR_NESTED_SIEFP 0x40001082
+#define HV_X64_MSR_NESTED_SIMP 0x40001083
+#define HV_X64_MSR_NESTED_EOM 0x40001084
+#define HV_X64_MSR_NESTED_SINT0 0x40001090
/*
* Synthetic Timer MSRs. Four timers per vcpu.
*/
-#define HV_REGISTER_STIMER0_CONFIG 0x400000B0
-#define HV_REGISTER_STIMER0_COUNT 0x400000B1
-#define HV_REGISTER_STIMER1_CONFIG 0x400000B2
-#define HV_REGISTER_STIMER1_COUNT 0x400000B3
-#define HV_REGISTER_STIMER2_CONFIG 0x400000B4
-#define HV_REGISTER_STIMER2_COUNT 0x400000B5
-#define HV_REGISTER_STIMER3_CONFIG 0x400000B6
-#define HV_REGISTER_STIMER3_COUNT 0x400000B7
+#define HV_X64_MSR_STIMER0_CONFIG 0x400000B0
+#define HV_X64_MSR_STIMER0_COUNT 0x400000B1
+#define HV_X64_MSR_STIMER1_CONFIG 0x400000B2
+#define HV_X64_MSR_STIMER1_COUNT 0x400000B3
+#define HV_X64_MSR_STIMER2_CONFIG 0x400000B4
+#define HV_X64_MSR_STIMER2_COUNT 0x400000B5
+#define HV_X64_MSR_STIMER3_CONFIG 0x400000B6
+#define HV_X64_MSR_STIMER3_COUNT 0x400000B7
/* Hyper-V guest idle MSR */
#define HV_X64_MSR_GUEST_IDLE 0x400000F0
/* Hyper-V guest crash notification MSR's */
-#define HV_REGISTER_CRASH_P0 0x40000100
-#define HV_REGISTER_CRASH_P1 0x40000101
-#define HV_REGISTER_CRASH_P2 0x40000102
-#define HV_REGISTER_CRASH_P3 0x40000103
-#define HV_REGISTER_CRASH_P4 0x40000104
-#define HV_REGISTER_CRASH_CTL 0x40000105
+#define HV_X64_MSR_CRASH_P0 0x40000100
+#define HV_X64_MSR_CRASH_P1 0x40000101
+#define HV_X64_MSR_CRASH_P2 0x40000102
+#define HV_X64_MSR_CRASH_P3 0x40000103
+#define HV_X64_MSR_CRASH_P4 0x40000104
+#define HV_X64_MSR_CRASH_CTL 0x40000105
/* TSC emulation after migration */
#define HV_X64_MSR_REENLIGHTENMENT_CONTROL 0x40000106
@@ -276,31 +276,38 @@ enum hv_isolation_type {
/* HV_X64_MSR_TSC_INVARIANT_CONTROL bits */
#define HV_EXPOSE_INVARIANT_TSC BIT_ULL(0)
-/* Register name aliases for temporary compatibility */
-#define HV_X64_MSR_STIMER0_COUNT HV_REGISTER_STIMER0_COUNT
-#define HV_X64_MSR_STIMER0_CONFIG HV_REGISTER_STIMER0_CONFIG
-#define HV_X64_MSR_STIMER1_COUNT HV_REGISTER_STIMER1_COUNT
-#define HV_X64_MSR_STIMER1_CONFIG HV_REGISTER_STIMER1_CONFIG
-#define HV_X64_MSR_STIMER2_COUNT HV_REGISTER_STIMER2_COUNT
-#define HV_X64_MSR_STIMER2_CONFIG HV_REGISTER_STIMER2_CONFIG
-#define HV_X64_MSR_STIMER3_COUNT HV_REGISTER_STIMER3_COUNT
-#define HV_X64_MSR_STIMER3_CONFIG HV_REGISTER_STIMER3_CONFIG
-#define HV_X64_MSR_SCONTROL HV_REGISTER_SCONTROL
-#define HV_X64_MSR_SVERSION HV_REGISTER_SVERSION
-#define HV_X64_MSR_SIMP HV_REGISTER_SIMP
-#define HV_X64_MSR_SIEFP HV_REGISTER_SIEFP
-#define HV_X64_MSR_VP_INDEX HV_REGISTER_VP_INDEX
-#define HV_X64_MSR_EOM HV_REGISTER_EOM
-#define HV_X64_MSR_SINT0 HV_REGISTER_SINT0
-#define HV_X64_MSR_SINT15 HV_REGISTER_SINT15
-#define HV_X64_MSR_CRASH_P0 HV_REGISTER_CRASH_P0
-#define HV_X64_MSR_CRASH_P1 HV_REGISTER_CRASH_P1
-#define HV_X64_MSR_CRASH_P2 HV_REGISTER_CRASH_P2
-#define HV_X64_MSR_CRASH_P3 HV_REGISTER_CRASH_P3
-#define HV_X64_MSR_CRASH_P4 HV_REGISTER_CRASH_P4
-#define HV_X64_MSR_CRASH_CTL HV_REGISTER_CRASH_CTL
-#define HV_X64_MSR_TIME_REF_COUNT HV_REGISTER_TIME_REF_COUNT
-#define HV_X64_MSR_REFERENCE_TSC HV_REGISTER_REFERENCE_TSC
+/*
+ * To support arch-generic code calling hv_set/get_register:
+ * - On x86, HV_MSR_ indicates an MSR accessed via rdmsrl/wrmsrl
+ * - On ARM, HV_MSR_ indicates a VP register accessed via hypercall
+ */
+#define HV_MSR_CRASH_P0 (HV_X64_MSR_CRASH_P0)
+#define HV_MSR_CRASH_P1 (HV_X64_MSR_CRASH_P1)
+#define HV_MSR_CRASH_P2 (HV_X64_MSR_CRASH_P2)
+#define HV_MSR_CRASH_P3 (HV_X64_MSR_CRASH_P3)
+#define HV_MSR_CRASH_P4 (HV_X64_MSR_CRASH_P4)
+#define HV_MSR_CRASH_CTL (HV_X64_MSR_CRASH_CTL)
+
+#define HV_MSR_VP_INDEX (HV_X64_MSR_VP_INDEX)
+#define HV_MSR_TIME_REF_COUNT (HV_X64_MSR_TIME_REF_COUNT)
+#define HV_MSR_REFERENCE_TSC (HV_X64_MSR_REFERENCE_TSC)
+
+#define HV_MSR_SINT0 (HV_X64_MSR_SINT0)
+#define HV_MSR_SVERSION (HV_X64_MSR_SVERSION)
+#define HV_MSR_SCONTROL (HV_X64_MSR_SCONTROL)
+#define HV_MSR_SIEFP (HV_X64_MSR_SIEFP)
+#define HV_MSR_SIMP (HV_X64_MSR_SIMP)
+#define HV_MSR_EOM (HV_X64_MSR_EOM)
+
+#define HV_MSR_NESTED_SCONTROL (HV_X64_MSR_NESTED_SCONTROL)
+#define HV_MSR_NESTED_SVERSION (HV_X64_MSR_NESTED_SVERSION)
+#define HV_MSR_NESTED_SIEFP (HV_X64_MSR_NESTED_SIEFP)
+#define HV_MSR_NESTED_SIMP (HV_X64_MSR_NESTED_SIMP)
+#define HV_MSR_NESTED_EOM (HV_X64_MSR_NESTED_EOM)
+#define HV_MSR_NESTED_SINT0 (HV_X64_MSR_NESTED_SINT0)
+
+#define HV_MSR_STIMER0_CONFIG (HV_X64_MSR_STIMER0_CONFIG)
+#define HV_MSR_STIMER0_COUNT (HV_X64_MSR_STIMER0_COUNT)
/*
* Registers are only accessible via HVCALL_GET_VP_REGISTERS hvcall and
diff --git a/arch/x86/include/asm/ia32.h b/arch/x86/include/asm/ia32.h
index c7ef6ea2fa99..4212c00c9708 100644
--- a/arch/x86/include/asm/ia32.h
+++ b/arch/x86/include/asm/ia32.h
@@ -69,7 +69,7 @@ extern void ia32_pick_mmap_layout(struct mm_struct *mm);
extern bool __ia32_enabled;
-static inline bool ia32_enabled(void)
+static __always_inline bool ia32_enabled(void)
{
return __ia32_enabled;
}
@@ -81,7 +81,7 @@ static inline void ia32_disable(void)
#else /* !CONFIG_IA32_EMULATION */
-static inline bool ia32_enabled(void)
+static __always_inline bool ia32_enabled(void)
{
return IS_ENABLED(CONFIG_X86_32);
}
diff --git a/arch/x86/include/asm/idtentry.h b/arch/x86/include/asm/idtentry.h
index 13639e57e1f8..749c7411d2f1 100644
--- a/arch/x86/include/asm/idtentry.h
+++ b/arch/x86/include/asm/idtentry.h
@@ -13,15 +13,18 @@
#include <asm/irq_stack.h>
+typedef void (*idtentry_t)(struct pt_regs *regs);
+
/**
* DECLARE_IDTENTRY - Declare functions for simple IDT entry points
* No error code pushed by hardware
* @vector: Vector number (ignored for C)
* @func: Function name of the entry point
*
- * Declares three functions:
+ * Declares four functions:
* - The ASM entry point: asm_##func
* - The XEN PV trap entry point: xen_##func (maybe unused)
+ * - The C handler called from the FRED event dispatcher (maybe unused)
* - The C handler called from the ASM entry point
*
* Note: This is the C variant of DECLARE_IDTENTRY(). As the name says it
@@ -31,6 +34,7 @@
#define DECLARE_IDTENTRY(vector, func) \
asmlinkage void asm_##func(void); \
asmlinkage void xen_asm_##func(void); \
+ void fred_##func(struct pt_regs *regs); \
__visible void func(struct pt_regs *regs)
/**
@@ -138,6 +142,17 @@ static __always_inline void __##func(struct pt_regs *regs, \
__visible noinstr void func(struct pt_regs *regs)
/**
+ * DEFINE_FREDENTRY_RAW - Emit code for raw FRED entry points
+ * @func: Function name of the entry point
+ *
+ * @func is called from the FRED event dispatcher with interrupts disabled.
+ *
+ * See @DEFINE_IDTENTRY_RAW for further details.
+ */
+#define DEFINE_FREDENTRY_RAW(func) \
+noinstr void fred_##func(struct pt_regs *regs)
+
+/**
* DECLARE_IDTENTRY_RAW_ERRORCODE - Declare functions for raw IDT entry points
* Error code pushed by hardware
* @vector: Vector number (ignored for C)
@@ -233,17 +248,27 @@ static noinline void __##func(struct pt_regs *regs, u32 vector)
#define DEFINE_IDTENTRY_SYSVEC(func) \
static void __##func(struct pt_regs *regs); \
\
+static __always_inline void instr_##func(struct pt_regs *regs) \
+{ \
+ kvm_set_cpu_l1tf_flush_l1d(); \
+ run_sysvec_on_irqstack_cond(__##func, regs); \
+} \
+ \
__visible noinstr void func(struct pt_regs *regs) \
{ \
irqentry_state_t state = irqentry_enter(regs); \
\
instrumentation_begin(); \
- kvm_set_cpu_l1tf_flush_l1d(); \
- run_sysvec_on_irqstack_cond(__##func, regs); \
+ instr_##func (regs); \
instrumentation_end(); \
irqentry_exit(regs, state); \
} \
\
+void fred_##func(struct pt_regs *regs) \
+{ \
+ instr_##func (regs); \
+} \
+ \
static noinline void __##func(struct pt_regs *regs)
/**
@@ -260,19 +285,29 @@ static noinline void __##func(struct pt_regs *regs)
#define DEFINE_IDTENTRY_SYSVEC_SIMPLE(func) \
static __always_inline void __##func(struct pt_regs *regs); \
\
-__visible noinstr void func(struct pt_regs *regs) \
+static __always_inline void instr_##func(struct pt_regs *regs) \
{ \
- irqentry_state_t state = irqentry_enter(regs); \
- \
- instrumentation_begin(); \
__irq_enter_raw(); \
kvm_set_cpu_l1tf_flush_l1d(); \
__##func (regs); \
__irq_exit_raw(); \
+} \
+ \
+__visible noinstr void func(struct pt_regs *regs) \
+{ \
+ irqentry_state_t state = irqentry_enter(regs); \
+ \
+ instrumentation_begin(); \
+ instr_##func (regs); \
instrumentation_end(); \
irqentry_exit(regs, state); \
} \
\
+void fred_##func(struct pt_regs *regs) \
+{ \
+ instr_##func (regs); \
+} \
+ \
static __always_inline void __##func(struct pt_regs *regs)
/**
@@ -410,17 +445,35 @@ __visible noinstr void func(struct pt_regs *regs, \
/* C-Code mapping */
#define DECLARE_IDTENTRY_NMI DECLARE_IDTENTRY_RAW
#define DEFINE_IDTENTRY_NMI DEFINE_IDTENTRY_RAW
+#define DEFINE_FREDENTRY_NMI DEFINE_FREDENTRY_RAW
#ifdef CONFIG_X86_64
#define DECLARE_IDTENTRY_MCE DECLARE_IDTENTRY_IST
#define DEFINE_IDTENTRY_MCE DEFINE_IDTENTRY_IST
#define DEFINE_IDTENTRY_MCE_USER DEFINE_IDTENTRY_NOIST
+#define DEFINE_FREDENTRY_MCE DEFINE_FREDENTRY_RAW
#define DECLARE_IDTENTRY_DEBUG DECLARE_IDTENTRY_IST
#define DEFINE_IDTENTRY_DEBUG DEFINE_IDTENTRY_IST
#define DEFINE_IDTENTRY_DEBUG_USER DEFINE_IDTENTRY_NOIST
+#define DEFINE_FREDENTRY_DEBUG DEFINE_FREDENTRY_RAW
+#endif
+
+void idt_install_sysvec(unsigned int n, const void *function);
+
+#ifdef CONFIG_X86_FRED
+void fred_install_sysvec(unsigned int vector, const idtentry_t function);
+#else
+static inline void fred_install_sysvec(unsigned int vector, const idtentry_t function) { }
#endif
+#define sysvec_install(vector, function) { \
+ if (cpu_feature_enabled(X86_FEATURE_FRED)) \
+ fred_install_sysvec(vector, function); \
+ else \
+ idt_install_sysvec(vector, asm_##function); \
+}
+
#else /* !__ASSEMBLY__ */
/*
@@ -447,7 +500,7 @@ __visible noinstr void func(struct pt_regs *regs, \
/* System vector entries */
#define DECLARE_IDTENTRY_SYSVEC(vector, func) \
- idtentry_sysvec vector func
+ DECLARE_IDTENTRY(vector, func)
#ifdef CONFIG_X86_64
# define DECLARE_IDTENTRY_MCE(vector, func) \
@@ -655,36 +708,53 @@ DECLARE_IDTENTRY(RESCHEDULE_VECTOR, sysvec_reschedule_ipi);
DECLARE_IDTENTRY_SYSVEC(REBOOT_VECTOR, sysvec_reboot);
DECLARE_IDTENTRY_SYSVEC(CALL_FUNCTION_SINGLE_VECTOR, sysvec_call_function_single);
DECLARE_IDTENTRY_SYSVEC(CALL_FUNCTION_VECTOR, sysvec_call_function);
+#else
+# define fred_sysvec_reschedule_ipi NULL
+# define fred_sysvec_reboot NULL
+# define fred_sysvec_call_function_single NULL
+# define fred_sysvec_call_function NULL
#endif
#ifdef CONFIG_X86_LOCAL_APIC
# ifdef CONFIG_X86_MCE_THRESHOLD
DECLARE_IDTENTRY_SYSVEC(THRESHOLD_APIC_VECTOR, sysvec_threshold);
+# else
+# define fred_sysvec_threshold NULL
# endif
# ifdef CONFIG_X86_MCE_AMD
DECLARE_IDTENTRY_SYSVEC(DEFERRED_ERROR_VECTOR, sysvec_deferred_error);
+# else
+# define fred_sysvec_deferred_error NULL
# endif
# ifdef CONFIG_X86_THERMAL_VECTOR
DECLARE_IDTENTRY_SYSVEC(THERMAL_APIC_VECTOR, sysvec_thermal);
+# else
+# define fred_sysvec_thermal NULL
# endif
# ifdef CONFIG_IRQ_WORK
DECLARE_IDTENTRY_SYSVEC(IRQ_WORK_VECTOR, sysvec_irq_work);
+# else
+# define fred_sysvec_irq_work NULL
# endif
#endif
-#ifdef CONFIG_HAVE_KVM
+#if IS_ENABLED(CONFIG_KVM)
DECLARE_IDTENTRY_SYSVEC(POSTED_INTR_VECTOR, sysvec_kvm_posted_intr_ipi);
DECLARE_IDTENTRY_SYSVEC(POSTED_INTR_WAKEUP_VECTOR, sysvec_kvm_posted_intr_wakeup_ipi);
DECLARE_IDTENTRY_SYSVEC(POSTED_INTR_NESTED_VECTOR, sysvec_kvm_posted_intr_nested_ipi);
+#else
+# define fred_sysvec_kvm_posted_intr_ipi NULL
+# define fred_sysvec_kvm_posted_intr_wakeup_ipi NULL
+# define fred_sysvec_kvm_posted_intr_nested_ipi 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);
-DECLARE_IDTENTRY_SYSVEC(HYPERV_STIMER0_VECTOR, sysvec_hyperv_stimer0);
+DECLARE_IDTENTRY_SYSVEC(HYPERV_STIMER0_VECTOR, sysvec_hyperv_stimer0);
#endif
#if IS_ENABLED(CONFIG_ACRN_GUEST)
diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h
index b65e9c46b922..d0941f4c2724 100644
--- a/arch/x86/include/asm/intel-family.h
+++ b/arch/x86/include/asm/intel-family.h
@@ -127,6 +127,7 @@
#define INTEL_FAM6_ARROWLAKE_H 0xC5
#define INTEL_FAM6_ARROWLAKE 0xC6
+#define INTEL_FAM6_ARROWLAKE_U 0xB5
#define INTEL_FAM6_LUNARLAKE_M 0xBD
diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index 3814a9263d64..294cd2a40818 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -379,7 +379,7 @@ static inline void iosubmit_cmds512(void __iomem *dst, const void *src,
const u8 *end = from + count * 64;
while (from < end) {
- movdir64b(dst, from);
+ movdir64b_io(dst, from);
from += 64;
}
}
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 51c782600e02..0d806513c4b3 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -140,7 +140,6 @@ extern void mask_ioapic_entries(void);
extern int restore_ioapic_entries(void);
extern void setup_ioapic_ids_from_mpc(void);
-extern void setup_ioapic_ids_from_mpc_nocheck(void);
extern int mp_find_ioapic(u32 gsi);
extern int mp_find_ioapic_pin(int ioapic, u32 gsi);
diff --git a/arch/x86/include/asm/iommu.h b/arch/x86/include/asm/iommu.h
index 2fd52b65deac..3be2451e7bc8 100644
--- a/arch/x86/include/asm/iommu.h
+++ b/arch/x86/include/asm/iommu.h
@@ -10,6 +10,7 @@ extern int force_iommu, no_iommu;
extern int iommu_detected;
extern int iommu_merge;
extern int panic_on_overflow;
+extern bool amd_iommu_snp_en;
#ifdef CONFIG_SWIOTLB
extern bool x86_swiotlb_enable;
diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h
index 836c170d3087..194dfff84cb1 100644
--- a/arch/x86/include/asm/irq.h
+++ b/arch/x86/include/asm/irq.h
@@ -29,7 +29,7 @@ struct irq_desc;
extern void fixup_irqs(void);
-#ifdef CONFIG_HAVE_KVM
+#if IS_ENABLED(CONFIG_KVM)
extern void kvm_set_posted_intr_wakeup_handler(void (*handler)(void));
#endif
diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h
index 3a19904c2db6..d18bfb238f66 100644
--- a/arch/x86/include/asm/irq_vectors.h
+++ b/arch/x86/include/asm/irq_vectors.h
@@ -84,11 +84,9 @@
#define HYPERVISOR_CALLBACK_VECTOR 0xf3
/* Vector for KVM to deliver posted interrupt IPI */
-#ifdef CONFIG_HAVE_KVM
#define POSTED_INTR_VECTOR 0xf2
#define POSTED_INTR_WAKEUP_VECTOR 0xf1
#define POSTED_INTR_NESTED_VECTOR 0xf0
-#endif
#define MANAGED_IRQ_SHUTDOWN_VECTOR 0xef
diff --git a/arch/x86/include/asm/kexec.h b/arch/x86/include/asm/kexec.h
index c9f6a6c5de3c..91ca9a9ee3a2 100644
--- a/arch/x86/include/asm/kexec.h
+++ b/arch/x86/include/asm/kexec.h
@@ -25,7 +25,6 @@
#include <asm/page.h>
#include <asm/ptrace.h>
-#include <asm/bootparam.h>
struct kimage;
diff --git a/arch/x86/include/asm/kvm-x86-ops.h b/arch/x86/include/asm/kvm-x86-ops.h
index 378ed944b849..110d7f29ca9a 100644
--- a/arch/x86/include/asm/kvm-x86-ops.h
+++ b/arch/x86/include/asm/kvm-x86-ops.h
@@ -103,7 +103,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(request_immediate_exit)
KVM_X86_OP(sched_in)
KVM_X86_OP_OPTIONAL(update_cpu_dirty_logging)
KVM_X86_OP_OPTIONAL(vcpu_blocking)
@@ -138,6 +137,7 @@ KVM_X86_OP(complete_emulated_msr)
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)
#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 058bc636356a..f852b13aeefe 100644
--- a/arch/x86/include/asm/kvm-x86-pmu-ops.h
+++ b/arch/x86/include/asm/kvm-x86-pmu-ops.h
@@ -12,11 +12,9 @@ BUILD_BUG_ON(1)
* a NULL definition, for example if "static_call_cond()" will be used
* at the call sites.
*/
-KVM_X86_PMU_OP(hw_event_available)
-KVM_X86_PMU_OP(pmc_idx_to_pmc)
KVM_X86_PMU_OP(rdpmc_ecx_to_pmc)
KVM_X86_PMU_OP(msr_idx_to_pmc)
-KVM_X86_PMU_OP(is_valid_rdpmc_ecx)
+KVM_X86_PMU_OP_OPTIONAL(check_rdpmc_early)
KVM_X86_PMU_OP(is_valid_msr)
KVM_X86_PMU_OP(get_msr)
KVM_X86_PMU_OP(set_msr)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index d271ba20a0b2..16e07a2eee19 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -536,6 +536,7 @@ struct kvm_pmc {
#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
+
struct kvm_pmu {
u8 version;
unsigned nr_arch_gp_counters;
@@ -1468,6 +1469,15 @@ struct kvm_arch {
*/
bool shadow_root_allocated;
+#ifdef CONFIG_KVM_EXTERNAL_WRITE_TRACKING
+ /*
+ * If set, the VM has (or had) an external write tracking user, and
+ * thus all write tracking metadata has been allocated, even if KVM
+ * itself isn't using write tracking.
+ */
+ bool external_write_tracking_enabled;
+#endif
+
#if IS_ENABLED(CONFIG_HYPERV)
hpa_t hv_root_tdp;
spinlock_t hv_root_tdp_lock;
@@ -1665,7 +1675,8 @@ struct kvm_x86_ops {
void (*flush_tlb_guest)(struct kvm_vcpu *vcpu);
int (*vcpu_pre_run)(struct kvm_vcpu *vcpu);
- enum exit_fastpath_completion (*vcpu_run)(struct kvm_vcpu *vcpu);
+ enum exit_fastpath_completion (*vcpu_run)(struct kvm_vcpu *vcpu,
+ bool force_immediate_exit);
int (*handle_exit)(struct kvm_vcpu *vcpu,
enum exit_fastpath_completion exit_fastpath);
int (*skip_emulated_instruction)(struct kvm_vcpu *vcpu);
@@ -1733,8 +1744,6 @@ struct kvm_x86_ops {
struct x86_exception *exception);
void (*handle_exit_irqoff)(struct kvm_vcpu *vcpu);
- void (*request_immediate_exit)(struct kvm_vcpu *vcpu);
-
void (*sched_in)(struct kvm_vcpu *vcpu, int cpu);
/*
@@ -1796,6 +1805,7 @@ struct kvm_x86_ops {
unsigned long (*vcpu_get_apicv_inhibit_reasons)(struct kvm_vcpu *vcpu);
gva_t (*get_untagged_addr)(struct kvm_vcpu *vcpu, gva_t gva, unsigned int flags);
+ void *(*alloc_apic_backing_page)(struct kvm_vcpu *vcpu);
};
struct kvm_x86_nested_ops {
@@ -1881,8 +1891,16 @@ static inline int kvm_arch_flush_remote_tlbs_range(struct kvm *kvm, gfn_t gfn,
}
#endif /* CONFIG_HYPERV */
+enum kvm_intr_type {
+ /* Values are arbitrary, but must be non-zero. */
+ KVM_HANDLING_IRQ = 1,
+ KVM_HANDLING_NMI,
+};
+
+/* Enable perf NMI and timer modes to work, and minimise false positives. */
#define kvm_arch_pmi_in_guest(vcpu) \
- ((vcpu) && (vcpu)->arch.handling_intr_from_guest)
+ ((vcpu) && (vcpu)->arch.handling_intr_from_guest && \
+ (!!in_nmi() == ((vcpu)->arch.handling_intr_from_guest == KVM_HANDLING_NMI)))
void __init kvm_mmu_x86_module_init(void);
int kvm_mmu_vendor_module_init(void);
@@ -2047,7 +2065,7 @@ int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3);
int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4);
int kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8);
int kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val);
-void kvm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *val);
+unsigned long kvm_get_dr(struct kvm_vcpu *vcpu, int dr);
unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu);
void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw);
int kvm_emulate_xsetbv(struct kvm_vcpu *vcpu);
@@ -2240,7 +2258,6 @@ extern bool kvm_find_async_pf_gfn(struct kvm_vcpu *vcpu, gfn_t gfn);
int kvm_skip_emulated_instruction(struct kvm_vcpu *vcpu);
int kvm_complete_insn_gp(struct kvm_vcpu *vcpu, int err);
-void __kvm_request_immediate_exit(struct kvm_vcpu *vcpu);
void __user *__x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa,
u32 size);
diff --git a/arch/x86/include/asm/kvmclock.h b/arch/x86/include/asm/kvmclock.h
index 511b35069187..f163176d6f7f 100644
--- a/arch/x86/include/asm/kvmclock.h
+++ b/arch/x86/include/asm/kvmclock.h
@@ -4,8 +4,6 @@
#include <linux/percpu.h>
-extern struct clocksource kvm_clock;
-
DECLARE_PER_CPU(struct pvclock_vsyscall_time_info *, hv_clock_per_cpu);
static __always_inline struct pvclock_vcpu_time_info *this_cpu_pvti(void)
diff --git a/arch/x86/include/asm/linkage.h b/arch/x86/include/asm/linkage.h
index 571fe4d2d232..dc31b13b87a0 100644
--- a/arch/x86/include/asm/linkage.h
+++ b/arch/x86/include/asm/linkage.h
@@ -40,27 +40,27 @@
#ifdef __ASSEMBLY__
-#if defined(CONFIG_RETHUNK) && !defined(__DISABLE_EXPORTS) && !defined(BUILD_VDSO)
+#if defined(CONFIG_MITIGATION_RETHUNK) && !defined(__DISABLE_EXPORTS) && !defined(BUILD_VDSO)
#define RET jmp __x86_return_thunk
-#else /* CONFIG_RETPOLINE */
-#ifdef CONFIG_SLS
+#else /* CONFIG_MITIGATION_RETPOLINE */
+#ifdef CONFIG_MITIGATION_SLS
#define RET ret; int3
#else
#define RET ret
#endif
-#endif /* CONFIG_RETPOLINE */
+#endif /* CONFIG_MITIGATION_RETPOLINE */
#else /* __ASSEMBLY__ */
-#if defined(CONFIG_RETHUNK) && !defined(__DISABLE_EXPORTS) && !defined(BUILD_VDSO)
+#if defined(CONFIG_MITIGATION_RETHUNK) && !defined(__DISABLE_EXPORTS) && !defined(BUILD_VDSO)
#define ASM_RET "jmp __x86_return_thunk\n\t"
-#else /* CONFIG_RETPOLINE */
-#ifdef CONFIG_SLS
+#else /* CONFIG_MITIGATION_RETPOLINE */
+#ifdef CONFIG_MITIGATION_SLS
#define ASM_RET "ret; int3\n\t"
#else
#define ASM_RET "ret\n\t"
#endif
-#endif /* CONFIG_RETPOLINE */
+#endif /* CONFIG_MITIGATION_RETPOLINE */
#endif /* __ASSEMBLY__ */
diff --git a/arch/x86/include/asm/local.h b/arch/x86/include/asm/local.h
index 73dba8b94443..59aa966dc212 100644
--- a/arch/x86/include/asm/local.h
+++ b/arch/x86/include/asm/local.h
@@ -131,8 +131,20 @@ static inline bool local_try_cmpxchg(local_t *l, long *old, long new)
(typeof(l->a.counter) *) old, new);
}
-/* Always has a lock prefix */
-#define local_xchg(l, n) (xchg(&((l)->a.counter), (n)))
+/*
+ * Implement local_xchg using CMPXCHG instruction without the LOCK prefix.
+ * XCHG is expensive due to the implied LOCK prefix. The processor
+ * cannot prefetch cachelines if XCHG is used.
+ */
+static __always_inline long
+local_xchg(local_t *l, long n)
+{
+ long c = local_read(l);
+
+ do { } while (!local_try_cmpxchg(l, &c, n));
+
+ return c;
+}
/**
* local_add_unless - add unless the number is already a given value
diff --git a/arch/x86/include/asm/mem_encrypt.h b/arch/x86/include/asm/mem_encrypt.h
index 359ada486fa9..f922b682b9b4 100644
--- a/arch/x86/include/asm/mem_encrypt.h
+++ b/arch/x86/include/asm/mem_encrypt.h
@@ -15,7 +15,8 @@
#include <linux/init.h>
#include <linux/cc_platform.h>
-#include <asm/bootparam.h>
+#include <asm/asm.h>
+struct boot_params;
#ifdef CONFIG_X86_MEM_ENCRYPT
void __init mem_encrypt_init(void);
@@ -46,8 +47,8 @@ void __init sme_unmap_bootdata(char *real_mode_data);
void __init sme_early_init(void);
-void __init sme_encrypt_kernel(struct boot_params *bp);
-void __init sme_enable(struct boot_params *bp);
+void sme_encrypt_kernel(struct boot_params *bp);
+void sme_enable(struct boot_params *bp);
int __init early_set_memory_decrypted(unsigned long vaddr, unsigned long size);
int __init early_set_memory_encrypted(unsigned long vaddr, unsigned long size);
@@ -58,6 +59,11 @@ void __init mem_encrypt_free_decrypted_mem(void);
void __init sev_es_init_vc_handling(void);
+static inline u64 sme_get_me_mask(void)
+{
+ return RIP_REL_REF(sme_me_mask);
+}
+
#define __bss_decrypted __section(".bss..decrypted")
#else /* !CONFIG_AMD_MEM_ENCRYPT */
@@ -75,8 +81,8 @@ static inline void __init sme_unmap_bootdata(char *real_mode_data) { }
static inline void __init sme_early_init(void) { }
-static inline void __init sme_encrypt_kernel(struct boot_params *bp) { }
-static inline void __init sme_enable(struct boot_params *bp) { }
+static inline void sme_encrypt_kernel(struct boot_params *bp) { }
+static inline void sme_enable(struct boot_params *bp) { }
static inline void sev_es_init_vc_handling(void) { }
@@ -89,6 +95,8 @@ early_set_mem_enc_dec_hypercall(unsigned long vaddr, unsigned long size, bool en
static inline void mem_encrypt_free_decrypted_mem(void) { }
+static inline u64 sme_get_me_mask(void) { return 0; }
+
#define __bss_decrypted
#endif /* CONFIG_AMD_MEM_ENCRYPT */
@@ -106,11 +114,6 @@ void add_encrypt_protection_map(void);
extern char __start_bss_decrypted[], __end_bss_decrypted[], __start_bss_decrypted_unused[];
-static inline u64 sme_get_me_mask(void)
-{
- return sme_me_mask;
-}
-
#endif /* __ASSEMBLY__ */
#endif /* __X86_MEM_ENCRYPT_H__ */
diff --git a/arch/x86/include/asm/mmu.h b/arch/x86/include/asm/mmu.h
index 0da5c227f490..ce4677b8b735 100644
--- a/arch/x86/include/asm/mmu.h
+++ b/arch/x86/include/asm/mmu.h
@@ -75,7 +75,7 @@ typedef struct {
.lock = __MUTEX_INITIALIZER(mm.context.lock), \
}
-void leave_mm(int cpu);
+void leave_mm(void);
#define leave_mm leave_mm
#endif /* _ASM_X86_MMU_H */
diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
index 4b0f98a8d338..c72c7ff78fcd 100644
--- a/arch/x86/include/asm/mpspec.h
+++ b/arch/x86/include/asm/mpspec.h
@@ -2,6 +2,7 @@
#ifndef _ASM_X86_MPSPEC_H
#define _ASM_X86_MPSPEC_H
+#include <linux/types.h>
#include <asm/mpspec_def.h>
#include <asm/x86_init.h>
@@ -46,70 +47,31 @@ extern int smp_found_config;
# define smp_found_config 0
#endif
-static inline void get_smp_config(void)
-{
- x86_init.mpparse.get_smp_config(0);
-}
-
-static inline void early_get_smp_config(void)
-{
- x86_init.mpparse.get_smp_config(1);
-}
-
-static inline void find_smp_config(void)
-{
- x86_init.mpparse.find_smp_config();
-}
-
#ifdef CONFIG_X86_MPPARSE
extern void e820__memblock_alloc_reserved_mpc_new(void);
extern int enable_update_mptable;
-extern void default_find_smp_config(void);
-extern void default_get_smp_config(unsigned int early);
+extern void mpparse_find_mptable(void);
+extern void mpparse_parse_early_smp_config(void);
+extern void mpparse_parse_smp_config(void);
#else
static inline void e820__memblock_alloc_reserved_mpc_new(void) { }
-#define enable_update_mptable 0
-#define default_find_smp_config x86_init_noop
-#define default_get_smp_config x86_init_uint_noop
+#define enable_update_mptable 0
+#define mpparse_find_mptable x86_init_noop
+#define mpparse_parse_early_smp_config x86_init_noop
+#define mpparse_parse_smp_config x86_init_noop
#endif
-int generic_processor_info(int apicid);
+extern DECLARE_BITMAP(phys_cpu_present_map, MAX_LOCAL_APIC);
-#define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_LOCAL_APIC)
-
-struct physid_mask {
- unsigned long mask[PHYSID_ARRAY_SIZE];
-};
-
-typedef struct physid_mask physid_mask_t;
-
-#define physid_set(physid, map) set_bit(physid, (map).mask)
-#define physid_isset(physid, map) test_bit(physid, (map).mask)
-
-#define physids_or(dst, src1, src2) \
- bitmap_or((dst).mask, (src1).mask, (src2).mask, MAX_LOCAL_APIC)
-
-#define physids_clear(map) \
- bitmap_zero((map).mask, MAX_LOCAL_APIC)
-
-#define physids_empty(map) \
- bitmap_empty((map).mask, MAX_LOCAL_APIC)
-
-static inline void physids_promote(unsigned long physids, physid_mask_t *map)
+static inline void reset_phys_cpu_present_map(u32 apicid)
{
- physids_clear(*map);
- map->mask[0] = physids;
+ bitmap_zero(phys_cpu_present_map, MAX_LOCAL_APIC);
+ set_bit(apicid, phys_cpu_present_map);
}
-static inline void physid_set_mask_of_physid(int physid, physid_mask_t *map)
+static inline void copy_phys_cpu_present_map(unsigned long *dst)
{
- physids_clear(*map);
- physid_set(physid, *map);
+ bitmap_copy(dst, phys_cpu_present_map, MAX_LOCAL_APIC);
}
-#define PHYSID_MASK_ALL { {[0 ... PHYSID_ARRAY_SIZE-1] = ~0UL} }
-#define PHYSID_MASK_NONE { {[0 ... PHYSID_ARRAY_SIZE-1] = 0UL} }
-
-extern physid_mask_t phys_cpu_present_map;
-
#endif /* _ASM_X86_MPSPEC_H */
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index ce4ce8720d55..390c4d13956d 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -293,24 +293,24 @@ static inline void hv_ivm_msr_write(u64 msr, u64 value) {}
static inline void hv_ivm_msr_read(u64 msr, u64 *value) {}
#endif
-static inline bool hv_is_synic_reg(unsigned int reg)
+static inline bool hv_is_synic_msr(unsigned int reg)
{
- return (reg >= HV_REGISTER_SCONTROL) &&
- (reg <= HV_REGISTER_SINT15);
+ return (reg >= HV_X64_MSR_SCONTROL) &&
+ (reg <= HV_X64_MSR_SINT15);
}
-static inline bool hv_is_sint_reg(unsigned int reg)
+static inline bool hv_is_sint_msr(unsigned int reg)
{
- return (reg >= HV_REGISTER_SINT0) &&
- (reg <= HV_REGISTER_SINT15);
+ return (reg >= HV_X64_MSR_SINT0) &&
+ (reg <= HV_X64_MSR_SINT15);
}
-u64 hv_get_register(unsigned int reg);
-void hv_set_register(unsigned int reg, u64 value);
-u64 hv_get_non_nested_register(unsigned int reg);
-void hv_set_non_nested_register(unsigned int reg, u64 value);
+u64 hv_get_msr(unsigned int reg);
+void hv_set_msr(unsigned int reg, u64 value);
+u64 hv_get_non_nested_msr(unsigned int reg);
+void hv_set_non_nested_msr(unsigned int reg, u64 value);
-static __always_inline u64 hv_raw_get_register(unsigned int reg)
+static __always_inline u64 hv_raw_get_msr(unsigned int reg)
{
return __rdmsr(reg);
}
@@ -331,10 +331,10 @@ static inline int hyperv_flush_guest_mapping_range(u64 as,
{
return -1;
}
-static inline void hv_set_register(unsigned int reg, u64 value) { }
-static inline u64 hv_get_register(unsigned int reg) { return 0; }
-static inline void hv_set_non_nested_register(unsigned int reg, u64 value) { }
-static inline u64 hv_get_non_nested_register(unsigned int reg) { return 0; }
+static inline void hv_set_msr(unsigned int reg, u64 value) { }
+static inline u64 hv_get_msr(unsigned int reg) { return 0; }
+static inline void hv_set_non_nested_msr(unsigned int reg, u64 value) { }
+static inline u64 hv_get_non_nested_msr(unsigned int reg) { return 0; }
#endif /* CONFIG_HYPERV */
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index f1bd7b91b3c6..e72c2b872957 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -36,8 +36,19 @@
#define EFER_FFXSR (1<<_EFER_FFXSR)
#define EFER_AUTOIBRS (1<<_EFER_AUTOIBRS)
-/* Intel MSRs. Some also available on other CPUs */
+/* FRED MSRs */
+#define MSR_IA32_FRED_RSP0 0x1cc /* Level 0 stack pointer */
+#define MSR_IA32_FRED_RSP1 0x1cd /* Level 1 stack pointer */
+#define MSR_IA32_FRED_RSP2 0x1ce /* Level 2 stack pointer */
+#define MSR_IA32_FRED_RSP3 0x1cf /* Level 3 stack pointer */
+#define MSR_IA32_FRED_STKLVLS 0x1d0 /* Exception stack levels */
+#define MSR_IA32_FRED_SSP0 MSR_IA32_PL0_SSP /* Level 0 shadow stack pointer */
+#define MSR_IA32_FRED_SSP1 0x1d1 /* Level 1 shadow stack pointer */
+#define MSR_IA32_FRED_SSP2 0x1d2 /* Level 2 shadow stack pointer */
+#define MSR_IA32_FRED_SSP3 0x1d3 /* Level 3 shadow stack pointer */
+#define MSR_IA32_FRED_CONFIG 0x1d4 /* Entrypoint and interrupt stack level */
+/* Intel MSRs. Some also available on other CPUs */
#define MSR_TEST_CTRL 0x00000033
#define MSR_TEST_CTRL_SPLIT_LOCK_DETECT_BIT 29
#define MSR_TEST_CTRL_SPLIT_LOCK_DETECT BIT(MSR_TEST_CTRL_SPLIT_LOCK_DETECT_BIT)
@@ -50,10 +61,13 @@
#define SPEC_CTRL_SSBD BIT(SPEC_CTRL_SSBD_SHIFT) /* Speculative Store Bypass Disable */
#define SPEC_CTRL_RRSBA_DIS_S_SHIFT 6 /* Disable RRSBA behavior */
#define SPEC_CTRL_RRSBA_DIS_S BIT(SPEC_CTRL_RRSBA_DIS_S_SHIFT)
+#define SPEC_CTRL_BHI_DIS_S_SHIFT 10 /* Disable Branch History Injection behavior */
+#define SPEC_CTRL_BHI_DIS_S BIT(SPEC_CTRL_BHI_DIS_S_SHIFT)
/* A mask for bits which the kernel toggles when controlling mitigations */
#define SPEC_CTRL_MITIGATIONS_MASK (SPEC_CTRL_IBRS | SPEC_CTRL_STIBP | SPEC_CTRL_SSBD \
- | SPEC_CTRL_RRSBA_DIS_S)
+ | SPEC_CTRL_RRSBA_DIS_S \
+ | SPEC_CTRL_BHI_DIS_S)
#define MSR_IA32_PRED_CMD 0x00000049 /* Prediction Command */
#define PRED_CMD_IBPB BIT(0) /* Indirect Branch Prediction Barrier */
@@ -152,6 +166,10 @@
* are restricted to targets in
* kernel.
*/
+#define ARCH_CAP_BHI_NO BIT(20) /*
+ * CPU is not affected by Branch
+ * History Injection.
+ */
#define ARCH_CAP_PBRSB_NO BIT(24) /*
* Not susceptible to Post-Barrier
* Return Stack Buffer Predictions.
@@ -165,6 +183,14 @@
* CPU is not vulnerable to Gather
* Data Sampling (GDS).
*/
+#define ARCH_CAP_RFDS_NO BIT(27) /*
+ * Not susceptible to Register
+ * File Data Sampling.
+ */
+#define ARCH_CAP_RFDS_CLEAR BIT(28) /*
+ * VERW clears CPU Register
+ * File.
+ */
#define ARCH_CAP_XAPIC_DISABLE BIT(21) /*
* IA32_XAPIC_DISABLE_STATUS MSR
@@ -594,34 +620,47 @@
#define MSR_AMD64_SEV_ES_GHCB 0xc0010130
#define MSR_AMD64_SEV 0xc0010131
#define MSR_AMD64_SEV_ENABLED_BIT 0
-#define MSR_AMD64_SEV_ES_ENABLED_BIT 1
-#define MSR_AMD64_SEV_SNP_ENABLED_BIT 2
#define MSR_AMD64_SEV_ENABLED BIT_ULL(MSR_AMD64_SEV_ENABLED_BIT)
+#define MSR_AMD64_SEV_ES_ENABLED_BIT 1
#define MSR_AMD64_SEV_ES_ENABLED BIT_ULL(MSR_AMD64_SEV_ES_ENABLED_BIT)
+#define MSR_AMD64_SEV_SNP_ENABLED_BIT 2
#define MSR_AMD64_SEV_SNP_ENABLED BIT_ULL(MSR_AMD64_SEV_SNP_ENABLED_BIT)
-
-/* SNP feature bits enabled by the hypervisor */
-#define MSR_AMD64_SNP_VTOM BIT_ULL(3)
-#define MSR_AMD64_SNP_REFLECT_VC BIT_ULL(4)
-#define MSR_AMD64_SNP_RESTRICTED_INJ BIT_ULL(5)
-#define MSR_AMD64_SNP_ALT_INJ BIT_ULL(6)
-#define MSR_AMD64_SNP_DEBUG_SWAP BIT_ULL(7)
-#define MSR_AMD64_SNP_PREVENT_HOST_IBS BIT_ULL(8)
-#define MSR_AMD64_SNP_BTB_ISOLATION BIT_ULL(9)
-#define MSR_AMD64_SNP_VMPL_SSS BIT_ULL(10)
-#define MSR_AMD64_SNP_SECURE_TSC BIT_ULL(11)
-#define MSR_AMD64_SNP_VMGEXIT_PARAM BIT_ULL(12)
-#define MSR_AMD64_SNP_IBS_VIRT BIT_ULL(14)
-#define MSR_AMD64_SNP_VMSA_REG_PROTECTION BIT_ULL(16)
-#define MSR_AMD64_SNP_SMT_PROTECTION BIT_ULL(17)
-
-/* SNP feature bits reserved for future use. */
-#define MSR_AMD64_SNP_RESERVED_BIT13 BIT_ULL(13)
-#define MSR_AMD64_SNP_RESERVED_BIT15 BIT_ULL(15)
-#define MSR_AMD64_SNP_RESERVED_MASK GENMASK_ULL(63, 18)
+#define MSR_AMD64_SNP_VTOM_BIT 3
+#define MSR_AMD64_SNP_VTOM BIT_ULL(MSR_AMD64_SNP_VTOM_BIT)
+#define MSR_AMD64_SNP_REFLECT_VC_BIT 4
+#define MSR_AMD64_SNP_REFLECT_VC BIT_ULL(MSR_AMD64_SNP_REFLECT_VC_BIT)
+#define MSR_AMD64_SNP_RESTRICTED_INJ_BIT 5
+#define MSR_AMD64_SNP_RESTRICTED_INJ BIT_ULL(MSR_AMD64_SNP_RESTRICTED_INJ_BIT)
+#define MSR_AMD64_SNP_ALT_INJ_BIT 6
+#define MSR_AMD64_SNP_ALT_INJ BIT_ULL(MSR_AMD64_SNP_ALT_INJ_BIT)
+#define MSR_AMD64_SNP_DEBUG_SWAP_BIT 7
+#define MSR_AMD64_SNP_DEBUG_SWAP BIT_ULL(MSR_AMD64_SNP_DEBUG_SWAP_BIT)
+#define MSR_AMD64_SNP_PREVENT_HOST_IBS_BIT 8
+#define MSR_AMD64_SNP_PREVENT_HOST_IBS BIT_ULL(MSR_AMD64_SNP_PREVENT_HOST_IBS_BIT)
+#define MSR_AMD64_SNP_BTB_ISOLATION_BIT 9
+#define MSR_AMD64_SNP_BTB_ISOLATION BIT_ULL(MSR_AMD64_SNP_BTB_ISOLATION_BIT)
+#define MSR_AMD64_SNP_VMPL_SSS_BIT 10
+#define MSR_AMD64_SNP_VMPL_SSS BIT_ULL(MSR_AMD64_SNP_VMPL_SSS_BIT)
+#define MSR_AMD64_SNP_SECURE_TSC_BIT 11
+#define MSR_AMD64_SNP_SECURE_TSC BIT_ULL(MSR_AMD64_SNP_SECURE_TSC_BIT)
+#define MSR_AMD64_SNP_VMGEXIT_PARAM_BIT 12
+#define MSR_AMD64_SNP_VMGEXIT_PARAM BIT_ULL(MSR_AMD64_SNP_VMGEXIT_PARAM_BIT)
+#define MSR_AMD64_SNP_RESERVED_BIT13 BIT_ULL(13)
+#define MSR_AMD64_SNP_IBS_VIRT_BIT 14
+#define MSR_AMD64_SNP_IBS_VIRT BIT_ULL(MSR_AMD64_SNP_IBS_VIRT_BIT)
+#define MSR_AMD64_SNP_RESERVED_BIT15 BIT_ULL(15)
+#define MSR_AMD64_SNP_VMSA_REG_PROT_BIT 16
+#define MSR_AMD64_SNP_VMSA_REG_PROT BIT_ULL(MSR_AMD64_SNP_VMSA_REG_PROT_BIT)
+#define MSR_AMD64_SNP_SMT_PROT_BIT 17
+#define MSR_AMD64_SNP_SMT_PROT BIT_ULL(MSR_AMD64_SNP_SMT_PROT_BIT)
+#define MSR_AMD64_SNP_RESV_BIT 18
+#define MSR_AMD64_SNP_RESERVED_MASK GENMASK_ULL(63, MSR_AMD64_SNP_RESV_BIT)
#define MSR_AMD64_VIRT_SPEC_CTRL 0xc001011f
+#define MSR_AMD64_RMP_BASE 0xc0010132
+#define MSR_AMD64_RMP_END 0xc0010133
+
/* AMD Collaborative Processor Performance Control MSRs */
#define MSR_AMD_CPPC_CAP1 0xc00102b0
#define MSR_AMD_CPPC_ENABLE 0xc00102b1
@@ -708,8 +747,15 @@
#define MSR_K8_TOP_MEM1 0xc001001a
#define MSR_K8_TOP_MEM2 0xc001001d
#define MSR_AMD64_SYSCFG 0xc0010010
-#define MSR_AMD64_SYSCFG_MEM_ENCRYPT_BIT 23
+#define MSR_AMD64_SYSCFG_MEM_ENCRYPT_BIT 23
#define MSR_AMD64_SYSCFG_MEM_ENCRYPT BIT_ULL(MSR_AMD64_SYSCFG_MEM_ENCRYPT_BIT)
+#define MSR_AMD64_SYSCFG_SNP_EN_BIT 24
+#define MSR_AMD64_SYSCFG_SNP_EN BIT_ULL(MSR_AMD64_SYSCFG_SNP_EN_BIT)
+#define MSR_AMD64_SYSCFG_SNP_VMPL_EN_BIT 25
+#define MSR_AMD64_SYSCFG_SNP_VMPL_EN BIT_ULL(MSR_AMD64_SYSCFG_SNP_VMPL_EN_BIT)
+#define MSR_AMD64_SYSCFG_MFDM_BIT 19
+#define MSR_AMD64_SYSCFG_MFDM BIT_ULL(MSR_AMD64_SYSCFG_MFDM_BIT)
+
#define MSR_K8_INT_PENDING_MSG 0xc0010055
/* C1E active bits in int pending message */
#define K8_INTP_C1E_ACTIVE_MASK 0x18000000
diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h
index 65ec1965cd28..d642037f9ed5 100644
--- a/arch/x86/include/asm/msr.h
+++ b/arch/x86/include/asm/msr.h
@@ -12,11 +12,13 @@
#include <uapi/asm/msr.h>
#include <asm/shared/msr.h>
+#include <linux/percpu.h>
+
struct msr_info {
- u32 msr_no;
- struct msr reg;
- struct msr *msrs;
- int err;
+ u32 msr_no;
+ struct msr reg;
+ struct msr __percpu *msrs;
+ int err;
};
struct msr_regs_info {
@@ -97,6 +99,19 @@ static __always_inline void __wrmsr(unsigned int msr, u32 low, u32 high)
: : "c" (msr), "a"(low), "d" (high) : "memory");
}
+/*
+ * WRMSRNS behaves exactly like WRMSR with the only difference being
+ * that it is not a serializing instruction by default.
+ */
+static __always_inline void __wrmsrns(u32 msr, u32 low, u32 high)
+{
+ /* Instruction opcode for WRMSRNS; supported in binutils >= 2.40. */
+ asm volatile("1: .byte 0x0f,0x01,0xc6\n"
+ "2:\n"
+ _ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_WRMSR)
+ : : "c" (msr), "a"(low), "d" (high));
+}
+
#define native_rdmsr(msr, val1, val2) \
do { \
u64 __val = __rdmsr((msr)); \
@@ -297,6 +312,11 @@ do { \
#endif /* !CONFIG_PARAVIRT_XXL */
+static __always_inline void wrmsrns(u32 msr, u64 val)
+{
+ __wrmsrns(msr, val, val >> 32);
+}
+
/*
* 64-bit version of wrmsr_safe():
*/
@@ -305,8 +325,8 @@ static inline int wrmsrl_safe(u32 msr, u64 val)
return wrmsr_safe(msr, (u32)val, (u32)(val >> 32));
}
-struct msr *msrs_alloc(void);
-void msrs_free(struct msr *msrs);
+struct msr __percpu *msrs_alloc(void);
+void msrs_free(struct msr __percpu *msrs);
int msr_set_bit(u32 msr, u8 bit);
int msr_clear_bit(u32 msr, u8 bit);
@@ -315,8 +335,8 @@ int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
int rdmsrl_on_cpu(unsigned int cpu, u32 msr_no, u64 *q);
int wrmsrl_on_cpu(unsigned int cpu, u32 msr_no, u64 q);
-void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs);
-void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs);
+void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr __percpu *msrs);
+void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr __percpu *msrs);
int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
int rdmsrl_safe_on_cpu(unsigned int cpu, u32 msr_no, u64 *q);
@@ -345,14 +365,14 @@ static inline int wrmsrl_on_cpu(unsigned int cpu, u32 msr_no, u64 q)
return 0;
}
static inline void rdmsr_on_cpus(const struct cpumask *m, u32 msr_no,
- struct msr *msrs)
+ struct msr __percpu *msrs)
{
- rdmsr_on_cpu(0, msr_no, &(msrs[0].l), &(msrs[0].h));
+ rdmsr_on_cpu(0, msr_no, raw_cpu_ptr(&msrs->l), raw_cpu_ptr(&msrs->h));
}
static inline void wrmsr_on_cpus(const struct cpumask *m, u32 msr_no,
- struct msr *msrs)
+ struct msr __percpu *msrs)
{
- wrmsr_on_cpu(0, msr_no, msrs[0].l, msrs[0].h);
+ wrmsr_on_cpu(0, msr_no, raw_cpu_read(msrs->l), raw_cpu_read(msrs->h));
}
static inline int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no,
u32 *l, u32 *h)
diff --git a/arch/x86/include/asm/nmi.h b/arch/x86/include/asm/nmi.h
index 5c5f1e56c404..41a0ebb699ec 100644
--- a/arch/x86/include/asm/nmi.h
+++ b/arch/x86/include/asm/nmi.h
@@ -14,9 +14,6 @@ extern void release_perfctr_nmi(unsigned int);
extern int reserve_evntsel_nmi(unsigned int);
extern void release_evntsel_nmi(unsigned int);
-struct ctl_table;
-extern int proc_nmi_enabled(struct ctl_table *, int ,
- void __user *, size_t *, loff_t *);
extern int unknown_nmi_panic;
#endif /* CONFIG_X86_LOCAL_APIC */
diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h
index 2aa52cab1e46..ff5f1ecc7d1e 100644
--- a/arch/x86/include/asm/nospec-branch.h
+++ b/arch/x86/include/asm/nospec-branch.h
@@ -59,13 +59,13 @@
#ifdef CONFIG_CALL_THUNKS_DEBUG
# define CALL_THUNKS_DEBUG_INC_CALLS \
- incq %gs:__x86_call_count;
+ incq PER_CPU_VAR(__x86_call_count);
# define CALL_THUNKS_DEBUG_INC_RETS \
- incq %gs:__x86_ret_count;
+ incq PER_CPU_VAR(__x86_ret_count);
# define CALL_THUNKS_DEBUG_INC_STUFFS \
- incq %gs:__x86_stuffs_count;
+ incq PER_CPU_VAR(__x86_stuffs_count);
# define CALL_THUNKS_DEBUG_INC_CTXSW \
- incq %gs:__x86_ctxsw_count;
+ incq PER_CPU_VAR(__x86_ctxsw_count);
#else
# define CALL_THUNKS_DEBUG_INC_CALLS
# define CALL_THUNKS_DEBUG_INC_RETS
@@ -73,16 +73,13 @@
# define CALL_THUNKS_DEBUG_INC_CTXSW
#endif
-#if defined(CONFIG_CALL_DEPTH_TRACKING) && !defined(COMPILE_OFFSETS)
+#if defined(CONFIG_MITIGATION_CALL_DEPTH_TRACKING) && !defined(COMPILE_OFFSETS)
#include <asm/asm-offsets.h>
#define CREDIT_CALL_DEPTH \
movq $-1, PER_CPU_VAR(pcpu_hot + X86_call_depth);
-#define ASM_CREDIT_CALL_DEPTH \
- movq $-1, PER_CPU_VAR(pcpu_hot + X86_call_depth);
-
#define RESET_CALL_DEPTH \
xor %eax, %eax; \
bts $63, %rax; \
@@ -95,20 +92,14 @@
CALL_THUNKS_DEBUG_INC_CALLS
#define INCREMENT_CALL_DEPTH \
- sarq $5, %gs:pcpu_hot + X86_call_depth; \
- CALL_THUNKS_DEBUG_INC_CALLS
-
-#define ASM_INCREMENT_CALL_DEPTH \
sarq $5, PER_CPU_VAR(pcpu_hot + X86_call_depth); \
CALL_THUNKS_DEBUG_INC_CALLS
#else
#define CREDIT_CALL_DEPTH
-#define ASM_CREDIT_CALL_DEPTH
#define RESET_CALL_DEPTH
-#define INCREMENT_CALL_DEPTH
-#define ASM_INCREMENT_CALL_DEPTH
#define RESET_CALL_DEPTH_FROM_CALL
+#define INCREMENT_CALL_DEPTH
#endif
/*
@@ -158,7 +149,7 @@
jnz 771b; \
/* barrier for jnz misprediction */ \
lfence; \
- ASM_CREDIT_CALL_DEPTH \
+ CREDIT_CALL_DEPTH \
CALL_THUNKS_DEBUG_INC_CTXSW
#else
/*
@@ -212,7 +203,7 @@
*/
.macro VALIDATE_UNRET_END
#if defined(CONFIG_NOINSTR_VALIDATION) && \
- (defined(CONFIG_CPU_UNRET_ENTRY) || defined(CONFIG_CPU_SRSO))
+ (defined(CONFIG_MITIGATION_UNRET_ENTRY) || defined(CONFIG_MITIGATION_SRSO))
ANNOTATE_RETPOLINE_SAFE
nop
#endif
@@ -241,7 +232,7 @@
* instruction irrespective of kCFI.
*/
.macro JMP_NOSPEC reg:req
-#ifdef CONFIG_RETPOLINE
+#ifdef CONFIG_MITIGATION_RETPOLINE
__CS_PREFIX \reg
jmp __x86_indirect_thunk_\reg
#else
@@ -251,7 +242,7 @@
.endm
.macro CALL_NOSPEC reg:req
-#ifdef CONFIG_RETPOLINE
+#ifdef CONFIG_MITIGATION_RETPOLINE
__CS_PREFIX \reg
call __x86_indirect_thunk_\reg
#else
@@ -271,11 +262,20 @@
.Lskip_rsb_\@:
.endm
-#if defined(CONFIG_CPU_UNRET_ENTRY) || defined(CONFIG_CPU_SRSO)
-#define CALL_UNTRAIN_RET "call entry_untrain_ret"
-#else
-#define CALL_UNTRAIN_RET ""
+/*
+ * The CALL to srso_alias_untrain_ret() must be patched in directly at
+ * the spot where untraining must be done, ie., srso_alias_untrain_ret()
+ * must be the target of a CALL instruction instead of indirectly
+ * jumping to a wrapper which then calls it. Therefore, this macro is
+ * called outside of __UNTRAIN_RET below, for the time being, before the
+ * kernel can support nested alternatives with arbitrary nesting.
+ */
+.macro CALL_UNTRAIN_RET
+#if defined(CONFIG_MITIGATION_UNRET_ENTRY) || defined(CONFIG_MITIGATION_SRSO)
+ ALTERNATIVE_2 "", "call entry_untrain_ret", X86_FEATURE_UNRET, \
+ "call srso_alias_untrain_ret", X86_FEATURE_SRSO_ALIAS
#endif
+.endm
/*
* Mitigate RETBleed for AMD/Hygon Zen uarch. Requires KERNEL CR3 because the
@@ -289,10 +289,10 @@
* where we have a stack but before any RET instruction.
*/
.macro __UNTRAIN_RET ibpb_feature, call_depth_insns
-#if defined(CONFIG_RETHUNK) || defined(CONFIG_CPU_IBPB_ENTRY)
+#if defined(CONFIG_MITIGATION_RETHUNK) || defined(CONFIG_MITIGATION_IBPB_ENTRY)
VALIDATE_UNRET_END
- ALTERNATIVE_3 "", \
- CALL_UNTRAIN_RET, X86_FEATURE_UNRET, \
+ CALL_UNTRAIN_RET
+ ALTERNATIVE_2 "", \
"call entry_ibpb", \ibpb_feature, \
__stringify(\call_depth_insns), X86_FEATURE_CALL_DEPTH
#endif
@@ -309,9 +309,9 @@
.macro CALL_DEPTH_ACCOUNT
-#ifdef CONFIG_CALL_DEPTH_TRACKING
+#ifdef CONFIG_MITIGATION_CALL_DEPTH_TRACKING
ALTERNATIVE "", \
- __stringify(ASM_INCREMENT_CALL_DEPTH), X86_FEATURE_CALL_DEPTH
+ __stringify(INCREMENT_CALL_DEPTH), X86_FEATURE_CALL_DEPTH
#endif
.endm
@@ -326,6 +326,19 @@
ALTERNATIVE "", __stringify(verw _ASM_RIP(mds_verw_sel)), X86_FEATURE_CLEAR_CPU_BUF
.endm
+#ifdef CONFIG_X86_64
+.macro CLEAR_BRANCH_HISTORY
+ ALTERNATIVE "", "call clear_bhb_loop", X86_FEATURE_CLEAR_BHB_LOOP
+.endm
+
+.macro CLEAR_BRANCH_HISTORY_VMEXIT
+ ALTERNATIVE "", "call clear_bhb_loop", X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT
+.endm
+#else
+#define CLEAR_BRANCH_HISTORY
+#define CLEAR_BRANCH_HISTORY_VMEXIT
+#endif
+
#else /* __ASSEMBLY__ */
#define ANNOTATE_RETPOLINE_SAFE \
@@ -339,19 +352,21 @@ extern retpoline_thunk_t __x86_indirect_thunk_array[];
extern retpoline_thunk_t __x86_indirect_call_thunk_array[];
extern retpoline_thunk_t __x86_indirect_jump_thunk_array[];
-#ifdef CONFIG_RETHUNK
+#ifdef CONFIG_MITIGATION_RETHUNK
extern void __x86_return_thunk(void);
#else
static inline void __x86_return_thunk(void) {}
#endif
-#ifdef CONFIG_CPU_UNRET_ENTRY
+#ifdef CONFIG_MITIGATION_UNRET_ENTRY
extern void retbleed_return_thunk(void);
#else
static inline void retbleed_return_thunk(void) {}
#endif
-#ifdef CONFIG_CPU_SRSO
+extern void srso_alias_untrain_ret(void);
+
+#ifdef CONFIG_MITIGATION_SRSO
extern void srso_return_thunk(void);
extern void srso_alias_return_thunk(void);
#else
@@ -366,9 +381,15 @@ extern void srso_alias_return_thunk(void);
extern void entry_untrain_ret(void);
extern void entry_ibpb(void);
+#ifdef CONFIG_X86_64
+extern void clear_bhb_loop(void);
+#endif
+
extern void (*x86_return_thunk)(void);
-#ifdef CONFIG_CALL_DEPTH_TRACKING
+extern void __warn_thunk(void);
+
+#ifdef CONFIG_MITIGATION_CALL_DEPTH_TRACKING
extern void call_depth_return_thunk(void);
#define CALL_DEPTH_ACCOUNT \
@@ -382,14 +403,14 @@ DECLARE_PER_CPU(u64, __x86_ret_count);
DECLARE_PER_CPU(u64, __x86_stuffs_count);
DECLARE_PER_CPU(u64, __x86_ctxsw_count);
#endif
-#else /* !CONFIG_CALL_DEPTH_TRACKING */
+#else /* !CONFIG_MITIGATION_CALL_DEPTH_TRACKING */
static inline void call_depth_return_thunk(void) {}
#define CALL_DEPTH_ACCOUNT ""
-#endif /* CONFIG_CALL_DEPTH_TRACKING */
+#endif /* CONFIG_MITIGATION_CALL_DEPTH_TRACKING */
-#ifdef CONFIG_RETPOLINE
+#ifdef CONFIG_MITIGATION_RETPOLINE
#define GEN(reg) \
extern retpoline_thunk_t __x86_indirect_thunk_ ## reg;
@@ -410,7 +431,7 @@ static inline void call_depth_return_thunk(void) {}
/*
* Inline asm uses the %V modifier which is only in newer GCC
- * which is ensured when CONFIG_RETPOLINE is defined.
+ * which is ensured when CONFIG_MITIGATION_RETPOLINE is defined.
*/
# define CALL_NOSPEC \
ALTERNATIVE_2( \
diff --git a/arch/x86/include/asm/page.h b/arch/x86/include/asm/page.h
index d18e5c332cb9..1b93ff80b43b 100644
--- a/arch/x86/include/asm/page.h
+++ b/arch/x86/include/asm/page.h
@@ -66,10 +66,14 @@ static inline void copy_user_page(void *to, void *from, unsigned long vaddr,
* virt_addr_valid(kaddr) returns true.
*/
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
-#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
extern bool __virt_addr_valid(unsigned long kaddr);
#define virt_addr_valid(kaddr) __virt_addr_valid((unsigned long) (kaddr))
+static __always_inline void *pfn_to_kaddr(unsigned long pfn)
+{
+ return __va(pfn << PAGE_SHIFT);
+}
+
static __always_inline u64 __canonical_address(u64 vaddr, u8 vaddr_bits)
{
return ((s64)vaddr << (64 - vaddr_bits)) >> (64 - vaddr_bits);
diff --git a/arch/x86/include/asm/page_types.h b/arch/x86/include/asm/page_types.h
index 86bd4311daf8..9da9c8a2f1df 100644
--- a/arch/x86/include/asm/page_types.h
+++ b/arch/x86/include/asm/page_types.h
@@ -7,7 +7,7 @@
#include <linux/mem_encrypt.h>
/* PAGE_SHIFT determines the page size */
-#define PAGE_SHIFT 12
+#define PAGE_SHIFT CONFIG_PAGE_SHIFT
#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index b40c462b4af3..b3ab80a03365 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -10,7 +10,6 @@
#include <linux/numa.h>
#include <asm/io.h>
#include <asm/memtype.h>
-#include <asm/x86_init.h>
struct pci_sysdata {
int domain; /* PCI domain */
@@ -124,16 +123,4 @@ cpumask_of_pcibus(const struct pci_bus *bus)
}
#endif
-struct pci_setup_rom {
- struct setup_data data;
- uint16_t vendor;
- uint16_t devid;
- uint64_t pcilen;
- unsigned long segment;
- unsigned long bus;
- unsigned long device;
- unsigned long function;
- uint8_t romdata[];
-};
-
#endif /* _ASM_X86_PCI_H */
diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h
index 5e01883eb51e..44958ebaf626 100644
--- a/arch/x86/include/asm/percpu.h
+++ b/arch/x86/include/asm/percpu.h
@@ -4,17 +4,21 @@
#ifdef CONFIG_X86_64
#define __percpu_seg gs
+#define __percpu_rel (%rip)
#else
#define __percpu_seg fs
+#define __percpu_rel
#endif
#ifdef __ASSEMBLY__
#ifdef CONFIG_SMP
-#define PER_CPU_VAR(var) %__percpu_seg:var
-#else /* ! SMP */
-#define PER_CPU_VAR(var) var
-#endif /* SMP */
+#define __percpu %__percpu_seg:
+#else
+#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
@@ -24,30 +28,84 @@
#else /* ...!ASSEMBLY */
+#include <linux/build_bug.h>
#include <linux/stringify.h>
#include <asm/asm.h>
#ifdef CONFIG_SMP
+
+#ifdef CONFIG_CC_HAS_NAMED_AS
+
+#ifdef __CHECKER__
+#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
+#else
+#define __percpu_seg_override __seg_fs
+#endif
+
+#define __percpu_prefix ""
+
+#else /* CONFIG_CC_HAS_NAMED_AS */
+
+#define __percpu_seg_override
#define __percpu_prefix "%%"__stringify(__percpu_seg)":"
+
+#endif /* CONFIG_CC_HAS_NAMED_AS */
+
+#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.
*/
-#define arch_raw_cpu_ptr(ptr) \
-({ \
- unsigned long tcp_ptr__; \
- asm ("add " __percpu_arg(1) ", %0" \
- : "=r" (tcp_ptr__) \
- : "m" (this_cpu_off), "0" (ptr)); \
- (typeof(*(ptr)) __kernel __force *)tcp_ptr__; \
+#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__; \
})
-#else
+#endif /* CONFIG_USE_X86_SEG_SUPPORT */
+
+#define PER_CPU_VAR(var) %__percpu_seg:(var)__percpu_rel
+
+#else /* CONFIG_SMP */
+#define __percpu_seg_override
#define __percpu_prefix ""
-#endif
+#define __force_percpu_prefix ""
+
+#define PER_CPU_VAR(var) (var)__percpu_rel
+#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 __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
@@ -107,14 +165,14 @@ do { \
(void)pto_tmp__; \
} \
asm qual(__pcpu_op2_##size(op, "%[val]", __percpu_arg([var])) \
- : [var] "+m" (_var) \
+ : [var] "+m" (__my_cpu_var(_var)) \
: [val] __pcpu_reg_imm_##size(pto_val__)); \
} while (0)
#define percpu_unary_op(size, qual, op, _var) \
({ \
asm qual (__pcpu_op1_##size(op, __percpu_arg([var])) \
- : [var] "+m" (_var)); \
+ : [var] "+m" (__my_cpu_var(_var))); \
})
/*
@@ -144,16 +202,16 @@ do { \
__pcpu_type_##size pfo_val__; \
asm qual (__pcpu_op2_##size(op, __percpu_arg([var]), "%[val]") \
: [val] __pcpu_reg_##size("=", pfo_val__) \
- : [var] "m" (_var)); \
+ : [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, __percpu_arg(P[var]), "%[val]") \
+ asm(__pcpu_op2_##size(op, __force_percpu_arg(a[var]), "%[val]") \
: [val] __pcpu_reg_##size("=", pfo_val__) \
- : [var] "p" (&(_var))); \
+ : [var] "i" (&(_var))); \
(typeof(_var))(unsigned long) pfo_val__; \
})
@@ -166,7 +224,7 @@ do { \
asm qual (__pcpu_op2_##size("xadd", "%[tmp]", \
__percpu_arg([var])) \
: [tmp] __pcpu_reg_##size("+", paro_tmp__), \
- [var] "+m" (_var) \
+ [var] "+m" (__my_cpu_var(_var)) \
: : "memory"); \
(typeof(_var))(unsigned long) (paro_tmp__ + _val); \
})
@@ -187,7 +245,7 @@ do { \
__percpu_arg([var])) \
"\n\tjnz 1b" \
: [oval] "=&a" (pxo_old__), \
- [var] "+m" (_var) \
+ [var] "+m" (__my_cpu_var(_var)) \
: [nval] __pcpu_reg_##size(, pxo_new__) \
: "memory"); \
(typeof(_var))(unsigned long) pxo_old__; \
@@ -204,7 +262,7 @@ do { \
asm qual (__pcpu_op2_##size("cmpxchg", "%[nval]", \
__percpu_arg([var])) \
: [oval] "+a" (pco_old__), \
- [var] "+m" (_var) \
+ [var] "+m" (__my_cpu_var(_var)) \
: [nval] __pcpu_reg_##size(, pco_new__) \
: "memory"); \
(typeof(_var))(unsigned long) pco_old__; \
@@ -221,7 +279,7 @@ do { \
CC_SET(z) \
: CC_OUT(z) (success), \
[oval] "+a" (pco_old__), \
- [var] "+m" (_var) \
+ [var] "+m" (__my_cpu_var(_var)) \
: [nval] __pcpu_reg_##size(, pco_new__) \
: "memory"); \
if (unlikely(!success)) \
@@ -244,7 +302,7 @@ do { \
\
asm qual (ALTERNATIVE("call this_cpu_cmpxchg8b_emu", \
"cmpxchg8b " __percpu_arg([var]), X86_FEATURE_CX8) \
- : [var] "+m" (_var), \
+ : [var] "+m" (__my_cpu_var(_var)), \
"+a" (old__.low), \
"+d" (old__.high) \
: "b" (new__.low), \
@@ -276,7 +334,7 @@ do { \
"cmpxchg8b " __percpu_arg([var]), X86_FEATURE_CX8) \
CC_SET(z) \
: CC_OUT(z) (success), \
- [var] "+m" (_var), \
+ [var] "+m" (__my_cpu_var(_var)), \
"+a" (old__.low), \
"+d" (old__.high) \
: "b" (new__.low), \
@@ -313,7 +371,7 @@ do { \
\
asm qual (ALTERNATIVE("call this_cpu_cmpxchg16b_emu", \
"cmpxchg16b " __percpu_arg([var]), X86_FEATURE_CX16) \
- : [var] "+m" (_var), \
+ : [var] "+m" (__my_cpu_var(_var)), \
"+a" (old__.low), \
"+d" (old__.high) \
: "b" (new__.low), \
@@ -345,7 +403,7 @@ do { \
"cmpxchg16b " __percpu_arg([var]), X86_FEATURE_CX16) \
CC_SET(z) \
: CC_OUT(z) (success), \
- [var] "+m" (_var), \
+ [var] "+m" (__my_cpu_var(_var)), \
"+a" (old__.low), \
"+d" (old__.high) \
: "b" (new__.low), \
@@ -366,9 +424,9 @@ do { \
* 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
- * get_current() and get_thread_info() both of which are actually
- * per-thread variables implemented as per-cpu variables and thus
- * stable for the duration of the respective task.
+ * 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_stable_1(pcp) percpu_stable_op(1, "mov", pcp)
#define this_cpu_read_stable_2(pcp) percpu_stable_op(2, "mov", pcp)
@@ -376,13 +434,72 @@ do { \
#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_USE_X86_SEG_SUPPORT
+
+#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 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_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)
+
+#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_read_8(pcp) __raw_cpu_read(volatile, pcp)
+#define this_cpu_write_8(pcp, val) __raw_cpu_write(volatile, pcp, val)
+#endif
+
+#define this_cpu_read_const(pcp) __raw_cpu_read(, pcp)
+#else /* CONFIG_USE_X86_SEG_SUPPORT */
+
#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)
+
+#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)
+
+#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)
+
+#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
+
+/*
+ * The generic per-cpu infrastrucutre is not suitable for
+ * reading const-qualified variables.
+ */
+#define this_cpu_read_const(pcp) ({ BUILD_BUG(); (typeof(pcp))0; })
+#endif /* CONFIG_USE_X86_SEG_SUPPORT */
+
#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)
@@ -408,12 +525,6 @@ do { \
#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_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 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)
@@ -452,8 +563,6 @@ do { \
* 32 bit must fall back to generic operations.
*/
#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)
#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)
@@ -462,8 +571,6 @@ do { \
#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_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)
#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)
@@ -494,7 +601,7 @@ static inline bool x86_this_cpu_variable_test_bit(int nr,
asm volatile("btl "__percpu_arg(2)",%1"
CC_SET(c)
: CC_OUT(c) (oldbit)
- : "m" (*(unsigned long __percpu *)addr), "Ir" (nr));
+ : "m" (*__my_cpu_ptr((unsigned long __percpu *)(addr))), "Ir" (nr));
return oldbit;
}
diff --git a/arch/x86/include/asm/perf_event_p4.h b/arch/x86/include/asm/perf_event_p4.h
index 94de1a05aeba..d65e338b6a5f 100644
--- a/arch/x86/include/asm/perf_event_p4.h
+++ b/arch/x86/include/asm/perf_event_p4.h
@@ -181,7 +181,7 @@ static inline u64 p4_clear_ht_bit(u64 config)
static inline int p4_ht_active(void)
{
#ifdef CONFIG_SMP
- return smp_num_siblings > 1;
+ return __max_threads_per_core > 1;
#endif
return 0;
}
@@ -189,7 +189,7 @@ static inline int p4_ht_active(void)
static inline int p4_ht_thread(int cpu)
{
#ifdef CONFIG_SMP
- if (smp_num_siblings == 2)
+ if (__max_threads_per_core == 2)
return cpu != cpumask_first(this_cpu_cpumask_var_ptr(cpu_sibling_map));
#endif
return 0;
diff --git a/arch/x86/include/asm/pgalloc.h b/arch/x86/include/asm/pgalloc.h
index c7ec5bb88334..dcd836b59beb 100644
--- a/arch/x86/include/asm/pgalloc.h
+++ b/arch/x86/include/asm/pgalloc.h
@@ -34,7 +34,7 @@ static inline void paravirt_release_p4d(unsigned long pfn) {}
*/
extern gfp_t __userpte_alloc_gfp;
-#ifdef CONFIG_PAGE_TABLE_ISOLATION
+#ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
/*
* Instead of one PGD, we acquire two PGDs. Being order-1, it is
* both 8k in size and 8k-aligned. That lets us just flip bit 12
diff --git a/arch/x86/include/asm/pgtable-3level.h b/arch/x86/include/asm/pgtable-3level.h
index 9e7c0b719c3c..dabafba957ea 100644
--- a/arch/x86/include/asm/pgtable-3level.h
+++ b/arch/x86/include/asm/pgtable-3level.h
@@ -52,7 +52,7 @@ static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
static inline void native_set_pud(pud_t *pudp, pud_t pud)
{
-#ifdef CONFIG_PAGE_TABLE_ISOLATION
+#ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
pud.p4d.pgd = pti_set_user_pgtbl(&pudp->p4d.pgd, pud.p4d.pgd);
#endif
pxx_xchg64(pud, pudp, native_pud_val(pud));
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index 9d077bca6a10..315535ffb258 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -31,7 +31,8 @@ struct seq_file;
void ptdump_walk_pgd_level(struct seq_file *m, struct mm_struct *mm);
void ptdump_walk_pgd_level_debugfs(struct seq_file *m, struct mm_struct *mm,
bool user);
-void ptdump_walk_pgd_level_checkwx(void);
+bool ptdump_walk_pgd_level_checkwx(void);
+#define ptdump_check_wx ptdump_walk_pgd_level_checkwx
void ptdump_walk_user_pgd_level_checkwx(void);
/*
@@ -41,10 +42,8 @@ void ptdump_walk_user_pgd_level_checkwx(void);
#define pgprot_decrypted(prot) __pgprot(cc_mkdec(pgprot_val(prot)))
#ifdef CONFIG_DEBUG_WX
-#define debug_checkwx() ptdump_walk_pgd_level_checkwx()
#define debug_checkwx_user() ptdump_walk_user_pgd_level_checkwx()
#else
-#define debug_checkwx() do { } while (0)
#define debug_checkwx_user() do { } while (0)
#endif
@@ -252,8 +251,8 @@ static inline unsigned long pgd_pfn(pgd_t pgd)
return (pgd_val(pgd) & PTE_PFN_MASK) >> PAGE_SHIFT;
}
-#define p4d_leaf p4d_large
-static inline int p4d_large(p4d_t p4d)
+#define p4d_leaf p4d_leaf
+static inline bool p4d_leaf(p4d_t p4d)
{
/* No 512 GiB pages yet */
return 0;
@@ -261,14 +260,14 @@ static inline int p4d_large(p4d_t p4d)
#define pte_page(pte) pfn_to_page(pte_pfn(pte))
-#define pmd_leaf pmd_large
-static inline int pmd_large(pmd_t pte)
+#define pmd_leaf pmd_leaf
+static inline bool pmd_leaf(pmd_t pte)
{
return pmd_flags(pte) & _PAGE_PSE;
}
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
-/* NOTE: when predicate huge page, consider also pmd_devmap, or use pmd_large */
+/* NOTE: when predicate huge page, consider also pmd_devmap, or use pmd_leaf */
static inline int pmd_trans_huge(pmd_t pmd)
{
return (pmd_val(pmd) & (_PAGE_PSE|_PAGE_DEVMAP)) == _PAGE_PSE;
@@ -909,7 +908,7 @@ static inline int is_new_memtype_allowed(u64 paddr, unsigned long size,
pmd_t *populate_extra_pmd(unsigned long vaddr);
pte_t *populate_extra_pte(unsigned long vaddr);
-#ifdef CONFIG_PAGE_TABLE_ISOLATION
+#ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
pgd_t __pti_set_user_pgtbl(pgd_t *pgdp, pgd_t pgd);
/*
@@ -923,12 +922,12 @@ static inline pgd_t pti_set_user_pgtbl(pgd_t *pgdp, pgd_t pgd)
return pgd;
return __pti_set_user_pgtbl(pgdp, pgd);
}
-#else /* CONFIG_PAGE_TABLE_ISOLATION */
+#else /* CONFIG_MITIGATION_PAGE_TABLE_ISOLATION */
static inline pgd_t pti_set_user_pgtbl(pgd_t *pgdp, pgd_t pgd)
{
return pgd;
}
-#endif /* CONFIG_PAGE_TABLE_ISOLATION */
+#endif /* CONFIG_MITIGATION_PAGE_TABLE_ISOLATION */
#endif /* __ASSEMBLY__ */
@@ -956,13 +955,13 @@ static inline int pte_same(pte_t a, pte_t b)
return a.pte == b.pte;
}
-static inline pte_t pte_next_pfn(pte_t pte)
+static inline pte_t pte_advance_pfn(pte_t pte, unsigned long nr)
{
if (__pte_needs_invert(pte_val(pte)))
- return __pte(pte_val(pte) - (1UL << PFN_PTE_SHIFT));
- return __pte(pte_val(pte) + (1UL << PFN_PTE_SHIFT));
+ return __pte(pte_val(pte) - (nr << PFN_PTE_SHIFT));
+ return __pte(pte_val(pte) + (nr << PFN_PTE_SHIFT));
}
-#define pte_next_pfn pte_next_pfn
+#define pte_advance_pfn pte_advance_pfn
static inline int pte_present(pte_t a)
{
@@ -1086,8 +1085,8 @@ static inline pmd_t *pud_pgtable(pud_t pud)
*/
#define pud_page(pud) pfn_to_page(pud_pfn(pud))
-#define pud_leaf pud_large
-static inline int pud_large(pud_t pud)
+#define pud_leaf pud_leaf
+static inline bool pud_leaf(pud_t pud)
{
return (pud_val(pud) & (_PAGE_PSE | _PAGE_PRESENT)) ==
(_PAGE_PSE | _PAGE_PRESENT);
@@ -1097,12 +1096,6 @@ static inline int pud_bad(pud_t pud)
{
return (pud_flags(pud) & ~(_KERNPG_TABLE | _PAGE_USER)) != 0;
}
-#else
-#define pud_leaf pud_large
-static inline int pud_large(pud_t pud)
-{
- return 0;
-}
#endif /* CONFIG_PGTABLE_LEVELS > 2 */
#if CONFIG_PGTABLE_LEVELS > 3
@@ -1131,7 +1124,7 @@ static inline int p4d_bad(p4d_t p4d)
{
unsigned long ignore_flags = _KERNPG_TABLE | _PAGE_USER;
- if (IS_ENABLED(CONFIG_PAGE_TABLE_ISOLATION))
+ if (IS_ENABLED(CONFIG_MITIGATION_PAGE_TABLE_ISOLATION))
ignore_flags |= _PAGE_NX;
return (p4d_flags(p4d) & ~ignore_flags) != 0;
@@ -1177,7 +1170,7 @@ static inline int pgd_bad(pgd_t pgd)
if (!pgtable_l5_enabled())
return 0;
- if (IS_ENABLED(CONFIG_PAGE_TABLE_ISOLATION))
+ if (IS_ENABLED(CONFIG_MITIGATION_PAGE_TABLE_ISOLATION))
ignore_flags |= _PAGE_NX;
return (pgd_flags(pgd) & ~ignore_flags) != _KERNPG_TABLE;
@@ -1419,12 +1412,12 @@ static inline bool pgdp_maps_userspace(void *__ptr)
return (((ptr & ~PAGE_MASK) / sizeof(pgd_t)) < PGD_KERNEL_START);
}
-#define pgd_leaf pgd_large
-static inline int pgd_large(pgd_t pgd) { return 0; }
+#define pgd_leaf pgd_leaf
+static inline bool pgd_leaf(pgd_t pgd) { return false; }
-#ifdef CONFIG_PAGE_TABLE_ISOLATION
+#ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
/*
- * All top-level PAGE_TABLE_ISOLATION page tables are order-1 pages
+ * All top-level MITIGATION_PAGE_TABLE_ISOLATION page tables are order-1 pages
* (8k-aligned and 8k in size). The kernel one is at the beginning 4k and
* the user one is in the last 4k. To switch between them, you
* just need to flip the 12th bit in their addresses.
@@ -1469,7 +1462,7 @@ static inline p4d_t *user_to_kernel_p4dp(p4d_t *p4dp)
{
return ptr_clear_bit(p4dp, PTI_PGTABLE_SWITCH_BIT);
}
-#endif /* CONFIG_PAGE_TABLE_ISOLATION */
+#endif /* CONFIG_MITIGATION_PAGE_TABLE_ISOLATION */
/*
* clone_pgd_range(pgd_t *dst, pgd_t *src, int count);
@@ -1484,7 +1477,7 @@ static inline p4d_t *user_to_kernel_p4dp(p4d_t *p4dp)
static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
{
memcpy(dst, src, count * sizeof(pgd_t));
-#ifdef CONFIG_PAGE_TABLE_ISOLATION
+#ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
if (!static_cpu_has(X86_FEATURE_PTI))
return;
/* Clone the user space pgd as well */
diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h
index 24af25b1551a..7e9db77231ac 100644
--- a/arch/x86/include/asm/pgtable_64.h
+++ b/arch/x86/include/asm/pgtable_64.h
@@ -143,7 +143,8 @@ static inline void native_set_p4d(p4d_t *p4dp, p4d_t p4d)
{
pgd_t pgd;
- if (pgtable_l5_enabled() || !IS_ENABLED(CONFIG_PAGE_TABLE_ISOLATION)) {
+ if (pgtable_l5_enabled() ||
+ !IS_ENABLED(CONFIG_MITIGATION_PAGE_TABLE_ISOLATION)) {
WRITE_ONCE(*p4dp, p4d);
return;
}
diff --git a/arch/x86/include/asm/pgtable_64_types.h b/arch/x86/include/asm/pgtable_64_types.h
index 38b54b992f32..9053dfe9fa03 100644
--- a/arch/x86/include/asm/pgtable_64_types.h
+++ b/arch/x86/include/asm/pgtable_64_types.h
@@ -21,9 +21,9 @@ typedef unsigned long pgprotval_t;
typedef struct { pteval_t pte; } pte_t;
typedef struct { pmdval_t pmd; } pmd_t;
-#ifdef CONFIG_X86_5LEVEL
extern unsigned int __pgtable_l5_enabled;
+#ifdef CONFIG_X86_5LEVEL
#ifdef USE_EARLY_PGTABLE_L5
/*
* cpu_feature_enabled() is not available in early boot code.
diff --git a/arch/x86/include/asm/preempt.h b/arch/x86/include/asm/preempt.h
index af77235fded6..919909d8cb77 100644
--- a/arch/x86/include/asm/preempt.h
+++ b/arch/x86/include/asm/preempt.h
@@ -91,7 +91,7 @@ static __always_inline void __preempt_count_sub(int val)
*/
static __always_inline bool __preempt_count_dec_and_test(void)
{
- return GEN_UNARY_RMWcc("decl", pcpu_hot.preempt_count, e,
+ return GEN_UNARY_RMWcc("decl", __my_cpu_var(pcpu_hot.preempt_count), e,
__percpu_arg([var]));
}
diff --git a/arch/x86/include/asm/processor-flags.h b/arch/x86/include/asm/processor-flags.h
index d8cccadc83a6..e5f204b9b33d 100644
--- a/arch/x86/include/asm/processor-flags.h
+++ b/arch/x86/include/asm/processor-flags.h
@@ -51,7 +51,7 @@
#define CR3_NOFLUSH 0
#endif
-#ifdef CONFIG_PAGE_TABLE_ISOLATION
+#ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
# define X86_CR3_PTI_PCID_USER_BIT 11
#endif
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 26620d7642a9..811548f131f4 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -20,7 +20,6 @@ struct vm86;
#include <asm/page.h>
#include <asm/pgtable_types.h>
#include <asm/percpu.h>
-#include <asm/msr.h>
#include <asm/desc_defs.h>
#include <asm/nops.h>
#include <asm/special_insns.h>
@@ -100,6 +99,9 @@ struct cpuinfo_topology {
u32 logical_pkg_id;
u32 logical_die_id;
+ // AMD Node ID and Nodes per Package info
+ u32 amd_node_id;
+
// Cache level topology IDs
u32 llc_id;
u32 l2c_id;
@@ -119,8 +121,6 @@ struct cpuinfo_x86 {
#endif
__u8 x86_virt_bits;
__u8 x86_phys_bits;
- /* CPUID returned core id bits: */
- __u8 x86_coreid_bits;
/* Max extended CPUID function supported: */
__u32 extended_cpuid_level;
/* Maximum supported CPUID level, -1=no CPUID: */
@@ -148,8 +148,6 @@ struct cpuinfo_x86 {
unsigned long loops_per_jiffy;
/* protected processor identification number */
u64 ppin;
- /* cpuid returned max cores value: */
- u16 x86_max_cores;
u16 x86_clflush_size;
/* number of cores as seen by the OS: */
u16 booted_cores;
@@ -186,13 +184,8 @@ extern struct cpuinfo_x86 new_cpu_data;
extern __u32 cpu_caps_cleared[NCAPINTS + NBUGINTS];
extern __u32 cpu_caps_set[NCAPINTS + NBUGINTS];
-#ifdef CONFIG_SMP
DECLARE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info);
#define cpu_data(cpu) per_cpu(cpu_info, cpu)
-#else
-#define cpu_info boot_cpu_data
-#define cpu_data(cpu) boot_cpu_data
-#endif
extern const struct seq_operations cpuinfo_op;
@@ -533,6 +526,9 @@ static __always_inline unsigned long current_top_of_stack(void)
* and around vm86 mode and sp0 on x86_64 is special because of the
* entry trampoline.
*/
+ if (IS_ENABLED(CONFIG_USE_X86_SEG_SUPPORT))
+ return this_cpu_read_const(const_pcpu_hot.top_of_stack);
+
return this_cpu_read_stable(pcpu_hot.top_of_stack);
}
@@ -555,7 +551,7 @@ static inline void load_sp0(unsigned long sp0)
unsigned long __get_wchan(struct task_struct *p);
-extern void select_idle_routine(const struct cpuinfo_x86 *c);
+extern void select_idle_routine(void);
extern void amd_e400_c1e_apic_setup(void);
extern unsigned long boot_option_idle_override;
@@ -576,28 +572,6 @@ extern void cpu_init(void);
extern void cpu_init_exception_handling(void);
extern void cr4_init(void);
-static inline unsigned long get_debugctlmsr(void)
-{
- unsigned long debugctlmsr = 0;
-
-#ifndef CONFIG_X86_DEBUGCTLMSR
- if (boot_cpu_data.x86 < 6)
- return 0;
-#endif
- rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctlmsr);
-
- return debugctlmsr;
-}
-
-static inline void update_debugctlmsr(unsigned long debugctlmsr)
-{
-#ifndef CONFIG_X86_DEBUGCTLMSR
- if (boot_cpu_data.x86 < 6)
- return;
-#endif
- wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctlmsr);
-}
-
extern void set_task_blockstep(struct task_struct *task, bool on);
/* Boot loader type from the setup header: */
@@ -664,8 +638,10 @@ static __always_inline void prefetchw(const void *x)
#else
extern unsigned long __end_init_task[];
-#define INIT_THREAD { \
- .sp = (unsigned long)&__end_init_task - sizeof(struct pt_regs), \
+#define INIT_THREAD { \
+ .sp = (unsigned long)&__end_init_task - \
+ TOP_OF_KERNEL_STACK_PADDING - \
+ sizeof(struct pt_regs), \
}
extern unsigned long KSTK_ESP(struct task_struct *task);
@@ -704,12 +680,10 @@ static inline u32 per_cpu_l2c_id(unsigned int cpu)
}
#ifdef CONFIG_CPU_SUP_AMD
-extern u32 amd_get_nodes_per_socket(void);
extern u32 amd_get_highest_perf(void);
extern void amd_clear_divider(void);
extern void amd_check_microcode(void);
#else
-static inline u32 amd_get_nodes_per_socket(void) { return 0; }
static inline u32 amd_get_highest_perf(void) { return 0; }
static inline void amd_clear_divider(void) { }
static inline void amd_check_microcode(void) { }
diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
index 65dee2420624..043758a2e627 100644
--- a/arch/x86/include/asm/prom.h
+++ b/arch/x86/include/asm/prom.h
@@ -23,11 +23,11 @@ extern int of_ioapic;
extern u64 initial_dtb;
extern void add_dtb(u64 data);
void x86_of_pci_init(void);
-void x86_dtb_init(void);
+void x86_dtb_parse_smp_config(void);
#else
static inline void add_dtb(u64 data) { }
static inline void x86_of_pci_init(void) { }
-static inline void x86_dtb_init(void) { }
+static inline void x86_dtb_parse_smp_config(void) { }
#define of_ioapic 0
#endif
diff --git a/arch/x86/include/asm/pti.h b/arch/x86/include/asm/pti.h
index 07375b476c4f..ab167c96b9ab 100644
--- a/arch/x86/include/asm/pti.h
+++ b/arch/x86/include/asm/pti.h
@@ -3,7 +3,7 @@
#define _ASM_X86_PTI_H
#ifndef __ASSEMBLY__
-#ifdef CONFIG_PAGE_TABLE_ISOLATION
+#ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
extern void pti_init(void);
extern void pti_check_boottime_disable(void);
extern void pti_finalize(void);
diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h
index f4db78b09c8f..5a83fbd9bc0b 100644
--- a/arch/x86/include/asm/ptrace.h
+++ b/arch/x86/include/asm/ptrace.h
@@ -56,18 +56,64 @@ struct pt_regs {
#else /* __i386__ */
+struct fred_cs {
+ /* CS selector */
+ u64 cs : 16,
+ /* Stack level at event time */
+ sl : 2,
+ /* IBT in WAIT_FOR_ENDBRANCH state */
+ wfe : 1,
+ : 45;
+};
+
+struct fred_ss {
+ /* SS selector */
+ u64 ss : 16,
+ /* STI state */
+ sti : 1,
+ /* Set if syscall, sysenter or INT n */
+ swevent : 1,
+ /* Event is NMI type */
+ nmi : 1,
+ : 13,
+ /* Event vector */
+ vector : 8,
+ : 8,
+ /* Event type */
+ type : 4,
+ : 4,
+ /* Event was incident to enclave execution */
+ enclave : 1,
+ /* CPU was in long mode */
+ lm : 1,
+ /*
+ * Nested exception during FRED delivery, not set
+ * for #DF.
+ */
+ nested : 1,
+ : 1,
+ /*
+ * The length of the instruction causing the event.
+ * Only set for INTO, INT1, INT3, INT n, SYSCALL
+ * and SYSENTER. 0 otherwise.
+ */
+ insnlen : 4;
+};
+
struct pt_regs {
-/*
- * C ABI says these regs are callee-preserved. They aren't saved on kernel entry
- * unless syscall needs a complete, fully filled "struct pt_regs".
- */
+ /*
+ * C ABI says these regs are callee-preserved. They aren't saved on
+ * kernel entry unless syscall needs a complete, fully filled
+ * "struct pt_regs".
+ */
unsigned long r15;
unsigned long r14;
unsigned long r13;
unsigned long r12;
unsigned long bp;
unsigned long bx;
-/* These regs are callee-clobbered. Always saved on kernel entry. */
+
+ /* These regs are callee-clobbered. Always saved on kernel entry. */
unsigned long r11;
unsigned long r10;
unsigned long r9;
@@ -77,18 +123,50 @@ struct pt_regs {
unsigned long dx;
unsigned long si;
unsigned long di;
-/*
- * On syscall entry, this is syscall#. On CPU exception, this is error code.
- * On hw interrupt, it's IRQ number:
- */
+
+ /*
+ * orig_ax is used on entry for:
+ * - the syscall number (syscall, sysenter, int80)
+ * - error_code stored by the CPU on traps and exceptions
+ * - the interrupt number for device interrupts
+ *
+ * A FRED stack frame starts here:
+ * 1) It _always_ includes an error code;
+ *
+ * 2) The return frame for ERET[US] starts here, but
+ * the content of orig_ax is ignored.
+ */
unsigned long orig_ax;
-/* Return frame for iretq */
+
+ /* The IRETQ return frame starts here */
unsigned long ip;
- unsigned long cs;
+
+ union {
+ /* CS selector */
+ u16 cs;
+ /* The extended 64-bit data slot containing CS */
+ u64 csx;
+ /* The FRED CS extension */
+ struct fred_cs fred_cs;
+ };
+
unsigned long flags;
unsigned long sp;
- unsigned long ss;
-/* top of stack page */
+
+ union {
+ /* SS selector */
+ u16 ss;
+ /* The extended 64-bit data slot containing SS */
+ u64 ssx;
+ /* The FRED SS extension */
+ struct fred_ss fred_ss;
+ };
+
+ /*
+ * Top of stack on IDT systems, while FRED systems have extra fields
+ * defined above for storing exception related information, e.g. CR2 or
+ * DR6.
+ */
};
#endif /* !__i386__ */
diff --git a/arch/x86/include/asm/required-features.h b/arch/x86/include/asm/required-features.h
index 7ba1726b71c7..e9187ddd3d1f 100644
--- a/arch/x86/include/asm/required-features.h
+++ b/arch/x86/include/asm/required-features.h
@@ -99,6 +99,7 @@
#define REQUIRED_MASK18 0
#define REQUIRED_MASK19 0
#define REQUIRED_MASK20 0
-#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 21)
+#define REQUIRED_MASK21 0
+#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 22)
#endif /* _ASM_X86_REQUIRED_FEATURES_H */
diff --git a/arch/x86/include/asm/resctrl.h b/arch/x86/include/asm/resctrl.h
index 255a78d9d906..12dbd2588ca7 100644
--- a/arch/x86/include/asm/resctrl.h
+++ b/arch/x86/include/asm/resctrl.h
@@ -7,6 +7,13 @@
#include <linux/sched.h>
#include <linux/jump_label.h>
+/*
+ * This value can never be a valid CLOSID, and is used when mapping a
+ * (closid, rmid) pair to an index and back. On x86 only the RMID is
+ * needed. The index is a software defined value.
+ */
+#define X86_RESCTRL_EMPTY_CLOSID ((u32)~0)
+
/**
* struct resctrl_pqr_state - State cache for the PQR MSR
* @cur_rmid: The cached Resource Monitoring ID
@@ -31,10 +38,47 @@ struct resctrl_pqr_state {
DECLARE_PER_CPU(struct resctrl_pqr_state, pqr_state);
+extern bool rdt_alloc_capable;
+extern bool rdt_mon_capable;
+
DECLARE_STATIC_KEY_FALSE(rdt_enable_key);
DECLARE_STATIC_KEY_FALSE(rdt_alloc_enable_key);
DECLARE_STATIC_KEY_FALSE(rdt_mon_enable_key);
+static inline bool resctrl_arch_alloc_capable(void)
+{
+ return rdt_alloc_capable;
+}
+
+static inline void resctrl_arch_enable_alloc(void)
+{
+ static_branch_enable_cpuslocked(&rdt_alloc_enable_key);
+ static_branch_inc_cpuslocked(&rdt_enable_key);
+}
+
+static inline void resctrl_arch_disable_alloc(void)
+{
+ static_branch_disable_cpuslocked(&rdt_alloc_enable_key);
+ static_branch_dec_cpuslocked(&rdt_enable_key);
+}
+
+static inline bool resctrl_arch_mon_capable(void)
+{
+ return rdt_mon_capable;
+}
+
+static inline void resctrl_arch_enable_mon(void)
+{
+ static_branch_enable_cpuslocked(&rdt_mon_enable_key);
+ static_branch_inc_cpuslocked(&rdt_enable_key);
+}
+
+static inline void resctrl_arch_disable_mon(void)
+{
+ static_branch_disable_cpuslocked(&rdt_mon_enable_key);
+ static_branch_dec_cpuslocked(&rdt_enable_key);
+}
+
/*
* __resctrl_sched_in() - Writes the task's CLOSid/RMID to IA32_PQR_MSR
*
@@ -88,12 +132,58 @@ static inline unsigned int resctrl_arch_round_mon_val(unsigned int val)
return val * scale;
}
+static inline void resctrl_arch_set_closid_rmid(struct task_struct *tsk,
+ u32 closid, u32 rmid)
+{
+ WRITE_ONCE(tsk->closid, closid);
+ WRITE_ONCE(tsk->rmid, rmid);
+}
+
+static inline bool resctrl_arch_match_closid(struct task_struct *tsk, u32 closid)
+{
+ return READ_ONCE(tsk->closid) == closid;
+}
+
+static inline bool resctrl_arch_match_rmid(struct task_struct *tsk, u32 ignored,
+ u32 rmid)
+{
+ return READ_ONCE(tsk->rmid) == rmid;
+}
+
static inline void resctrl_sched_in(struct task_struct *tsk)
{
if (static_branch_likely(&rdt_enable_key))
__resctrl_sched_in(tsk);
}
+static inline u32 resctrl_arch_system_num_rmid_idx(void)
+{
+ /* RMID are independent numbers for x86. num_rmid_idx == num_rmid */
+ return boot_cpu_data.x86_cache_max_rmid + 1;
+}
+
+static inline void resctrl_arch_rmid_idx_decode(u32 idx, u32 *closid, u32 *rmid)
+{
+ *rmid = idx;
+ *closid = X86_RESCTRL_EMPTY_CLOSID;
+}
+
+static inline u32 resctrl_arch_rmid_idx_encode(u32 ignored, u32 rmid)
+{
+ return rmid;
+}
+
+/* x86 can always read an rmid, nothing needs allocating */
+struct rdt_resource;
+static inline void *resctrl_arch_mon_ctx_alloc(struct rdt_resource *r, int evtid)
+{
+ might_sleep();
+ return NULL;
+};
+
+static inline void resctrl_arch_mon_ctx_free(struct rdt_resource *r, int evtid,
+ void *ctx) { };
+
void resctrl_cpu_detect(struct cpuinfo_x86 *c);
#else
diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
index 5c83729c8e71..e61e68d71cba 100644
--- a/arch/x86/include/asm/setup.h
+++ b/arch/x86/include/asm/setup.h
@@ -48,7 +48,7 @@ extern unsigned long saved_video_mode;
extern void reserve_standard_io_resources(void);
extern void i386_reserve_resources(void);
extern unsigned long __startup_64(unsigned long physaddr, struct boot_params *bp);
-extern void startup_64_setup_env(unsigned long physbase);
+extern void startup_64_setup_gdt_idt(void);
extern void early_setup_idt(void);
extern void __init do_early_exception(struct pt_regs *regs, int trapnr);
diff --git a/arch/x86/include/asm/setup_data.h b/arch/x86/include/asm/setup_data.h
new file mode 100644
index 000000000000..77c51111a893
--- /dev/null
+++ b/arch/x86/include/asm/setup_data.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_SETUP_DATA_H
+#define _ASM_X86_SETUP_DATA_H
+
+#include <uapi/asm/setup_data.h>
+
+#ifndef __ASSEMBLY__
+
+struct pci_setup_rom {
+ struct setup_data data;
+ uint16_t vendor;
+ uint16_t devid;
+ uint64_t pcilen;
+ unsigned long segment;
+ unsigned long bus;
+ unsigned long device;
+ unsigned long function;
+ uint8_t romdata[];
+};
+
+/* kexec external ABI */
+struct efi_setup_data {
+ u64 fw_vendor;
+ u64 __unused;
+ u64 tables;
+ u64 smbios;
+ u64 reserved[8];
+};
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_X86_SETUP_DATA_H */
diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h
index 5b4a1ce3d368..7f57382afee4 100644
--- a/arch/x86/include/asm/sev.h
+++ b/arch/x86/include/asm/sev.h
@@ -13,7 +13,6 @@
#include <asm/insn.h>
#include <asm/sev-common.h>
-#include <asm/bootparam.h>
#include <asm/coco.h>
#define GHCB_PROTOCOL_MIN 1ULL
@@ -22,6 +21,8 @@
#define VMGEXIT() { asm volatile("rep; vmmcall\n\r"); }
+struct boot_params;
+
enum es_result {
ES_OK, /* All good */
ES_UNSUPPORTED, /* Requested operation not supported */
@@ -87,9 +88,23 @@ extern bool handle_vc_boot_ghcb(struct pt_regs *regs);
/* Software defined (when rFlags.CF = 1) */
#define PVALIDATE_FAIL_NOUPDATE 255
+/* RMUPDATE detected 4K page and 2MB page overlap. */
+#define RMPUPDATE_FAIL_OVERLAP 4
+
/* RMP page size */
#define RMP_PG_SIZE_4K 0
#define RMP_PG_SIZE_2M 1
+#define RMP_TO_PG_LEVEL(level) (((level) == RMP_PG_SIZE_4K) ? PG_LEVEL_4K : PG_LEVEL_2M)
+#define PG_LEVEL_TO_RMP(level) (((level) == PG_LEVEL_4K) ? RMP_PG_SIZE_4K : RMP_PG_SIZE_2M)
+
+struct rmp_state {
+ u64 gpa;
+ u8 assigned;
+ u8 pagesize;
+ u8 immutable;
+ u8 rsvd;
+ u32 asid;
+} __packed;
#define RMPADJUST_VMSA_PAGE_BIT BIT(16)
@@ -199,20 +214,21 @@ static inline int pvalidate(unsigned long vaddr, bool rmp_psize, bool validate)
struct snp_guest_request_ioctl;
void setup_ghcb(void);
-void __init early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr,
- unsigned long npages);
-void __init early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr,
- unsigned long npages);
-void __init snp_prep_memory(unsigned long paddr, unsigned int sz, enum psc_op op);
+void early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr,
+ unsigned long npages);
+void early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr,
+ unsigned long npages);
void snp_set_memory_shared(unsigned long vaddr, unsigned long npages);
void snp_set_memory_private(unsigned long vaddr, unsigned long npages);
void snp_set_wakeup_secondary_cpu(void);
bool snp_init(struct boot_params *bp);
-void __init __noreturn snp_abort(void);
+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);
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
static inline void sev_es_ist_enter(struct pt_regs *regs) { }
static inline void sev_es_ist_exit(void) { }
@@ -227,12 +243,12 @@ static inline void __init
early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr, unsigned long npages) { }
static inline void __init
early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr, unsigned long npages) { }
-static inline void __init snp_prep_memory(unsigned long paddr, unsigned int sz, enum psc_op op) { }
static inline void snp_set_memory_shared(unsigned long vaddr, unsigned long npages) { }
static inline void snp_set_memory_private(unsigned long vaddr, unsigned long npages) { }
static inline void snp_set_wakeup_secondary_cpu(void) { }
static inline bool snp_init(struct boot_params *bp) { return false; }
static inline void snp_abort(void) { }
+static inline void snp_dmi_setup(void) { }
static inline int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, struct snp_guest_request_ioctl *rio)
{
return -ENOTTY;
@@ -241,6 +257,31 @@ static inline int snp_issue_guest_request(u64 exit_code, struct snp_req_data *in
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
+
+#ifdef CONFIG_KVM_AMD_SEV
+bool snp_probe_rmptable_info(void);
+int snp_lookup_rmpentry(u64 pfn, bool *assigned, int *level);
+void snp_dump_hva_rmpentry(unsigned long address);
+int psmash(u64 pfn);
+int rmp_make_private(u64 pfn, u64 gpa, enum pg_level level, u32 asid, bool immutable);
+int rmp_make_shared(u64 pfn, enum pg_level level);
+void snp_leak_pages(u64 pfn, unsigned int npages);
+void kdump_sev_callback(void);
+#else
+static inline bool snp_probe_rmptable_info(void) { return false; }
+static inline int snp_lookup_rmpentry(u64 pfn, bool *assigned, int *level) { return -ENODEV; }
+static inline void snp_dump_hva_rmpentry(unsigned long address) {}
+static inline int psmash(u64 pfn) { return -ENODEV; }
+static inline int rmp_make_private(u64 pfn, u64 gpa, enum pg_level level, u32 asid,
+ bool immutable)
+{
+ return -ENODEV;
+}
+static inline int rmp_make_shared(u64 pfn, enum pg_level level) { return -ENODEV; }
+static inline void snp_leak_pages(u64 pfn, unsigned int npages) {}
+static inline void kdump_sev_callback(void) { }
#endif
#endif
diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h
index 4fab2ed454f3..a35936b512fe 100644
--- a/arch/x86/include/asm/smp.h
+++ b/arch/x86/include/asm/smp.h
@@ -8,9 +8,6 @@
#include <asm/current.h>
#include <asm/thread_info.h>
-extern int smp_num_siblings;
-extern unsigned int num_processors;
-
DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_sibling_map);
DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_core_map);
DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_die_map);
@@ -59,11 +56,6 @@ static inline void stop_other_cpus(void)
smp_ops.stop_other_cpus(1);
}
-static inline void smp_prepare_boot_cpu(void)
-{
- smp_ops.smp_prepare_boot_cpu();
-}
-
static inline void smp_prepare_cpus(unsigned int max_cpus)
{
smp_ops.smp_prepare_cpus(max_cpus);
@@ -110,7 +102,6 @@ void cpu_disable_common(void);
void native_smp_prepare_boot_cpu(void);
void smp_prepare_cpus_common(void);
void native_smp_prepare_cpus(unsigned int max_cpus);
-void calculate_max_logical_packages(void);
void native_smp_cpus_done(unsigned int max_cpus);
int common_cpu_up(unsigned int cpunum, struct task_struct *tidle);
int native_kick_ap(unsigned int cpu, struct task_struct *tidle);
@@ -174,8 +165,6 @@ static inline struct cpumask *cpu_llc_shared_mask(int cpu)
}
#endif /* CONFIG_SMP */
-extern unsigned disabled_cpus;
-
#ifdef CONFIG_DEBUG_NMI_SELFTEST
extern void nmi_selftest(void);
#else
diff --git a/arch/x86/include/asm/spec-ctrl.h b/arch/x86/include/asm/spec-ctrl.h
index c648502e4535..658b690b2ccb 100644
--- a/arch/x86/include/asm/spec-ctrl.h
+++ b/arch/x86/include/asm/spec-ctrl.h
@@ -96,4 +96,6 @@ static inline void speculative_store_bypass_ht_init(void) { }
extern void speculation_ctrl_update(unsigned long tif);
extern void speculation_ctrl_update_current(void);
+extern bool itlb_multihit_kvm_mitigation;
+
#endif
diff --git a/arch/x86/include/asm/special_insns.h b/arch/x86/include/asm/special_insns.h
index 48f8dd47cf68..2e9fc5c400cd 100644
--- a/arch/x86/include/asm/special_insns.h
+++ b/arch/x86/include/asm/special_insns.h
@@ -2,11 +2,11 @@
#ifndef _ASM_X86_SPECIAL_INSNS_H
#define _ASM_X86_SPECIAL_INSNS_H
-
#ifdef __KERNEL__
-
#include <asm/nops.h>
#include <asm/processor-flags.h>
+
+#include <linux/errno.h>
#include <linux/irqflags.h>
#include <linux/jump_label.h>
@@ -224,10 +224,10 @@ static inline void serialize(void)
}
/* The dst parameter must be 64-bytes aligned */
-static inline void movdir64b(void __iomem *dst, const void *src)
+static inline void movdir64b(void *dst, const void *src)
{
const struct { char _[64]; } *__src = src;
- struct { char _[64]; } __iomem *__dst = dst;
+ struct { char _[64]; } *__dst = dst;
/*
* MOVDIR64B %(rdx), rax.
@@ -245,6 +245,11 @@ static inline void movdir64b(void __iomem *dst, const void *src)
: "m" (*__src), "a" (__dst), "d" (__src));
}
+static inline void movdir64b_io(void __iomem *dst, const void *src)
+{
+ movdir64b((void __force *)dst, src);
+}
+
/**
* enqcmds - Enqueue a command in supervisor (CPL0) mode
* @dst: destination, in MMIO space (must be 512-bit aligned)
diff --git a/arch/x86/include/asm/static_call.h b/arch/x86/include/asm/static_call.h
index 343b722ccaf2..125c407e2abe 100644
--- a/arch/x86/include/asm/static_call.h
+++ b/arch/x86/include/asm/static_call.h
@@ -46,7 +46,7 @@
#define ARCH_DEFINE_STATIC_CALL_TRAMP(name, func) \
__ARCH_DEFINE_STATIC_CALL_TRAMP(name, ".byte 0xe9; .long " #func " - (. + 4)")
-#ifdef CONFIG_RETHUNK
+#ifdef CONFIG_MITIGATION_RETHUNK
#define ARCH_DEFINE_STATIC_CALL_NULL_TRAMP(name) \
__ARCH_DEFINE_STATIC_CALL_TRAMP(name, "jmp __x86_return_thunk")
#else
diff --git a/arch/x86/include/asm/suspend_32.h b/arch/x86/include/asm/suspend_32.h
index a800abb1a992..d8416b3bf832 100644
--- a/arch/x86/include/asm/suspend_32.h
+++ b/arch/x86/include/asm/suspend_32.h
@@ -12,11 +12,6 @@
/* image of the saved processor state */
struct saved_context {
- /*
- * On x86_32, all segment registers except gs are saved at kernel
- * entry in pt_regs.
- */
- u16 gs;
unsigned long cr0, cr2, cr3, cr4;
u64 misc_enable;
struct saved_msrs saved_msrs;
@@ -27,6 +22,11 @@ struct saved_context {
unsigned long tr;
unsigned long safety;
unsigned long return_address;
+ /*
+ * On x86_32, all segment registers except gs are saved at kernel
+ * entry in pt_regs.
+ */
+ u16 gs;
bool misc_enable_saved;
} __attribute__((packed));
diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h
index 87a7b917d30e..728c98175b9c 100644
--- a/arch/x86/include/asm/svm.h
+++ b/arch/x86/include/asm/svm.h
@@ -358,10 +358,10 @@ struct sev_es_save_area {
struct vmcb_seg ldtr;
struct vmcb_seg idtr;
struct vmcb_seg tr;
- u64 vmpl0_ssp;
- u64 vmpl1_ssp;
- u64 vmpl2_ssp;
- u64 vmpl3_ssp;
+ u64 pl0_ssp;
+ u64 pl1_ssp;
+ u64 pl2_ssp;
+ u64 pl3_ssp;
u64 u_cet;
u8 reserved_0xc8[2];
u8 vmpl;
diff --git a/arch/x86/include/asm/switch_to.h b/arch/x86/include/asm/switch_to.h
index f42dbf17f52b..c3bd0c0758c9 100644
--- a/arch/x86/include/asm/switch_to.h
+++ b/arch/x86/include/asm/switch_to.h
@@ -70,9 +70,13 @@ static inline void update_task_stack(struct task_struct *task)
#ifdef CONFIG_X86_32
this_cpu_write(cpu_tss_rw.x86_tss.sp1, task->thread.sp0);
#else
- /* Xen PV enters the kernel on the thread stack. */
- if (cpu_feature_enabled(X86_FEATURE_XENPV))
+ if (cpu_feature_enabled(X86_FEATURE_FRED)) {
+ /* WRMSRNS is a baseline feature for FRED. */
+ wrmsrns(MSR_IA32_FRED_RSP0, (unsigned long)task_stack_page(task) + THREAD_SIZE);
+ } else if (cpu_feature_enabled(X86_FEATURE_XENPV)) {
+ /* Xen PV enters the kernel on the thread stack. */
load_sp0(task_top_of_stack(task));
+ }
#endif
}
diff --git a/arch/x86/include/asm/syscall.h b/arch/x86/include/asm/syscall.h
index f44e2f9ab65d..2fc7bc3863ff 100644
--- a/arch/x86/include/asm/syscall.h
+++ b/arch/x86/include/asm/syscall.h
@@ -16,19 +16,17 @@
#include <asm/thread_info.h> /* for TS_COMPAT */
#include <asm/unistd.h>
+/* This is used purely for kernel/trace/trace_syscalls.c */
typedef long (*sys_call_ptr_t)(const struct pt_regs *);
extern const sys_call_ptr_t sys_call_table[];
-#if defined(CONFIG_X86_32)
-#define ia32_sys_call_table sys_call_table
-#else
/*
* These may not exist, but still put the prototypes in so we
* can use IS_ENABLED().
*/
-extern const sys_call_ptr_t ia32_sys_call_table[];
-extern const sys_call_ptr_t x32_sys_call_table[];
-#endif
+extern long ia32_sys_call(const struct pt_regs *, unsigned int nr);
+extern long x32_sys_call(const struct pt_regs *, unsigned int nr);
+extern long x64_sys_call(const struct pt_regs *, unsigned int nr);
/*
* Only the low 32 bits of orig_ax are meaningful, so we return int.
@@ -127,6 +125,7 @@ static inline int syscall_get_arch(struct task_struct *task)
}
bool do_syscall_64(struct pt_regs *regs, int nr);
+void do_int80_emulation(struct pt_regs *regs);
#endif /* CONFIG_X86_32 */
diff --git a/arch/x86/include/asm/text-patching.h b/arch/x86/include/asm/text-patching.h
index 0b70653a98c1..345aafbc1964 100644
--- a/arch/x86/include/asm/text-patching.h
+++ b/arch/x86/include/asm/text-patching.h
@@ -15,6 +15,8 @@
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);
+
/*
* Clear and restore the kernel write-protection flag on the local CPU.
* Allows the kernel to edit read-only pages.
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index d63b02940747..12da7dfd5ef1 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -31,7 +31,9 @@
* In vm86 mode, the hardware frame is much longer still, so add 16
* bytes to make room for the real-mode segments.
*
- * x86_64 has a fixed-length stack frame.
+ * x86-64 has a fixed-length stack frame, but it depends on whether
+ * or not FRED is enabled. Future versions of FRED might make this
+ * dynamic, but for now it is always 2 words longer.
*/
#ifdef CONFIG_X86_32
# ifdef CONFIG_VM86
@@ -39,8 +41,12 @@
# else
# define TOP_OF_KERNEL_STACK_PADDING 8
# endif
-#else
-# define TOP_OF_KERNEL_STACK_PADDING 0
+#else /* x86-64 */
+# ifdef CONFIG_X86_FRED
+# define TOP_OF_KERNEL_STACK_PADDING (2 * 8)
+# else
+# define TOP_OF_KERNEL_STACK_PADDING 0
+# endif
#endif
/*
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
index 5f87f6b9b09e..abe3a8f22cbd 100644
--- a/arch/x86/include/asm/topology.h
+++ b/arch/x86/include/asm/topology.h
@@ -102,6 +102,35 @@ static inline void setup_node_to_cpumask_map(void) { }
#include <asm-generic/topology.h>
+/* Topology information */
+enum x86_topology_domains {
+ TOPO_SMT_DOMAIN,
+ TOPO_CORE_DOMAIN,
+ TOPO_MODULE_DOMAIN,
+ TOPO_TILE_DOMAIN,
+ TOPO_DIE_DOMAIN,
+ TOPO_DIEGRP_DOMAIN,
+ TOPO_PKG_DOMAIN,
+ TOPO_MAX_DOMAIN,
+};
+
+struct x86_topology_system {
+ unsigned int dom_shifts[TOPO_MAX_DOMAIN];
+ unsigned int dom_size[TOPO_MAX_DOMAIN];
+};
+
+extern struct x86_topology_system x86_topo_system;
+
+static inline unsigned int topology_get_domain_size(enum x86_topology_domains dom)
+{
+ return x86_topo_system.dom_size[dom];
+}
+
+static inline unsigned int topology_get_domain_shift(enum x86_topology_domains dom)
+{
+ return dom == TOPO_SMT_DOMAIN ? 0 : x86_topo_system.dom_shifts[dom - 1];
+}
+
extern const struct cpumask *cpu_coregroup_mask(int cpu);
extern const struct cpumask *cpu_clustergroup_mask(int cpu);
@@ -112,7 +141,42 @@ extern const struct cpumask *cpu_clustergroup_mask(int cpu);
#define topology_core_id(cpu) (cpu_data(cpu).topo.core_id)
#define topology_ppin(cpu) (cpu_data(cpu).ppin)
-extern unsigned int __max_die_per_package;
+#define topology_amd_node_id(cpu) (cpu_data(cpu).topo.amd_node_id)
+
+extern unsigned int __max_dies_per_package;
+extern unsigned int __max_logical_packages;
+extern unsigned int __max_threads_per_core;
+extern unsigned int __num_threads_per_package;
+extern unsigned int __num_cores_per_package;
+
+static inline unsigned int topology_max_packages(void)
+{
+ return __max_logical_packages;
+}
+
+static inline unsigned int topology_max_dies_per_package(void)
+{
+ return __max_dies_per_package;
+}
+
+static inline unsigned int topology_num_cores_per_package(void)
+{
+ return __num_cores_per_package;
+}
+
+static inline unsigned int topology_num_threads_per_package(void)
+{
+ return __num_threads_per_package;
+}
+
+#ifdef CONFIG_X86_LOCAL_APIC
+int topology_get_logical_id(u32 apicid, enum x86_topology_domains at_level);
+#else
+static inline int topology_get_logical_id(u32 apicid, enum x86_topology_domains at_level)
+{
+ return 0;
+}
+#endif
#ifdef CONFIG_SMP
#define topology_cluster_id(cpu) (cpu_data(cpu).topo.l2c_id)
@@ -121,12 +185,11 @@ extern unsigned int __max_die_per_package;
#define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu))
#define topology_sibling_cpumask(cpu) (per_cpu(cpu_sibling_map, cpu))
-extern unsigned int __max_logical_packages;
-#define topology_max_packages() (__max_logical_packages)
-static inline int topology_max_die_per_package(void)
+static inline int topology_phys_to_logical_pkg(unsigned int pkg)
{
- return __max_die_per_package;
+ return topology_get_logical_id(pkg << x86_topo_system.dom_shifts[TOPO_PKG_DOMAIN],
+ TOPO_PKG_DOMAIN);
}
extern int __max_smt_threads;
@@ -138,9 +201,12 @@ static inline int topology_max_smt_threads(void)
#include <linux/cpu_smt.h>
-int topology_update_package_map(unsigned int apicid, unsigned int cpu);
-int topology_update_die_map(unsigned int dieid, unsigned int cpu);
-int topology_phys_to_logical_pkg(unsigned int pkg);
+extern unsigned int __amd_nodes_per_pkg;
+
+static inline unsigned int topology_amd_nodes_per_pkg(void)
+{
+ return __amd_nodes_per_pkg;
+}
extern struct cpumask __cpu_primary_thread_mask;
#define cpu_primary_thread_mask ((const struct cpumask *)&__cpu_primary_thread_mask)
@@ -153,16 +219,12 @@ static inline bool topology_is_primary_thread(unsigned int cpu)
{
return cpumask_test_cpu(cpu, cpu_primary_thread_mask);
}
+
#else /* CONFIG_SMP */
-#define topology_max_packages() (1)
-static inline int
-topology_update_package_map(unsigned int apicid, unsigned int cpu) { return 0; }
-static inline int
-topology_update_die_map(unsigned int dieid, unsigned int cpu) { return 0; }
static inline int topology_phys_to_logical_pkg(unsigned int pkg) { return 0; }
-static inline int topology_max_die_per_package(void) { return 1; }
static inline int topology_max_smt_threads(void) { return 1; }
static inline bool topology_is_primary_thread(unsigned int cpu) { return true; }
+static inline unsigned int topology_amd_nodes_per_pkg(void) { return 1; }
#endif /* !CONFIG_SMP */
static inline void arch_fix_phys_package_id(int num, u32 slot)
diff --git a/arch/x86/include/asm/trap_pf.h b/arch/x86/include/asm/trap_pf.h
index afa524325e55..a23a7b707b64 100644
--- a/arch/x86/include/asm/trap_pf.h
+++ b/arch/x86/include/asm/trap_pf.h
@@ -2,6 +2,8 @@
#ifndef _ASM_X86_TRAP_PF_H
#define _ASM_X86_TRAP_PF_H
+#include <linux/bits.h>
+
/*
* Page fault error code bits:
*
@@ -13,16 +15,18 @@
* bit 5 == 1: protection keys block access
* bit 6 == 1: shadow stack access fault
* bit 15 == 1: SGX MMU page-fault
+ * bit 31 == 1: fault was due to RMP violation
*/
enum x86_pf_error_code {
- X86_PF_PROT = 1 << 0,
- X86_PF_WRITE = 1 << 1,
- X86_PF_USER = 1 << 2,
- X86_PF_RSVD = 1 << 3,
- X86_PF_INSTR = 1 << 4,
- X86_PF_PK = 1 << 5,
- X86_PF_SHSTK = 1 << 6,
- X86_PF_SGX = 1 << 15,
+ X86_PF_PROT = BIT(0),
+ X86_PF_WRITE = BIT(1),
+ X86_PF_USER = BIT(2),
+ X86_PF_RSVD = BIT(3),
+ X86_PF_INSTR = BIT(4),
+ X86_PF_PK = BIT(5),
+ X86_PF_SHSTK = BIT(6),
+ X86_PF_SGX = BIT(15),
+ X86_PF_RMP = BIT(31),
};
#endif /* _ASM_X86_TRAP_PF_H */
diff --git a/arch/x86/include/asm/trapnr.h b/arch/x86/include/asm/trapnr.h
index f5d2325aa0b7..8d1154cdf787 100644
--- a/arch/x86/include/asm/trapnr.h
+++ b/arch/x86/include/asm/trapnr.h
@@ -2,6 +2,18 @@
#ifndef _ASM_X86_TRAPNR_H
#define _ASM_X86_TRAPNR_H
+/*
+ * Event type codes used by FRED, Intel VT-x and AMD SVM
+ */
+#define EVENT_TYPE_EXTINT 0 // External interrupt
+#define EVENT_TYPE_RESERVED 1
+#define EVENT_TYPE_NMI 2 // NMI
+#define EVENT_TYPE_HWEXC 3 // Hardware originated traps, exceptions
+#define EVENT_TYPE_SWINT 4 // INT n
+#define EVENT_TYPE_PRIV_SWEXC 5 // INT1
+#define EVENT_TYPE_SWEXC 6 // INTO, INT3
+#define EVENT_TYPE_OTHER 7 // FRED SYSCALL/SYSENTER, VT-x MTF
+
/* Interrupts/Exceptions */
#define X86_TRAP_DE 0 /* Divide-by-zero */
diff --git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h
index 594fce0ca744..405efb3e4996 100644
--- a/arch/x86/include/asm/tsc.h
+++ b/arch/x86/include/asm/tsc.h
@@ -5,8 +5,9 @@
#ifndef _ASM_X86_TSC_H
#define _ASM_X86_TSC_H
-#include <asm/processor.h>
#include <asm/cpufeature.h>
+#include <asm/processor.h>
+#include <asm/msr.h>
/*
* Standard way to access the cycle counter.
diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h
index f2c02e4469cc..04789f45ab2b 100644
--- a/arch/x86/include/asm/uaccess_64.h
+++ b/arch/x86/include/asm/uaccess_64.h
@@ -11,6 +11,7 @@
#include <asm/alternative.h>
#include <asm/cpufeatures.h>
#include <asm/page.h>
+#include <asm/percpu.h>
#ifdef CONFIG_ADDRESS_MASKING
/*
@@ -18,14 +19,10 @@
*/
static inline unsigned long __untagged_addr(unsigned long addr)
{
- /*
- * Refer tlbstate_untag_mask directly to avoid RIP-relative relocation
- * in alternative instructions. The relocation gets wrong when gets
- * copied to the target place.
- */
asm (ALTERNATIVE("",
- "and %%gs:tlbstate_untag_mask, %[addr]\n\t", X86_FEATURE_LAM)
- : [addr] "+r" (addr) : "m" (tlbstate_untag_mask));
+ "and " __percpu_arg([mask]) ", %[addr]", X86_FEATURE_LAM)
+ : [addr] "+r" (addr)
+ : [mask] "m" (__my_cpu_var(tlbstate_untag_mask)));
return addr;
}
@@ -54,7 +51,7 @@ static inline unsigned long __untagged_addr_remote(struct mm_struct *mm,
* half and a user half. When cast to a signed type, user pointers
* are positive and kernel pointers are negative.
*/
-#define valid_user_address(x) ((long)(x) >= 0)
+#define valid_user_address(x) ((__force long)(x) >= 0)
/*
* User pointers can have tag bits on x86-64. This scheme tolerates
@@ -87,8 +84,9 @@ static inline bool __access_ok(const void __user *ptr, unsigned long size)
if (__builtin_constant_p(size <= PAGE_SIZE) && size <= PAGE_SIZE) {
return valid_user_address(ptr);
} else {
- unsigned long sum = size + (unsigned long)ptr;
- return valid_user_address(sum) && sum >= (unsigned long)ptr;
+ unsigned long sum = size + (__force unsigned long)ptr;
+
+ return valid_user_address(sum) && sum >= (__force unsigned long)ptr;
}
}
#define __access_ok __access_ok
diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h
index 0e73616b82f3..4dba17363008 100644
--- a/arch/x86/include/asm/vmx.h
+++ b/arch/x86/include/asm/vmx.h
@@ -17,6 +17,7 @@
#include <linux/types.h>
#include <uapi/asm/vmx.h>
+#include <asm/trapnr.h>
#include <asm/vmxfeatures.h>
#define VMCS_CONTROL_BIT(x) BIT(VMX_FEATURE_##x & 0x1f)
@@ -374,14 +375,14 @@ enum vmcs_field {
#define VECTORING_INFO_DELIVER_CODE_MASK INTR_INFO_DELIVER_CODE_MASK
#define VECTORING_INFO_VALID_MASK INTR_INFO_VALID_MASK
-#define INTR_TYPE_EXT_INTR (0 << 8) /* external interrupt */
-#define INTR_TYPE_RESERVED (1 << 8) /* reserved */
-#define INTR_TYPE_NMI_INTR (2 << 8) /* NMI */
-#define INTR_TYPE_HARD_EXCEPTION (3 << 8) /* processor exception */
-#define INTR_TYPE_SOFT_INTR (4 << 8) /* software interrupt */
-#define INTR_TYPE_PRIV_SW_EXCEPTION (5 << 8) /* ICE breakpoint - undocumented */
-#define INTR_TYPE_SOFT_EXCEPTION (6 << 8) /* software exception */
-#define INTR_TYPE_OTHER_EVENT (7 << 8) /* other event */
+#define INTR_TYPE_EXT_INTR (EVENT_TYPE_EXTINT << 8) /* external interrupt */
+#define INTR_TYPE_RESERVED (EVENT_TYPE_RESERVED << 8) /* reserved */
+#define INTR_TYPE_NMI_INTR (EVENT_TYPE_NMI << 8) /* NMI */
+#define INTR_TYPE_HARD_EXCEPTION (EVENT_TYPE_HWEXC << 8) /* processor exception */
+#define INTR_TYPE_SOFT_INTR (EVENT_TYPE_SWINT << 8) /* software interrupt */
+#define INTR_TYPE_PRIV_SW_EXCEPTION (EVENT_TYPE_PRIV_SWEXC << 8) /* ICE breakpoint */
+#define INTR_TYPE_SOFT_EXCEPTION (EVENT_TYPE_SWEXC << 8) /* software exception */
+#define INTR_TYPE_OTHER_EVENT (EVENT_TYPE_OTHER << 8) /* other event */
/* GUEST_INTERRUPTIBILITY_INFO flags. */
#define GUEST_INTR_STATE_STI 0x00000001
diff --git a/arch/x86/include/asm/vmxfeatures.h b/arch/x86/include/asm/vmxfeatures.h
index c6a7eed03914..266daf5b5b84 100644
--- a/arch/x86/include/asm/vmxfeatures.h
+++ b/arch/x86/include/asm/vmxfeatures.h
@@ -25,6 +25,7 @@
#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 */
/* Aggregated APIC features 24-27 */
#define VMX_FEATURE_FLEXPRIORITY ( 0*32+ 24) /* TPR shadow + virt APIC */
diff --git a/arch/x86/include/asm/word-at-a-time.h b/arch/x86/include/asm/word-at-a-time.h
index 46b4f1f7f354..e8d7d4941c4c 100644
--- a/arch/x86/include/asm/word-at-a-time.h
+++ b/arch/x86/include/asm/word-at-a-time.h
@@ -2,7 +2,8 @@
#ifndef _ASM_WORD_AT_A_TIME_H
#define _ASM_WORD_AT_A_TIME_H
-#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/wordpart.h>
/*
* This is largely generic for little-endian machines, but the
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index c878616a18b8..6149eabe200f 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -2,8 +2,6 @@
#ifndef _ASM_X86_PLATFORM_H
#define _ASM_X86_PLATFORM_H
-#include <asm/bootparam.h>
-
struct ghcb;
struct mpc_bus;
struct mpc_cpu;
@@ -15,13 +13,15 @@ struct irq_domain;
/**
* struct x86_init_mpparse - platform specific mpparse ops
* @setup_ioapic_ids: platform specific ioapic id override
- * @find_smp_config: find the smp configuration
- * @get_smp_config: get the smp configuration
+ * @find_mptable: Find MPTABLE early to reserve the memory region
+ * @early_parse_smp_cfg: Parse the SMP configuration data early before initmem_init()
+ * @parse_smp_cfg: Parse the SMP configuration data
*/
struct x86_init_mpparse {
void (*setup_ioapic_ids)(void);
- void (*find_smp_config)(void);
- void (*get_smp_config)(unsigned int early);
+ void (*find_mptable)(void);
+ void (*early_parse_smp_cfg)(void);
+ void (*parse_smp_cfg)(void);
};
/**
@@ -30,12 +30,13 @@ struct x86_init_mpparse {
* @reserve_resources: reserve the standard resources for the
* platform
* @memory_setup: platform specific memory setup
- *
+ * @dmi_setup: platform specific DMI setup
*/
struct x86_init_resources {
void (*probe_roms)(void);
void (*reserve_resources)(void);
char *(*memory_setup)(void);
+ void (*dmi_setup)(void);
};
/**
diff --git a/arch/x86/include/asm/xen/hypervisor.h b/arch/x86/include/asm/xen/hypervisor.h
index a9088250770f..64fbd2dbc5b7 100644
--- a/arch/x86/include/asm/xen/hypervisor.h
+++ b/arch/x86/include/asm/xen/hypervisor.h
@@ -62,6 +62,11 @@ void xen_arch_unregister_cpu(int num);
#ifdef CONFIG_PVH
void __init xen_pvh_init(struct boot_params *boot_params);
void __init mem_map_via_hcall(struct boot_params *boot_params_p);
+#ifdef CONFIG_XEN_PVH
+void __init xen_reserve_extra_memory(struct boot_params *bootp);
+#else
+static inline void xen_reserve_extra_memory(struct boot_params *bootp) { }
+#endif
#endif
/* Lazy mode for batching updates / context switch */
diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h
index 01d19fc22346..9b82eebd7add 100644
--- a/arch/x86/include/uapi/asm/bootparam.h
+++ b/arch/x86/include/uapi/asm/bootparam.h
@@ -2,21 +2,7 @@
#ifndef _ASM_X86_BOOTPARAM_H
#define _ASM_X86_BOOTPARAM_H
-/* setup_data/setup_indirect types */
-#define SETUP_NONE 0
-#define SETUP_E820_EXT 1
-#define SETUP_DTB 2
-#define SETUP_PCI 3
-#define SETUP_EFI 4
-#define SETUP_APPLE_PROPERTIES 5
-#define SETUP_JAILHOUSE 6
-#define SETUP_CC_BLOB 7
-#define SETUP_IMA 8
-#define SETUP_RNG_SEED 9
-#define SETUP_ENUM_MAX SETUP_RNG_SEED
-
-#define SETUP_INDIRECT (1<<31)
-#define SETUP_TYPE_MAX (SETUP_ENUM_MAX | SETUP_INDIRECT)
+#include <asm/setup_data.h>
/* ram_size flags */
#define RAMDISK_IMAGE_START_MASK 0x07FF
@@ -38,6 +24,7 @@
#define XLF_EFI_KEXEC (1<<4)
#define XLF_5LEVEL (1<<5)
#define XLF_5LEVEL_ENABLED (1<<6)
+#define XLF_MEM_ENCRYPTION (1<<7)
#ifndef __ASSEMBLY__
@@ -48,22 +35,6 @@
#include <asm/ist.h>
#include <video/edid.h>
-/* extensible setup data list node */
-struct setup_data {
- __u64 next;
- __u32 type;
- __u32 len;
- __u8 data[];
-};
-
-/* extensible setup indirect data node */
-struct setup_indirect {
- __u32 type;
- __u32 reserved; /* Reserved, must be set to zero. */
- __u64 len;
- __u64 addr;
-};
-
struct setup_header {
__u8 setup_sects;
__u16 root_flags;
@@ -137,50 +108,10 @@ struct efi_info {
#define E820_MAX_ENTRIES_ZEROPAGE 128
/*
- * The E820 memory region entry of the boot protocol ABI:
- */
-struct boot_e820_entry {
- __u64 addr;
- __u64 size;
- __u32 type;
-} __attribute__((packed));
-
-/*
* Smallest compatible version of jailhouse_setup_data required by this kernel.
*/
#define JAILHOUSE_SETUP_REQUIRED_VERSION 1
-/*
- * The boot loader is passing platform information via this Jailhouse-specific
- * setup data structure.
- */
-struct jailhouse_setup_data {
- struct {
- __u16 version;
- __u16 compatible_version;
- } __attribute__((packed)) hdr;
- struct {
- __u16 pm_timer_address;
- __u16 num_cpus;
- __u64 pci_mmconfig_base;
- __u32 tsc_khz;
- __u32 apic_khz;
- __u8 standard_ioapic;
- __u8 cpu_ids[255];
- } __attribute__((packed)) v1;
- struct {
- __u32 flags;
- } __attribute__((packed)) v2;
-} __attribute__((packed));
-
-/*
- * IMA buffer setup data information from the previous kernel during kexec
- */
-struct ima_setup_data {
- __u64 addr;
- __u64 size;
-} __attribute__((packed));
-
/* The so-called "zeropage" */
struct boot_params {
struct screen_info screen_info; /* 0x000 */
diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h
index a448d0964fc0..ef11aa4cab42 100644
--- a/arch/x86/include/uapi/asm/kvm.h
+++ b/arch/x86/include/uapi/asm/kvm.h
@@ -7,6 +7,8 @@
*
*/
+#include <linux/const.h>
+#include <linux/bits.h>
#include <linux/types.h>
#include <linux/ioctl.h>
#include <linux/stddef.h>
@@ -40,7 +42,6 @@
#define __KVM_HAVE_IRQ_LINE
#define __KVM_HAVE_MSI
#define __KVM_HAVE_USER_NMI
-#define __KVM_HAVE_GUEST_DEBUG
#define __KVM_HAVE_MSIX
#define __KVM_HAVE_MCE
#define __KVM_HAVE_PIT_STATE2
@@ -49,7 +50,6 @@
#define __KVM_HAVE_DEBUGREGS
#define __KVM_HAVE_XSAVE
#define __KVM_HAVE_XCRS
-#define __KVM_HAVE_READONLY_MEM
/* Architectural interrupt line count. */
#define KVM_NR_INTERRUPTS 256
@@ -526,9 +526,301 @@ struct kvm_pmu_event_filter {
#define KVM_PMU_EVENT_ALLOW 0
#define KVM_PMU_EVENT_DENY 1
-#define KVM_PMU_EVENT_FLAG_MASKED_EVENTS BIT(0)
+#define KVM_PMU_EVENT_FLAG_MASKED_EVENTS _BITUL(0)
#define KVM_PMU_EVENT_FLAGS_VALID_MASK (KVM_PMU_EVENT_FLAG_MASKED_EVENTS)
+/* for KVM_CAP_MCE */
+struct kvm_x86_mce {
+ __u64 status;
+ __u64 addr;
+ __u64 misc;
+ __u64 mcg_status;
+ __u8 bank;
+ __u8 pad1[7];
+ __u64 pad2[3];
+};
+
+/* for KVM_CAP_XEN_HVM */
+#define KVM_XEN_HVM_CONFIG_HYPERCALL_MSR (1 << 0)
+#define KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL (1 << 1)
+#define KVM_XEN_HVM_CONFIG_SHARED_INFO (1 << 2)
+#define KVM_XEN_HVM_CONFIG_RUNSTATE (1 << 3)
+#define KVM_XEN_HVM_CONFIG_EVTCHN_2LEVEL (1 << 4)
+#define KVM_XEN_HVM_CONFIG_EVTCHN_SEND (1 << 5)
+#define KVM_XEN_HVM_CONFIG_RUNSTATE_UPDATE_FLAG (1 << 6)
+#define KVM_XEN_HVM_CONFIG_PVCLOCK_TSC_UNSTABLE (1 << 7)
+#define KVM_XEN_HVM_CONFIG_SHARED_INFO_HVA (1 << 8)
+
+struct kvm_xen_hvm_config {
+ __u32 flags;
+ __u32 msr;
+ __u64 blob_addr_32;
+ __u64 blob_addr_64;
+ __u8 blob_size_32;
+ __u8 blob_size_64;
+ __u8 pad2[30];
+};
+
+struct kvm_xen_hvm_attr {
+ __u16 type;
+ __u16 pad[3];
+ union {
+ __u8 long_mode;
+ __u8 vector;
+ __u8 runstate_update_flag;
+ union {
+ __u64 gfn;
+#define KVM_XEN_INVALID_GFN ((__u64)-1)
+ __u64 hva;
+ } shared_info;
+ struct {
+ __u32 send_port;
+ __u32 type; /* EVTCHNSTAT_ipi / EVTCHNSTAT_interdomain */
+ __u32 flags;
+#define KVM_XEN_EVTCHN_DEASSIGN (1 << 0)
+#define KVM_XEN_EVTCHN_UPDATE (1 << 1)
+#define KVM_XEN_EVTCHN_RESET (1 << 2)
+ /*
+ * Events sent by the guest are either looped back to
+ * the guest itself (potentially on a different port#)
+ * or signalled via an eventfd.
+ */
+ union {
+ struct {
+ __u32 port;
+ __u32 vcpu;
+ __u32 priority;
+ } port;
+ struct {
+ __u32 port; /* Zero for eventfd */
+ __s32 fd;
+ } eventfd;
+ __u32 padding[4];
+ } deliver;
+ } evtchn;
+ __u32 xen_version;
+ __u64 pad[8];
+ } u;
+};
+
+
+/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_SHARED_INFO */
+#define KVM_XEN_ATTR_TYPE_LONG_MODE 0x0
+#define KVM_XEN_ATTR_TYPE_SHARED_INFO 0x1
+#define KVM_XEN_ATTR_TYPE_UPCALL_VECTOR 0x2
+/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_EVTCHN_SEND */
+#define KVM_XEN_ATTR_TYPE_EVTCHN 0x3
+#define KVM_XEN_ATTR_TYPE_XEN_VERSION 0x4
+/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_RUNSTATE_UPDATE_FLAG */
+#define KVM_XEN_ATTR_TYPE_RUNSTATE_UPDATE_FLAG 0x5
+/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_SHARED_INFO_HVA */
+#define KVM_XEN_ATTR_TYPE_SHARED_INFO_HVA 0x6
+
+struct kvm_xen_vcpu_attr {
+ __u16 type;
+ __u16 pad[3];
+ union {
+ __u64 gpa;
+#define KVM_XEN_INVALID_GPA ((__u64)-1)
+ __u64 hva;
+ __u64 pad[8];
+ struct {
+ __u64 state;
+ __u64 state_entry_time;
+ __u64 time_running;
+ __u64 time_runnable;
+ __u64 time_blocked;
+ __u64 time_offline;
+ } runstate;
+ __u32 vcpu_id;
+ struct {
+ __u32 port;
+ __u32 priority;
+ __u64 expires_ns;
+ } timer;
+ __u8 vector;
+ } u;
+};
+
+/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_SHARED_INFO */
+#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO 0x0
+#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO 0x1
+#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADDR 0x2
+#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_CURRENT 0x3
+#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_DATA 0x4
+#define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADJUST 0x5
+/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_EVTCHN_SEND */
+#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_ID 0x6
+#define KVM_XEN_VCPU_ATTR_TYPE_TIMER 0x7
+#define KVM_XEN_VCPU_ATTR_TYPE_UPCALL_VECTOR 0x8
+/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_SHARED_INFO_HVA */
+#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO_HVA 0x9
+
+/* Secure Encrypted Virtualization command */
+enum sev_cmd_id {
+ /* Guest initialization commands */
+ KVM_SEV_INIT = 0,
+ KVM_SEV_ES_INIT,
+ /* Guest launch commands */
+ KVM_SEV_LAUNCH_START,
+ KVM_SEV_LAUNCH_UPDATE_DATA,
+ KVM_SEV_LAUNCH_UPDATE_VMSA,
+ KVM_SEV_LAUNCH_SECRET,
+ KVM_SEV_LAUNCH_MEASURE,
+ KVM_SEV_LAUNCH_FINISH,
+ /* Guest migration commands (outgoing) */
+ KVM_SEV_SEND_START,
+ KVM_SEV_SEND_UPDATE_DATA,
+ KVM_SEV_SEND_UPDATE_VMSA,
+ KVM_SEV_SEND_FINISH,
+ /* Guest migration commands (incoming) */
+ KVM_SEV_RECEIVE_START,
+ KVM_SEV_RECEIVE_UPDATE_DATA,
+ KVM_SEV_RECEIVE_UPDATE_VMSA,
+ KVM_SEV_RECEIVE_FINISH,
+ /* Guest status and debug commands */
+ KVM_SEV_GUEST_STATUS,
+ KVM_SEV_DBG_DECRYPT,
+ KVM_SEV_DBG_ENCRYPT,
+ /* Guest certificates commands */
+ KVM_SEV_CERT_EXPORT,
+ /* Attestation report */
+ KVM_SEV_GET_ATTESTATION_REPORT,
+ /* Guest Migration Extension */
+ KVM_SEV_SEND_CANCEL,
+
+ KVM_SEV_NR_MAX,
+};
+
+struct kvm_sev_cmd {
+ __u32 id;
+ __u32 pad0;
+ __u64 data;
+ __u32 error;
+ __u32 sev_fd;
+};
+
+struct kvm_sev_launch_start {
+ __u32 handle;
+ __u32 policy;
+ __u64 dh_uaddr;
+ __u32 dh_len;
+ __u32 pad0;
+ __u64 session_uaddr;
+ __u32 session_len;
+ __u32 pad1;
+};
+
+struct kvm_sev_launch_update_data {
+ __u64 uaddr;
+ __u32 len;
+ __u32 pad0;
+};
+
+
+struct kvm_sev_launch_secret {
+ __u64 hdr_uaddr;
+ __u32 hdr_len;
+ __u32 pad0;
+ __u64 guest_uaddr;
+ __u32 guest_len;
+ __u32 pad1;
+ __u64 trans_uaddr;
+ __u32 trans_len;
+ __u32 pad2;
+};
+
+struct kvm_sev_launch_measure {
+ __u64 uaddr;
+ __u32 len;
+ __u32 pad0;
+};
+
+struct kvm_sev_guest_status {
+ __u32 handle;
+ __u32 policy;
+ __u32 state;
+};
+
+struct kvm_sev_dbg {
+ __u64 src_uaddr;
+ __u64 dst_uaddr;
+ __u32 len;
+ __u32 pad0;
+};
+
+struct kvm_sev_attestation_report {
+ __u8 mnonce[16];
+ __u64 uaddr;
+ __u32 len;
+ __u32 pad0;
+};
+
+struct kvm_sev_send_start {
+ __u32 policy;
+ __u32 pad0;
+ __u64 pdh_cert_uaddr;
+ __u32 pdh_cert_len;
+ __u32 pad1;
+ __u64 plat_certs_uaddr;
+ __u32 plat_certs_len;
+ __u32 pad2;
+ __u64 amd_certs_uaddr;
+ __u32 amd_certs_len;
+ __u32 pad3;
+ __u64 session_uaddr;
+ __u32 session_len;
+ __u32 pad4;
+};
+
+struct kvm_sev_send_update_data {
+ __u64 hdr_uaddr;
+ __u32 hdr_len;
+ __u32 pad0;
+ __u64 guest_uaddr;
+ __u32 guest_len;
+ __u32 pad1;
+ __u64 trans_uaddr;
+ __u32 trans_len;
+ __u32 pad2;
+};
+
+struct kvm_sev_receive_start {
+ __u32 handle;
+ __u32 policy;
+ __u64 pdh_uaddr;
+ __u32 pdh_len;
+ __u32 pad0;
+ __u64 session_uaddr;
+ __u32 session_len;
+ __u32 pad1;
+};
+
+struct kvm_sev_receive_update_data {
+ __u64 hdr_uaddr;
+ __u32 hdr_len;
+ __u32 pad0;
+ __u64 guest_uaddr;
+ __u32 guest_len;
+ __u32 pad1;
+ __u64 trans_uaddr;
+ __u32 trans_len;
+ __u32 pad2;
+};
+
+#define KVM_X2APIC_API_USE_32BIT_IDS (1ULL << 0)
+#define KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK (1ULL << 1)
+
+struct kvm_hyperv_eventfd {
+ __u32 conn_id;
+ __s32 fd;
+ __u32 flags;
+ __u32 padding[3];
+};
+
+#define KVM_HYPERV_CONN_ID_MASK 0x00ffffff
+#define KVM_HYPERV_EVENTFD_DEASSIGN (1 << 0)
+
/*
* Masked event layout.
* Bits Description
@@ -549,10 +841,10 @@ struct kvm_pmu_event_filter {
((__u64)(!!(exclude)) << 55))
#define KVM_PMU_MASKED_ENTRY_EVENT_SELECT \
- (GENMASK_ULL(7, 0) | GENMASK_ULL(35, 32))
-#define KVM_PMU_MASKED_ENTRY_UMASK_MASK (GENMASK_ULL(63, 56))
-#define KVM_PMU_MASKED_ENTRY_UMASK_MATCH (GENMASK_ULL(15, 8))
-#define KVM_PMU_MASKED_ENTRY_EXCLUDE (BIT_ULL(55))
+ (__GENMASK_ULL(7, 0) | __GENMASK_ULL(35, 32))
+#define KVM_PMU_MASKED_ENTRY_UMASK_MASK (__GENMASK_ULL(63, 56))
+#define KVM_PMU_MASKED_ENTRY_UMASK_MATCH (__GENMASK_ULL(15, 8))
+#define KVM_PMU_MASKED_ENTRY_EXCLUDE (_BITULL(55))
#define KVM_PMU_MASKED_ENTRY_UMASK_MASK_SHIFT (56)
/* for KVM_{GET,SET,HAS}_DEVICE_ATTR */
@@ -560,7 +852,7 @@ struct kvm_pmu_event_filter {
#define KVM_VCPU_TSC_OFFSET 0 /* attribute for the TSC offset */
/* x86-specific KVM_EXIT_HYPERCALL flags. */
-#define KVM_EXIT_HYPERCALL_LONG_MODE BIT(0)
+#define KVM_EXIT_HYPERCALL_LONG_MODE _BITULL(0)
#define KVM_X86_DEFAULT_VM 0
#define KVM_X86_SW_PROTECTED_VM 1
diff --git a/arch/x86/include/uapi/asm/kvm_para.h b/arch/x86/include/uapi/asm/kvm_para.h
index 6e64b27b2c1e..a1efa7907a0b 100644
--- a/arch/x86/include/uapi/asm/kvm_para.h
+++ b/arch/x86/include/uapi/asm/kvm_para.h
@@ -92,7 +92,7 @@ struct kvm_clock_pairing {
#define KVM_ASYNC_PF_DELIVERY_AS_INT (1 << 3)
/* MSR_KVM_ASYNC_PF_INT */
-#define KVM_ASYNC_PF_VEC_MASK GENMASK(7, 0)
+#define KVM_ASYNC_PF_VEC_MASK __GENMASK(7, 0)
/* MSR_KVM_MIGRATION_CONTROL */
#define KVM_MIGRATION_READY (1 << 0)
@@ -142,7 +142,6 @@ struct kvm_vcpu_pv_apf_data {
__u32 token;
__u8 pad[56];
- __u32 enabled;
};
#define KVM_PV_EOI_BIT 0
diff --git a/arch/x86/include/uapi/asm/processor-flags.h b/arch/x86/include/uapi/asm/processor-flags.h
index d898432947ff..f1a4adc78272 100644
--- a/arch/x86/include/uapi/asm/processor-flags.h
+++ b/arch/x86/include/uapi/asm/processor-flags.h
@@ -139,6 +139,13 @@
#define X86_CR4_LAM_SUP_BIT 28 /* LAM for supervisor pointers */
#define X86_CR4_LAM_SUP _BITUL(X86_CR4_LAM_SUP_BIT)
+#ifdef __x86_64__
+#define X86_CR4_FRED_BIT 32 /* enable FRED kernel entry */
+#define X86_CR4_FRED _BITUL(X86_CR4_FRED_BIT)
+#else
+#define X86_CR4_FRED (0)
+#endif
+
/*
* x86-64 Task Priority Register, CR8
*/
diff --git a/arch/x86/include/uapi/asm/setup_data.h b/arch/x86/include/uapi/asm/setup_data.h
new file mode 100644
index 000000000000..b111b0c18544
--- /dev/null
+++ b/arch/x86/include/uapi/asm/setup_data.h
@@ -0,0 +1,83 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _UAPI_ASM_X86_SETUP_DATA_H
+#define _UAPI_ASM_X86_SETUP_DATA_H
+
+/* setup_data/setup_indirect types */
+#define SETUP_NONE 0
+#define SETUP_E820_EXT 1
+#define SETUP_DTB 2
+#define SETUP_PCI 3
+#define SETUP_EFI 4
+#define SETUP_APPLE_PROPERTIES 5
+#define SETUP_JAILHOUSE 6
+#define SETUP_CC_BLOB 7
+#define SETUP_IMA 8
+#define SETUP_RNG_SEED 9
+#define SETUP_ENUM_MAX SETUP_RNG_SEED
+
+#define SETUP_INDIRECT (1<<31)
+#define SETUP_TYPE_MAX (SETUP_ENUM_MAX | SETUP_INDIRECT)
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+
+/* extensible setup data list node */
+struct setup_data {
+ __u64 next;
+ __u32 type;
+ __u32 len;
+ __u8 data[];
+};
+
+/* extensible setup indirect data node */
+struct setup_indirect {
+ __u32 type;
+ __u32 reserved; /* Reserved, must be set to zero. */
+ __u64 len;
+ __u64 addr;
+};
+
+/*
+ * The E820 memory region entry of the boot protocol ABI:
+ */
+struct boot_e820_entry {
+ __u64 addr;
+ __u64 size;
+ __u32 type;
+} __attribute__((packed));
+
+/*
+ * The boot loader is passing platform information via this Jailhouse-specific
+ * setup data structure.
+ */
+struct jailhouse_setup_data {
+ struct {
+ __u16 version;
+ __u16 compatible_version;
+ } __attribute__((packed)) hdr;
+ struct {
+ __u16 pm_timer_address;
+ __u16 num_cpus;
+ __u64 pci_mmconfig_base;
+ __u32 tsc_khz;
+ __u32 apic_khz;
+ __u8 standard_ioapic;
+ __u8 cpu_ids[255];
+ } __attribute__((packed)) v1;
+ struct {
+ __u32 flags;
+ } __attribute__((packed)) v2;
+} __attribute__((packed));
+
+/*
+ * IMA buffer setup data information from the previous kernel during kexec
+ */
+struct ima_setup_data {
+ __u64 addr;
+ __u64 size;
+} __attribute__((packed));
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _UAPI_ASM_X86_SETUP_DATA_H */
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 0000325ab98f..74077694da7d 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -33,6 +33,7 @@ KASAN_SANITIZE_sev.o := n
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.
@@ -48,6 +49,7 @@ obj-y += platform-quirks.o
obj-y += process_$(BITS).o signal.o signal_$(BITS).o
obj-y += traps.o idt.o irq.o irq_$(BITS).o dumpstack_$(BITS).o
obj-y += time.o ioport.o dumpstack.o nmi.o
+obj-$(CONFIG_X86_FRED) += fred.o
obj-$(CONFIG_MODIFY_LDT_SYSCALL) += ldt.o
obj-$(CONFIG_X86_KERNEL_IBT) += ibt_selftest.o
obj-y += setup.o x86_init.o i8259.o irqinit.o
@@ -98,11 +100,11 @@ obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o
obj-$(CONFIG_X86_TSC) += trace_clock.o
obj-$(CONFIG_TRACING) += trace.o
obj-$(CONFIG_RETHOOK) += rethook.o
-obj-$(CONFIG_CRASH_CORE) += crash_core_$(BITS).o
+obj-$(CONFIG_VMCORE_INFO) += vmcore_info_$(BITS).o
obj-$(CONFIG_KEXEC_CORE) += machine_kexec_$(BITS).o
-obj-$(CONFIG_KEXEC_CORE) += relocate_kernel_$(BITS).o crash.o
+obj-$(CONFIG_KEXEC_CORE) += relocate_kernel_$(BITS).o
obj-$(CONFIG_KEXEC_FILE) += kexec-bzimage64.o
-obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o
+obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o crash.o
obj-y += kprobes/
obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_X86_32) += doublefault_32.o
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 85a3ce2a3666..4bf82dbd2a6b 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -164,35 +164,6 @@ static int __init acpi_parse_madt(struct acpi_table_header *table)
return 0;
}
-/**
- * acpi_register_lapic - register a local apic and generates a logic cpu number
- * @id: local apic id to register
- * @acpiid: ACPI id to register
- * @enabled: this cpu is enabled or not
- *
- * Returns the logic cpu number which maps to the local apic
- */
-static int acpi_register_lapic(int id, u32 acpiid, u8 enabled)
-{
- int cpu;
-
- if (id >= MAX_LOCAL_APIC) {
- pr_info("skipped apicid that is too big\n");
- return -EINVAL;
- }
-
- if (!enabled) {
- ++disabled_cpus;
- return -EINVAL;
- }
-
- cpu = generic_processor_info(id);
- if (cpu >= 0)
- early_per_cpu(x86_cpu_to_acpiid, cpu) = acpiid;
-
- return cpu;
-}
-
static bool __init acpi_is_processor_usable(u32 lapic_flags)
{
if (lapic_flags & ACPI_MADT_ENABLED)
@@ -254,7 +225,7 @@ acpi_parse_x2apic(union acpi_subtable_headers *header, const unsigned long end)
return 0;
}
- acpi_register_lapic(apic_id, processor->uid, enabled);
+ topology_register_apic(apic_id, processor->uid, enabled);
#else
pr_warn("x2apic entry ignored\n");
#endif
@@ -289,9 +260,9 @@ acpi_parse_lapic(union acpi_subtable_headers * header, const unsigned long end)
* to not preallocating memory for all NR_CPUS
* when we use CPU hotplug.
*/
- acpi_register_lapic(processor->id, /* APIC ID */
- processor->processor_id, /* ACPI ID */
- processor->lapic_flags & ACPI_MADT_ENABLED);
+ topology_register_apic(processor->id, /* APIC ID */
+ processor->processor_id, /* ACPI ID */
+ processor->lapic_flags & ACPI_MADT_ENABLED);
has_lapic_cpus = true;
return 0;
@@ -309,9 +280,9 @@ acpi_parse_sapic(union acpi_subtable_headers *header, const unsigned long end)
acpi_table_print_madt_entry(&header->common);
- acpi_register_lapic((processor->id << 8) | processor->eid,/* APIC ID */
- processor->processor_id, /* ACPI ID */
- processor->lapic_flags & ACPI_MADT_ENABLED);
+ topology_register_apic((processor->id << 8) | processor->eid,/* APIC ID */
+ processor->processor_id, /* ACPI ID */
+ processor->lapic_flags & ACPI_MADT_ENABLED);
return 0;
}
@@ -844,12 +815,10 @@ static int acpi_map_cpu2node(acpi_handle handle, int cpu, int physid)
return 0;
}
-int acpi_map_cpu(acpi_handle handle, phys_cpuid_t physid, u32 acpi_id,
- int *pcpu)
+int acpi_map_cpu(acpi_handle handle, phys_cpuid_t physid, u32 acpi_id, int *pcpu)
{
- int cpu;
+ int cpu = topology_hotplug_apic(physid, acpi_id);
- cpu = acpi_register_lapic(physid, acpi_id, ACPI_MADT_ENABLED);
if (cpu < 0) {
pr_info("Unable to map lapic to logical cpu number\n");
return cpu;
@@ -868,15 +837,11 @@ int acpi_unmap_cpu(int cpu)
#ifdef CONFIG_ACPI_NUMA
set_apicid_to_node(per_cpu(x86_cpu_to_apicid, cpu), NUMA_NO_NODE);
#endif
-
- per_cpu(x86_cpu_to_apicid, cpu) = BAD_APICID;
- set_cpu_present(cpu, false);
- num_processors--;
-
- return (0);
+ topology_hotunplug_apic(cpu);
+ return 0;
}
EXPORT_SYMBOL(acpi_unmap_cpu);
-#endif /* CONFIG_ACPI_HOTPLUG_CPU */
+#endif /* CONFIG_ACPI_HOTPLUG_CPU */
int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base)
{
diff --git a/arch/x86/kernel/acpi/cppc.c b/arch/x86/kernel/acpi/cppc.c
index 8d8752b44f11..ff8f25faca3d 100644
--- a/arch/x86/kernel/acpi/cppc.c
+++ b/arch/x86/kernel/acpi/cppc.c
@@ -20,7 +20,7 @@ bool cpc_supported_by_cpu(void)
(boot_cpu_data.x86_model >= 0x20 && boot_cpu_data.x86_model <= 0x2f)))
return true;
else if (boot_cpu_data.x86 == 0x17 &&
- boot_cpu_data.x86_model >= 0x70 && boot_cpu_data.x86_model <= 0x7f)
+ boot_cpu_data.x86_model >= 0x30 && boot_cpu_data.x86_model <= 0x7f)
return true;
return boot_cpu_has(X86_FEATURE_CPPC);
}
diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c
index 401808b47af3..f3ffd0a3a012 100644
--- a/arch/x86/kernel/acpi/cstate.c
+++ b/arch/x86/kernel/acpi/cstate.c
@@ -131,8 +131,8 @@ static long acpi_processor_ffh_cstate_probe_cpu(void *_cx)
cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &edx);
/* Check whether this particular cx_type (in CST) is supported or not */
- cstate_type = ((cx->address >> MWAIT_SUBSTATE_SIZE) &
- MWAIT_CSTATE_MASK) + 1;
+ cstate_type = (((cx->address >> MWAIT_SUBSTATE_SIZE) &
+ MWAIT_CSTATE_MASK) + 1) & MWAIT_CSTATE_MASK;
edx_part = edx >> (cstate_type * MWAIT_SUBSTATE_SIZE);
num_cstate_subtype = edx_part & MWAIT_SUBSTATE_MASK;
diff --git a/arch/x86/kernel/acpi/wakeup_64.S b/arch/x86/kernel/acpi/wakeup_64.S
index d5d8a352eafa..94ff83f3d3fe 100644
--- a/arch/x86/kernel/acpi/wakeup_64.S
+++ b/arch/x86/kernel/acpi/wakeup_64.S
@@ -17,7 +17,7 @@
* Hooray, we are in Long 64-bit mode (but still running in low memory)
*/
SYM_FUNC_START(wakeup_long64)
- movq saved_magic, %rax
+ movq saved_magic(%rip), %rax
movq $0x123456789abcdef0, %rdx
cmpq %rdx, %rax
je 2f
@@ -33,14 +33,14 @@ SYM_FUNC_START(wakeup_long64)
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
- movq saved_rsp, %rsp
+ movq saved_rsp(%rip), %rsp
- movq saved_rbx, %rbx
- movq saved_rdi, %rdi
- movq saved_rsi, %rsi
- movq saved_rbp, %rbp
+ movq saved_rbx(%rip), %rbx
+ movq saved_rdi(%rip), %rdi
+ movq saved_rsi(%rip), %rsi
+ movq saved_rbp(%rip), %rbp
- movq saved_rip, %rax
+ movq saved_rip(%rip), %rax
ANNOTATE_RETPOLINE_SAFE
jmp *%rax
SYM_FUNC_END(wakeup_long64)
@@ -72,11 +72,11 @@ SYM_FUNC_START(do_suspend_lowlevel)
movq $.Lresume_point, saved_rip(%rip)
- movq %rsp, saved_rsp
- movq %rbp, saved_rbp
- movq %rbx, saved_rbx
- movq %rdi, saved_rdi
- movq %rsi, saved_rsi
+ movq %rsp, saved_rsp(%rip)
+ movq %rbp, saved_rbp(%rip)
+ movq %rbx, saved_rbx(%rip)
+ movq %rdi, saved_rdi(%rip)
+ movq %rsi, saved_rsi(%rip)
addq $8, %rsp
movl $3, %edi
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index 1d85cb7071cb..45a280f2161c 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -45,7 +45,7 @@ EXPORT_SYMBOL_GPL(alternatives_patched);
#define DA_ENDBR 0x08
#define DA_SMP 0x10
-static unsigned int __initdata_or_module debug_alternative;
+static unsigned int debug_alternative;
static int __init debug_alt(char *str)
{
@@ -133,7 +133,7 @@ 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 __init_or_module add_nop(u8 *instr, unsigned int len)
+static void add_nop(u8 *instr, unsigned int len)
{
u8 *target = instr + len;
@@ -206,7 +206,7 @@ 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 __init_or_module
+static bool
__optimize_nops(u8 *instr, size_t len, struct insn *insn, int *next, int *prev, int *target)
{
int i = *next - insn->length;
@@ -335,8 +335,7 @@ bool need_reloc(unsigned long offset, u8 *src, size_t src_len)
return (target < src || target > src + src_len);
}
-static void __init_or_module noinline
-apply_relocation(u8 *buf, size_t len, u8 *dest, u8 *src, size_t src_len)
+void apply_relocation(u8 *buf, size_t len, u8 *dest, u8 *src, size_t src_len)
{
int prev, target = 0;
@@ -545,7 +544,7 @@ static inline bool is_jcc32(struct insn *insn)
return insn->opcode.bytes[0] == 0x0f && (insn->opcode.bytes[1] & 0xf0) == 0x80;
}
-#if defined(CONFIG_RETPOLINE) && defined(CONFIG_OBJTOOL)
+#if defined(CONFIG_MITIGATION_RETPOLINE) && defined(CONFIG_OBJTOOL)
/*
* CALL/JMP *%\reg
@@ -709,8 +708,8 @@ static int patch_retpoline(void *addr, struct insn *insn, u8 *bytes)
/*
* The compiler is supposed to EMIT an INT3 after every unconditional
* JMP instruction due to AMD BTC. However, if the compiler is too old
- * or SLS isn't enabled, we still need an INT3 after indirect JMPs
- * even on Intel.
+ * or MITIGATION_SLS isn't enabled, we still need an INT3 after
+ * indirect JMPs even on Intel.
*/
if (op == JMP32_INSN_OPCODE && i < insn->length)
bytes[i++] = INT3_INSN_OPCODE;
@@ -770,7 +769,7 @@ void __init_or_module noinline apply_retpolines(s32 *start, s32 *end)
}
}
-#ifdef CONFIG_RETHUNK
+#ifdef CONFIG_MITIGATION_RETHUNK
/*
* Rewrite the compiler generated return thunk tail-calls.
@@ -843,14 +842,14 @@ void __init_or_module noinline apply_returns(s32 *start, s32 *end)
}
#else
void __init_or_module noinline apply_returns(s32 *start, s32 *end) { }
-#endif /* CONFIG_RETHUNK */
+#endif /* CONFIG_MITIGATION_RETHUNK */
-#else /* !CONFIG_RETPOLINE || !CONFIG_OBJTOOL */
+#else /* !CONFIG_MITIGATION_RETPOLINE || !CONFIG_OBJTOOL */
void __init_or_module noinline apply_retpolines(s32 *start, s32 *end) { }
void __init_or_module noinline apply_returns(s32 *start, s32 *end) { }
-#endif /* CONFIG_RETPOLINE && CONFIG_OBJTOOL */
+#endif /* CONFIG_MITIGATION_RETPOLINE && CONFIG_OBJTOOL */
#ifdef CONFIG_X86_KERNEL_IBT
@@ -1805,7 +1804,7 @@ static inline temp_mm_state_t use_temporary_mm(struct mm_struct *mm)
* restoring the previous mm.
*/
if (this_cpu_read(cpu_tlbstate_shared.is_lazy))
- leave_mm(smp_processor_id());
+ leave_mm();
temp_state.mm = this_cpu_read(cpu_tlbstate.loaded_mm);
switch_mm_irqs_off(NULL, mm, current);
diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c
index 053f6dcc6b2c..5bf5f9fc5753 100644
--- a/arch/x86/kernel/amd_nb.c
+++ b/arch/x86/kernel/amd_nb.c
@@ -386,7 +386,7 @@ struct resource *amd_get_mmconfig_range(struct resource *res)
int amd_get_subcaches(int cpu)
{
- struct pci_dev *link = node_to_amd_nb(topology_die_id(cpu))->link;
+ struct pci_dev *link = node_to_amd_nb(topology_amd_node_id(cpu))->link;
unsigned int mask;
if (!amd_nb_has_feature(AMD_NB_L3_PARTITIONING))
@@ -400,7 +400,7 @@ int amd_get_subcaches(int cpu)
int amd_set_subcaches(int cpu, unsigned long mask)
{
static unsigned int reset, ban;
- struct amd_northbridge *nb = node_to_amd_nb(topology_die_id(cpu));
+ struct amd_northbridge *nb = node_to_amd_nb(topology_amd_node_id(cpu));
unsigned int reg;
int cuid;
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 4667bc4b00ab..a42d8a6f7149 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -19,6 +19,7 @@
#include <linux/kernel_stat.h>
#include <linux/mc146818rtc.h>
#include <linux/acpi_pmtmr.h>
+#include <linux/bitmap.h>
#include <linux/clockchips.h>
#include <linux/interrupt.h>
#include <linux/memblock.h>
@@ -67,10 +68,6 @@
#include "local.h"
-unsigned int num_processors;
-
-unsigned disabled_cpus;
-
/* Processor that is doing the boot up */
u32 boot_cpu_physical_apicid __ro_after_init = BAD_APICID;
EXPORT_SYMBOL_GPL(boot_cpu_physical_apicid);
@@ -78,18 +75,6 @@ EXPORT_SYMBOL_GPL(boot_cpu_physical_apicid);
u8 boot_cpu_apic_version __ro_after_init;
/*
- * Bitmask of physically existing CPUs:
- */
-physid_mask_t phys_cpu_present_map;
-
-/*
- * Processor to be disabled specified by kernel parameter
- * disable_cpu_apicid=<int>, mostly used for the kdump 2nd kernel to
- * avoid undefined behaviour caused by sending INIT from AP to BSP.
- */
-static u32 disabled_cpu_apicid __ro_after_init = BAD_APICID;
-
-/*
* This variable controls which CPUs receive external NMIs. By default,
* external NMIs are delivered only to the BSP.
*/
@@ -108,14 +93,6 @@ static inline bool apic_accessible(void)
return x2apic_mode || apic_mmio_base;
}
-/*
- * Map cpu index to physical APIC ID
- */
-DEFINE_EARLY_PER_CPU_READ_MOSTLY(u32, x86_cpu_to_apicid, BAD_APICID);
-DEFINE_EARLY_PER_CPU_READ_MOSTLY(u32, x86_cpu_to_acpiid, U32_MAX);
-EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_apicid);
-EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_acpiid);
-
#ifdef CONFIG_X86_32
/* Local APIC was disabled by the BIOS and enabled by the kernel */
static int enabled_via_apicbase __ro_after_init;
@@ -261,16 +238,6 @@ u64 native_apic_icr_read(void)
return icr1 | ((u64)icr2 << 32);
}
-#ifdef CONFIG_X86_32
-/**
- * get_physical_broadcast - Get number of physical broadcast IDs
- */
-int get_physical_broadcast(void)
-{
- return modern_apic() ? 0xff : 0xf;
-}
-#endif
-
/**
* lapic_get_maxlvt - get the maximum number of local vector table entries
*/
@@ -1549,9 +1516,6 @@ static void setup_local_APIC(void)
apic_write(APIC_ESR, 0);
}
#endif
- /* Validate that the APIC is registered if required */
- BUG_ON(apic->apic_id_registered && !apic->apic_id_registered());
-
/*
* Intel recommends to set DFR, LDR and TPR before enabling
* an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel
@@ -1690,8 +1654,6 @@ void apic_ap_setup(void)
end_local_APIC_setup();
}
-static __init void cpu_set_boot_apic(void);
-
static __init void apic_read_boot_cpu_id(bool x2apic)
{
/*
@@ -1706,7 +1668,8 @@ static __init void apic_read_boot_cpu_id(bool x2apic)
boot_cpu_physical_apicid = read_apic_id();
boot_cpu_apic_version = GET_APIC_VERSION(apic_read(APIC_LVR));
}
- cpu_set_boot_apic();
+ topology_register_boot_apic(boot_cpu_physical_apicid);
+ x86_32_probe_bigsmp_early();
}
#ifdef CONFIG_X86_X2APIC
@@ -2091,7 +2054,6 @@ void __init init_apic_mappings(void)
pr_info("APIC: disable apic facility\n");
apic_disable();
}
- num_processors = 1;
}
}
@@ -2305,155 +2267,6 @@ void disconnect_bsp_APIC(int virt_wire_setup)
apic_write(APIC_LVT1, value);
}
-/*
- * The number of allocated logical CPU IDs. Since logical CPU IDs are allocated
- * contiguously, it equals to current allocated max logical CPU ID plus 1.
- * All allocated CPU IDs should be in the [0, nr_logical_cpuids) range,
- * so the maximum of nr_logical_cpuids is nr_cpu_ids.
- *
- * NOTE: Reserve 0 for BSP.
- */
-static int nr_logical_cpuids = 1;
-
-/*
- * Used to store mapping between logical CPU IDs and APIC IDs.
- */
-u32 cpuid_to_apicid[] = { [0 ... NR_CPUS - 1] = BAD_APICID, };
-
-bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
-{
- return phys_id == (u64)cpuid_to_apicid[cpu];
-}
-
-#ifdef CONFIG_SMP
-static void cpu_mark_primary_thread(unsigned int cpu, unsigned int apicid)
-{
- /* Isolate the SMT bit(s) in the APICID and check for 0 */
- u32 mask = (1U << (fls(smp_num_siblings) - 1)) - 1;
-
- if (smp_num_siblings == 1 || !(apicid & mask))
- cpumask_set_cpu(cpu, &__cpu_primary_thread_mask);
-}
-
-/*
- * Due to the utter mess of CPUID evaluation smp_num_siblings is not valid
- * during early boot. Initialize the primary thread mask before SMP
- * bringup.
- */
-static int __init smp_init_primary_thread_mask(void)
-{
- unsigned int cpu;
-
- /*
- * XEN/PV provides either none or useless topology information.
- * Pretend that all vCPUs are primary threads.
- */
- if (xen_pv_domain()) {
- cpumask_copy(&__cpu_primary_thread_mask, cpu_possible_mask);
- return 0;
- }
-
- for (cpu = 0; cpu < nr_logical_cpuids; cpu++)
- cpu_mark_primary_thread(cpu, cpuid_to_apicid[cpu]);
- return 0;
-}
-early_initcall(smp_init_primary_thread_mask);
-#else
-static inline void cpu_mark_primary_thread(unsigned int cpu, unsigned int apicid) { }
-#endif
-
-/*
- * Should use this API to allocate logical CPU IDs to keep nr_logical_cpuids
- * and cpuid_to_apicid[] synchronized.
- */
-static int allocate_logical_cpuid(int apicid)
-{
- int i;
-
- /*
- * cpuid <-> apicid mapping is persistent, so when a cpu is up,
- * check if the kernel has allocated a cpuid for it.
- */
- for (i = 0; i < nr_logical_cpuids; i++) {
- if (cpuid_to_apicid[i] == apicid)
- return i;
- }
-
- /* Allocate a new cpuid. */
- if (nr_logical_cpuids >= nr_cpu_ids) {
- WARN_ONCE(1, "APIC: NR_CPUS/possible_cpus limit of %u reached. "
- "Processor %d/0x%x and the rest are ignored.\n",
- nr_cpu_ids, nr_logical_cpuids, apicid);
- return -EINVAL;
- }
-
- cpuid_to_apicid[nr_logical_cpuids] = apicid;
- return nr_logical_cpuids++;
-}
-
-static void cpu_update_apic(int cpu, u32 apicid)
-{
-#if defined(CONFIG_SMP) || defined(CONFIG_X86_64)
- early_per_cpu(x86_cpu_to_apicid, cpu) = apicid;
-#endif
- set_cpu_possible(cpu, true);
- physid_set(apicid, phys_cpu_present_map);
- set_cpu_present(cpu, true);
- num_processors++;
-
- if (system_state != SYSTEM_BOOTING)
- cpu_mark_primary_thread(cpu, apicid);
-}
-
-static __init void cpu_set_boot_apic(void)
-{
- cpuid_to_apicid[0] = boot_cpu_physical_apicid;
- cpu_update_apic(0, boot_cpu_physical_apicid);
- x86_32_probe_bigsmp_early();
-}
-
-int generic_processor_info(int apicid)
-{
- int cpu, max = nr_cpu_ids;
-
- /* The boot CPU must be set before MADT/MPTABLE parsing happens */
- if (cpuid_to_apicid[0] == BAD_APICID)
- panic("Boot CPU APIC not registered yet\n");
-
- if (apicid == boot_cpu_physical_apicid)
- return 0;
-
- if (disabled_cpu_apicid == apicid) {
- int thiscpu = num_processors + disabled_cpus;
-
- pr_warn("APIC: Disabling requested cpu. Processor %d/0x%x ignored.\n",
- thiscpu, apicid);
-
- disabled_cpus++;
- return -ENODEV;
- }
-
- if (num_processors >= nr_cpu_ids) {
- int thiscpu = max + disabled_cpus;
-
- pr_warn("APIC: NR_CPUS/possible_cpus limit of %i reached. "
- "Processor %d/0x%x ignored.\n", max, thiscpu, apicid);
-
- disabled_cpus++;
- return -EINVAL;
- }
-
- cpu = allocate_logical_cpuid(apicid);
- if (cpu < 0) {
- disabled_cpus++;
- return -EINVAL;
- }
-
- cpu_update_apic(cpu, apicid);
- return cpu;
-}
-
-
void __irq_msi_compose_msg(struct irq_cfg *cfg, struct msi_msg *msg,
bool dmar)
{
@@ -2496,10 +2309,7 @@ EXPORT_SYMBOL_GPL(x86_msi_msg_get_destid);
static void __init apic_bsp_up_setup(void)
{
-#ifdef CONFIG_X86_64
- apic_write(APIC_ID, apic->set_apic_id(boot_cpu_physical_apicid));
-#endif
- physid_set_mask_of_physid(boot_cpu_physical_apicid, &phys_cpu_present_map);
+ reset_phys_cpu_present_map(boot_cpu_physical_apicid);
}
/**
@@ -2845,15 +2655,6 @@ static int __init lapic_insert_resource(void)
*/
late_initcall(lapic_insert_resource);
-static int __init apic_set_disabled_cpu_apicid(char *arg)
-{
- if (!arg || !get_option(&arg, &disabled_cpu_apicid))
- return -EINVAL;
-
- return 0;
-}
-early_param("disable_cpu_apicid", apic_set_disabled_cpu_apicid);
-
static int __init apic_set_extnmi(char *arg)
{
if (!arg)
diff --git a/arch/x86/kernel/apic/apic_common.c b/arch/x86/kernel/apic/apic_common.c
index 8a00141073ea..9ef3be866832 100644
--- a/arch/x86/kernel/apic/apic_common.c
+++ b/arch/x86/kernel/apic/apic_common.c
@@ -18,16 +18,6 @@ u32 apic_flat_calc_apicid(unsigned int cpu)
return 1U << cpu;
}
-bool default_check_apicid_used(physid_mask_t *map, u32 apicid)
-{
- return physid_isset(apicid, *map);
-}
-
-void default_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap)
-{
- *retmap = *phys_map;
-}
-
u32 default_cpu_present_to_apicid(int mps_cpu)
{
if (mps_cpu < nr_cpu_ids && cpu_present(mps_cpu))
@@ -37,11 +27,6 @@ u32 default_cpu_present_to_apicid(int mps_cpu)
}
EXPORT_SYMBOL_GPL(default_cpu_present_to_apicid);
-bool default_apic_id_registered(void)
-{
- return physid_isset(read_apic_id(), phys_cpu_present_map);
-}
-
/*
* Set up the logical destination ID when the APIC operates in logical
* destination mode.
diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c
index b295a056a4fc..f37ad3392fec 100644
--- a/arch/x86/kernel/apic/apic_flat_64.c
+++ b/arch/x86/kernel/apic/apic_flat_64.c
@@ -61,16 +61,6 @@ static u32 flat_get_apic_id(u32 x)
return (x >> 24) & 0xFF;
}
-static u32 set_apic_id(u32 id)
-{
- return (id & 0xFF) << 24;
-}
-
-static u32 flat_phys_pkg_id(u32 initial_apic_id, int index_msb)
-{
- return initial_apic_id >> index_msb;
-}
-
static int flat_probe(void)
{
return 1;
@@ -80,7 +70,6 @@ static struct apic apic_flat __ro_after_init = {
.name = "flat",
.probe = flat_probe,
.acpi_madt_oem_check = flat_acpi_madt_oem_check,
- .apic_id_registered = default_apic_id_registered,
.dest_mode_logical = true,
@@ -88,11 +77,9 @@ static struct apic apic_flat __ro_after_init = {
.init_apic_ldr = default_init_apic_ldr,
.cpu_present_to_apicid = default_cpu_present_to_apicid,
- .phys_pkg_id = flat_phys_pkg_id,
.max_apic_id = 0xFE,
.get_apic_id = flat_get_apic_id,
- .set_apic_id = set_apic_id,
.calc_dest_apicid = apic_flat_calc_apicid,
@@ -151,18 +138,15 @@ static struct apic apic_physflat __ro_after_init = {
.name = "physical flat",
.probe = physflat_probe,
.acpi_madt_oem_check = physflat_acpi_madt_oem_check,
- .apic_id_registered = default_apic_id_registered,
.dest_mode_logical = false,
.disable_esr = 0,
.cpu_present_to_apicid = default_cpu_present_to_apicid,
- .phys_pkg_id = flat_phys_pkg_id,
.max_apic_id = 0xFE,
.get_apic_id = flat_get_apic_id,
- .set_apic_id = set_apic_id,
.calc_dest_apicid = apic_default_calc_apicid,
diff --git a/arch/x86/kernel/apic/apic_noop.c b/arch/x86/kernel/apic/apic_noop.c
index 9f1d553eb48f..b5bb7a2e8340 100644
--- a/arch/x86/kernel/apic/apic_noop.c
+++ b/arch/x86/kernel/apic/apic_noop.c
@@ -29,7 +29,6 @@ static void noop_send_IPI_self(int vector) { }
static void noop_apic_icr_write(u32 low, u32 id) { }
static int noop_wakeup_secondary_cpu(u32 apicid, unsigned long start_eip) { return -1; }
static u64 noop_apic_icr_read(void) { return 0; }
-static u32 noop_phys_pkg_id(u32 cpuid_apic, int index_msb) { return 0; }
static u32 noop_get_apic_id(u32 apicid) { return 0; }
static void noop_apic_eoi(void) { }
@@ -51,12 +50,8 @@ struct apic apic_noop __ro_after_init = {
.disable_esr = 0,
- .check_apicid_used = default_check_apicid_used,
- .ioapic_phys_id_map = default_ioapic_phys_id_map,
.cpu_present_to_apicid = default_cpu_present_to_apicid,
- .phys_pkg_id = noop_phys_pkg_id,
-
.max_apic_id = 0xFE,
.get_apic_id = noop_get_apic_id,
diff --git a/arch/x86/kernel/apic/apic_numachip.c b/arch/x86/kernel/apic/apic_numachip.c
index 7d0c51b9d3bc..16410f087b7a 100644
--- a/arch/x86/kernel/apic/apic_numachip.c
+++ b/arch/x86/kernel/apic/apic_numachip.c
@@ -38,11 +38,6 @@ static u32 numachip1_get_apic_id(u32 x)
return id;
}
-static u32 numachip1_set_apic_id(u32 id)
-{
- return (id & 0xff) << 24;
-}
-
static u32 numachip2_get_apic_id(u32 x)
{
u64 mcfg;
@@ -51,16 +46,6 @@ static u32 numachip2_get_apic_id(u32 x)
return ((mcfg >> (28 - 8)) & 0xfff00) | (x >> 24);
}
-static u32 numachip2_set_apic_id(u32 id)
-{
- return id << 24;
-}
-
-static u32 numachip_phys_pkg_id(u32 initial_apic_id, int index_msb)
-{
- return initial_apic_id >> index_msb;
-}
-
static void numachip1_apic_icr_write(int apicid, unsigned int val)
{
write_lcsr(CSR_G3_EXT_IRQ_GEN, (apicid << 16) | val);
@@ -227,11 +212,9 @@ static const struct apic apic_numachip1 __refconst = {
.disable_esr = 0,
.cpu_present_to_apicid = default_cpu_present_to_apicid,
- .phys_pkg_id = numachip_phys_pkg_id,
.max_apic_id = UINT_MAX,
.get_apic_id = numachip1_get_apic_id,
- .set_apic_id = numachip1_set_apic_id,
.calc_dest_apicid = apic_default_calc_apicid,
@@ -263,11 +246,9 @@ static const struct apic apic_numachip2 __refconst = {
.disable_esr = 0,
.cpu_present_to_apicid = default_cpu_present_to_apicid,
- .phys_pkg_id = numachip_phys_pkg_id,
.max_apic_id = UINT_MAX,
.get_apic_id = numachip2_get_apic_id,
- .set_apic_id = numachip2_set_apic_id,
.calc_dest_apicid = apic_default_calc_apicid,
diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp_32.c
index 5a0d60b38e6b..9285d500d5b4 100644
--- a/arch/x86/kernel/apic/bigsmp_32.c
+++ b/arch/x86/kernel/apic/bigsmp_32.c
@@ -18,22 +18,6 @@ static u32 bigsmp_get_apic_id(u32 x)
return (x >> 24) & 0xFF;
}
-static bool bigsmp_check_apicid_used(physid_mask_t *map, u32 apicid)
-{
- return false;
-}
-
-static void bigsmp_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap)
-{
- /* For clustered we don't have a good way to do this yet - hack */
- physids_promote(0xFFL, retmap);
-}
-
-static u32 bigsmp_phys_pkg_id(u32 cpuid_apic, int index_msb)
-{
- return cpuid_apic >> index_msb;
-}
-
static void bigsmp_send_IPI_allbutself(int vector)
{
default_send_IPI_mask_allbutself_phys(cpu_online_mask, vector);
@@ -84,14 +68,10 @@ static struct apic apic_bigsmp __ro_after_init = {
.disable_esr = 1,
- .check_apicid_used = bigsmp_check_apicid_used,
- .ioapic_phys_id_map = bigsmp_ioapic_phys_id_map,
.cpu_present_to_apicid = default_cpu_present_to_apicid,
- .phys_pkg_id = bigsmp_phys_pkg_id,
.max_apic_id = 0xFE,
.get_apic_id = bigsmp_get_apic_id,
- .set_apic_id = NULL,
.calc_dest_apicid = apic_default_calc_apicid,
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 40c7cf180c20..477b740b2f26 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1458,20 +1458,20 @@ void restore_boot_irq_mode(void)
*
* by Matt Domsch <Matt_Domsch@dell.com> Tue Dec 21 12:25:05 CST 1999
*/
-void __init setup_ioapic_ids_from_mpc_nocheck(void)
+static void __init setup_ioapic_ids_from_mpc_nocheck(void)
{
+ DECLARE_BITMAP(phys_id_present_map, MAX_LOCAL_APIC);
+ const u32 broadcast_id = 0xF;
union IO_APIC_reg_00 reg_00;
- physid_mask_t phys_id_present_map;
- int ioapic_idx;
- int i;
unsigned char old_id;
unsigned long flags;
+ int ioapic_idx, i;
/*
* This is broken; anything with a real cpu count has to
* circumvent this idiocy regardless.
*/
- apic->ioapic_phys_id_map(&phys_cpu_present_map, &phys_id_present_map);
+ copy_phys_cpu_present_map(phys_id_present_map);
/*
* Set the IOAPIC ID to the value stored in the MPC table.
@@ -1484,11 +1484,10 @@ void __init setup_ioapic_ids_from_mpc_nocheck(void)
old_id = mpc_ioapic_id(ioapic_idx);
- if (mpc_ioapic_id(ioapic_idx) >= get_physical_broadcast()) {
- printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
- ioapic_idx, mpc_ioapic_id(ioapic_idx));
- printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
- reg_00.bits.ID);
+ if (mpc_ioapic_id(ioapic_idx) >= broadcast_id) {
+ pr_err(FW_BUG "IO-APIC#%d ID is %d in the MPC table!...\n",
+ ioapic_idx, mpc_ioapic_id(ioapic_idx));
+ pr_err("... fixing up to %d. (tell your hw vendor)\n", reg_00.bits.ID);
ioapics[ioapic_idx].mp_config.apicid = reg_00.bits.ID;
}
@@ -1497,23 +1496,21 @@ void __init setup_ioapic_ids_from_mpc_nocheck(void)
* system must have a unique ID or we get lots of nice
* 'stuck on smp_invalidate_needed IPI wait' messages.
*/
- if (apic->check_apicid_used(&phys_id_present_map,
- mpc_ioapic_id(ioapic_idx))) {
- printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n",
- ioapic_idx, mpc_ioapic_id(ioapic_idx));
- for (i = 0; i < get_physical_broadcast(); i++)
- if (!physid_isset(i, phys_id_present_map))
+ if (test_bit(mpc_ioapic_id(ioapic_idx), phys_id_present_map)) {
+ pr_err(FW_BUG "IO-APIC#%d ID %d is already used!...\n",
+ ioapic_idx, mpc_ioapic_id(ioapic_idx));
+ for (i = 0; i < broadcast_id; i++)
+ if (!test_bit(i, phys_id_present_map))
break;
- if (i >= get_physical_broadcast())
+ if (i >= broadcast_id)
panic("Max APIC ID exceeded!\n");
- printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
- i);
- physid_set(i, phys_id_present_map);
+ pr_err("... fixing up to %d. (tell your hw vendor)\n", i);
+ set_bit(i, phys_id_present_map);
ioapics[ioapic_idx].mp_config.apicid = i;
} else {
apic_printk(APIC_VERBOSE, "Setting %d in the phys_id_present_map\n",
mpc_ioapic_id(ioapic_idx));
- physid_set(mpc_ioapic_id(ioapic_idx), phys_id_present_map);
+ set_bit(mpc_ioapic_id(ioapic_idx), phys_id_present_map);
}
/*
@@ -2209,7 +2206,7 @@ static inline void __init check_timer(void)
* 8259A.
*/
if (pin1 == -1) {
- panic_if_irq_remap("BIOS bug: timer not connected to IO-APIC");
+ panic_if_irq_remap(FW_BUG "Timer not connected to IO-APIC");
pin1 = pin2;
apic1 = apic2;
no_pin1 = 1;
@@ -2354,7 +2351,7 @@ static int mp_irqdomain_create(int ioapic)
fwspec.param_count = 1;
fwspec.param[0] = mpc_ioapic_id(ioapic);
- parent = irq_find_matching_fwspec(&fwspec, DOMAIN_BUS_ANY);
+ parent = irq_find_matching_fwspec(&fwspec, DOMAIN_BUS_GENERIC_MSI);
if (!parent) {
if (!cfg->dev)
irq_domain_free_fwnode(fn);
@@ -2494,56 +2491,41 @@ unsigned int arch_dynirq_lower_bound(unsigned int from)
#ifdef CONFIG_X86_32
static int io_apic_get_unique_id(int ioapic, int apic_id)
{
+ static DECLARE_BITMAP(apic_id_map, MAX_LOCAL_APIC);
+ const u32 broadcast_id = 0xF;
union IO_APIC_reg_00 reg_00;
- static physid_mask_t apic_id_map = PHYSID_MASK_NONE;
- physid_mask_t tmp;
unsigned long flags;
int i = 0;
- /*
- * The P4 platform supports up to 256 APIC IDs on two separate APIC
- * buses (one for LAPICs, one for IOAPICs), where predecessors only
- * supports up to 16 on one shared APIC bus.
- *
- * TBD: Expand LAPIC/IOAPIC support on P4-class systems to take full
- * advantage of new APIC bus architecture.
- */
-
- if (physids_empty(apic_id_map))
- apic->ioapic_phys_id_map(&phys_cpu_present_map, &apic_id_map);
+ /* Initialize the ID map */
+ if (bitmap_empty(apic_id_map, MAX_LOCAL_APIC))
+ copy_phys_cpu_present_map(apic_id_map);
raw_spin_lock_irqsave(&ioapic_lock, flags);
reg_00.raw = io_apic_read(ioapic, 0);
raw_spin_unlock_irqrestore(&ioapic_lock, flags);
- if (apic_id >= get_physical_broadcast()) {
- printk(KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying "
- "%d\n", ioapic, apic_id, reg_00.bits.ID);
+ if (apic_id >= broadcast_id) {
+ pr_warn("IOAPIC[%d]: Invalid apic_id %d, trying %d\n",
+ ioapic, apic_id, reg_00.bits.ID);
apic_id = reg_00.bits.ID;
}
- /*
- * Every APIC in a system must have a unique ID or we get lots of nice
- * 'stuck on smp_invalidate_needed IPI wait' messages.
- */
- if (apic->check_apicid_used(&apic_id_map, apic_id)) {
-
- for (i = 0; i < get_physical_broadcast(); i++) {
- if (!apic->check_apicid_used(&apic_id_map, i))
+ /* Every APIC in a system must have a unique ID */
+ if (test_bit(apic_id, apic_id_map)) {
+ for (i = 0; i < broadcast_id; i++) {
+ if (!test_bit(i, apic_id_map))
break;
}
- if (i == get_physical_broadcast())
+ if (i == broadcast_id)
panic("Max apic_id exceeded!\n");
- printk(KERN_WARNING "IOAPIC[%d]: apic_id %d already used, "
- "trying %d\n", ioapic, apic_id, i);
-
+ pr_warn("IOAPIC[%d]: apic_id %d already used, trying %d\n", ioapic, apic_id, i);
apic_id = i;
}
- physid_set_mask_of_physid(apic_id, &tmp);
- physids_or(apic_id_map, apic_id_map, tmp);
+ set_bit(apic_id, apic_id_map);
if (reg_00.bits.ID != apic_id) {
reg_00.bits.ID = apic_id;
@@ -2569,11 +2551,9 @@ static int io_apic_get_unique_id(int ioapic, int apic_id)
static u8 io_apic_unique_id(int idx, u8 id)
{
- if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) &&
- !APIC_XAPIC(boot_cpu_apic_version))
+ if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && !APIC_XAPIC(boot_cpu_apic_version))
return io_apic_get_unique_id(idx, id);
- else
- return id;
+ return id;
}
#else
static u8 io_apic_unique_id(int idx, u8 id)
diff --git a/arch/x86/kernel/apic/local.h b/arch/x86/kernel/apic/local.h
index 9ea6186ea88c..842fe28496be 100644
--- a/arch/x86/kernel/apic/local.h
+++ b/arch/x86/kernel/apic/local.h
@@ -16,8 +16,6 @@
/* X2APIC */
void __x2apic_send_IPI_dest(unsigned int apicid, int vector, unsigned int dest);
u32 x2apic_get_apic_id(u32 id);
-u32 x2apic_set_apic_id(u32 id);
-u32 x2apic_phys_pkg_id(u32 initial_apicid, int index_msb);
void x2apic_send_IPI_all(int vector);
void x2apic_send_IPI_allbutself(int vector);
@@ -63,9 +61,6 @@ void default_send_IPI_allbutself(int vector);
void default_send_IPI_all(int vector);
void default_send_IPI_self(int vector);
-bool default_apic_id_registered(void);
-bool default_check_apicid_used(physid_mask_t *map, u32 apicid);
-
#ifdef CONFIG_X86_32
void default_send_IPI_mask_sequence_logical(const struct cpumask *mask, int vector);
void default_send_IPI_mask_allbutself_logical(const struct cpumask *mask, int vector);
diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c
index c0f78059f06a..f75ee345c02d 100644
--- a/arch/x86/kernel/apic/probe_32.c
+++ b/arch/x86/kernel/apic/probe_32.c
@@ -18,11 +18,6 @@
#include "local.h"
-static u32 default_phys_pkg_id(u32 cpuid_apic, int index_msb)
-{
- return cpuid_apic >> index_msb;
-}
-
static u32 default_get_apic_id(u32 x)
{
unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR));
@@ -43,17 +38,13 @@ static struct apic apic_default __ro_after_init = {
.name = "default",
.probe = probe_default,
- .apic_id_registered = default_apic_id_registered,
.dest_mode_logical = true,
.disable_esr = 0,
- .check_apicid_used = default_check_apicid_used,
.init_apic_ldr = default_init_apic_ldr,
- .ioapic_phys_id_map = default_ioapic_phys_id_map,
.cpu_present_to_apicid = default_cpu_present_to_apicid,
- .phys_pkg_id = default_phys_pkg_id,
.max_apic_id = 0xFE,
.get_apic_id = default_get_apic_id,
diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c
index 28a7d3f2312d..567dbd2fe4b6 100644
--- a/arch/x86/kernel/apic/x2apic_cluster.c
+++ b/arch/x86/kernel/apic/x2apic_cluster.c
@@ -231,16 +231,12 @@ static struct apic apic_x2apic_cluster __ro_after_init = {
.disable_esr = 0,
- .check_apicid_used = NULL,
.init_apic_ldr = init_x2apic_ldr,
- .ioapic_phys_id_map = NULL,
.cpu_present_to_apicid = default_cpu_present_to_apicid,
- .phys_pkg_id = x2apic_phys_pkg_id,
.max_apic_id = UINT_MAX,
.x2apic_set_max_apicid = true,
.get_apic_id = x2apic_get_apic_id,
- .set_apic_id = x2apic_set_apic_id,
.calc_dest_apicid = x2apic_calc_apicid,
diff --git a/arch/x86/kernel/apic/x2apic_phys.c b/arch/x86/kernel/apic/x2apic_phys.c
index 409815a40668..12d4c35547a6 100644
--- a/arch/x86/kernel/apic/x2apic_phys.c
+++ b/arch/x86/kernel/apic/x2apic_phys.c
@@ -129,16 +129,6 @@ u32 x2apic_get_apic_id(u32 id)
return id;
}
-u32 x2apic_set_apic_id(u32 id)
-{
- return id;
-}
-
-u32 x2apic_phys_pkg_id(u32 initial_apicid, int index_msb)
-{
- return initial_apicid >> index_msb;
-}
-
static struct apic apic_x2apic_phys __ro_after_init = {
.name = "physical x2apic",
@@ -150,12 +140,10 @@ static struct apic apic_x2apic_phys __ro_after_init = {
.disable_esr = 0,
.cpu_present_to_apicid = default_cpu_present_to_apicid,
- .phys_pkg_id = x2apic_phys_pkg_id,
.max_apic_id = UINT_MAX,
.x2apic_set_max_apicid = true,
.get_apic_id = x2apic_get_apic_id,
- .set_apic_id = x2apic_set_apic_id,
.calc_dest_apicid = apic_default_calc_apicid,
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c
index f1766b18dcd0..7fef504ca508 100644
--- a/arch/x86/kernel/apic/x2apic_uv_x.c
+++ b/arch/x86/kernel/apic/x2apic_uv_x.c
@@ -241,54 +241,20 @@ static void __init uv_tsc_check_sync(void)
is_uv(UV3) ? sname.s3.field : \
undef)
-/* [Copied from arch/x86/kernel/cpu/topology.c:detect_extended_topology()] */
-
-#define SMT_LEVEL 0 /* Leaf 0xb SMT level */
-#define INVALID_TYPE 0 /* Leaf 0xb sub-leaf types */
-#define SMT_TYPE 1
-#define CORE_TYPE 2
-#define LEAFB_SUBTYPE(ecx) (((ecx) >> 8) & 0xff)
-#define BITS_SHIFT_NEXT_LEVEL(eax) ((eax) & 0x1f)
-
-static void set_x2apic_bits(void)
-{
- unsigned int eax, ebx, ecx, edx, sub_index;
- unsigned int sid_shift;
-
- cpuid(0, &eax, &ebx, &ecx, &edx);
- if (eax < 0xb) {
- pr_info("UV: CPU does not have CPUID.11\n");
- return;
- }
-
- cpuid_count(0xb, SMT_LEVEL, &eax, &ebx, &ecx, &edx);
- if (ebx == 0 || (LEAFB_SUBTYPE(ecx) != SMT_TYPE)) {
- pr_info("UV: CPUID.11 not implemented\n");
- return;
- }
-
- sid_shift = BITS_SHIFT_NEXT_LEVEL(eax);
- sub_index = 1;
- do {
- cpuid_count(0xb, sub_index, &eax, &ebx, &ecx, &edx);
- if (LEAFB_SUBTYPE(ecx) == CORE_TYPE) {
- sid_shift = BITS_SHIFT_NEXT_LEVEL(eax);
- break;
- }
- sub_index++;
- } while (LEAFB_SUBTYPE(ecx) != INVALID_TYPE);
-
- uv_cpuid.apicid_shift = 0;
- uv_cpuid.apicid_mask = (~(-1 << sid_shift));
- uv_cpuid.socketid_shift = sid_shift;
-}
-
static void __init early_get_apic_socketid_shift(void)
{
+ unsigned int sid_shift = topology_get_domain_shift(TOPO_PKG_DOMAIN);
+
if (is_uv2_hub() || is_uv3_hub())
uvh_apicid.v = uv_early_read_mmr(UVH_APICID);
- set_x2apic_bits();
+ if (sid_shift) {
+ uv_cpuid.apicid_shift = 0;
+ uv_cpuid.apicid_mask = (~(-1 << sid_shift));
+ uv_cpuid.socketid_shift = sid_shift;
+ } else {
+ pr_info("UV: CPU does not have valid CPUID.11\n");
+ }
pr_info("UV: apicid_shift:%d apicid_mask:0x%x\n", uv_cpuid.apicid_shift, uv_cpuid.apicid_mask);
pr_info("UV: socketid_shift:%d pnode_mask:0x%x\n", uv_cpuid.socketid_shift, uv_cpuid.pnode_mask);
@@ -779,21 +745,6 @@ static void uv_send_IPI_all(int vector)
uv_send_IPI_mask(cpu_online_mask, vector);
}
-static u32 set_apic_id(u32 id)
-{
- return id;
-}
-
-static unsigned int uv_read_apic_id(void)
-{
- return x2apic_get_apic_id(apic_read(APIC_ID));
-}
-
-static u32 uv_phys_pkg_id(u32 initial_apicid, int index_msb)
-{
- return uv_read_apic_id() >> index_msb;
-}
-
static int uv_probe(void)
{
return apic == &apic_x2apic_uv_x;
@@ -810,11 +761,9 @@ static struct apic apic_x2apic_uv_x __ro_after_init = {
.disable_esr = 0,
.cpu_present_to_apicid = default_cpu_present_to_apicid,
- .phys_pkg_id = uv_phys_pkg_id,
.max_apic_id = UINT_MAX,
.get_apic_id = x2apic_get_apic_id,
- .set_apic_id = set_apic_id,
.calc_dest_apicid = apic_default_calc_apicid,
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index 76a5ced278c2..b37ab1095707 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -1055,35 +1055,6 @@ static int apm_get_power_status(u_short *status, u_short *bat, u_short *life)
return APM_SUCCESS;
}
-#if 0
-static int apm_get_battery_status(u_short which, u_short *status,
- u_short *bat, u_short *life, u_short *nbat)
-{
- u32 eax;
- u32 ebx;
- u32 ecx;
- u32 edx;
- u32 esi;
-
- if (apm_info.connection_version < 0x0102) {
- /* pretend we only have one battery. */
- if (which != 1)
- return APM_BAD_DEVICE;
- *nbat = 1;
- return apm_get_power_status(status, bat, life);
- }
-
- if (apm_bios_call(APM_FUNC_GET_STATUS, (0x8000 | (which)), 0, &eax,
- &ebx, &ecx, &edx, &esi))
- return (eax >> 8) & 0xff;
- *status = ebx;
- *bat = ecx;
- *life = edx;
- *nbat = esi;
- return APM_SUCCESS;
-}
-#endif
-
/**
* apm_engage_power_management - enable PM on a device
* @device: identity of device
diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c
index 6913b372ccf7..a98020bf31bb 100644
--- a/arch/x86/kernel/asm-offsets.c
+++ b/arch/x86/kernel/asm-offsets.c
@@ -109,7 +109,7 @@ static void __used common(void)
OFFSET(TSS_sp2, tss_struct, x86_tss.sp2);
OFFSET(X86_top_of_stack, pcpu_hot, top_of_stack);
OFFSET(X86_current_task, pcpu_hot, current_task);
-#ifdef CONFIG_CALL_DEPTH_TRACKING
+#ifdef CONFIG_MITIGATION_CALL_DEPTH_TRACKING
OFFSET(X86_call_depth, pcpu_hot, call_depth);
#endif
#if IS_ENABLED(CONFIG_CRYPTO_ARIA_AESNI_AVX_X86_64)
diff --git a/arch/x86/kernel/callthunks.c b/arch/x86/kernel/callthunks.c
index 64ad2ddea121..e92ff0c11db8 100644
--- a/arch/x86/kernel/callthunks.c
+++ b/arch/x86/kernel/callthunks.c
@@ -24,6 +24,8 @@
static int __initdata_or_module debug_callthunks;
+#define MAX_PATCH_LEN (255-1)
+
#define prdbg(fmt, args...) \
do { \
if (debug_callthunks) \
@@ -42,8 +44,8 @@ DEFINE_PER_CPU(u64, __x86_call_count);
DEFINE_PER_CPU(u64, __x86_ret_count);
DEFINE_PER_CPU(u64, __x86_stuffs_count);
DEFINE_PER_CPU(u64, __x86_ctxsw_count);
-EXPORT_SYMBOL_GPL(__x86_ctxsw_count);
-EXPORT_SYMBOL_GPL(__x86_call_count);
+EXPORT_PER_CPU_SYMBOL_GPL(__x86_ctxsw_count);
+EXPORT_PER_CPU_SYMBOL_GPL(__x86_call_count);
#endif
extern s32 __call_sites[], __call_sites_end[];
@@ -179,10 +181,15 @@ static const u8 nops[] = {
static void *patch_dest(void *dest, bool direct)
{
unsigned int tsize = SKL_TMPL_SIZE;
+ u8 insn_buff[MAX_PATCH_LEN];
u8 *pad = dest - tsize;
+ memcpy(insn_buff, skl_call_thunk_template, tsize);
+ apply_relocation(insn_buff, tsize, pad,
+ skl_call_thunk_template, tsize);
+
/* Already patched? */
- if (!bcmp(pad, skl_call_thunk_template, tsize))
+ if (!bcmp(pad, insn_buff, tsize))
return pad;
/* Ensure there are nops */
@@ -192,9 +199,9 @@ static void *patch_dest(void *dest, bool direct)
}
if (direct)
- memcpy(pad, skl_call_thunk_template, tsize);
+ memcpy(pad, insn_buff, tsize);
else
- text_poke_copy_locked(pad, skl_call_thunk_template, tsize, true);
+ text_poke_copy_locked(pad, insn_buff, tsize, true);
return pad;
}
@@ -290,20 +297,27 @@ void *callthunks_translate_call_dest(void *dest)
static bool is_callthunk(void *addr)
{
unsigned int tmpl_size = SKL_TMPL_SIZE;
- void *tmpl = skl_call_thunk_template;
+ u8 insn_buff[MAX_PATCH_LEN];
unsigned long dest;
+ u8 *pad;
dest = roundup((unsigned long)addr, CONFIG_FUNCTION_ALIGNMENT);
if (!thunks_initialized || skip_addr((void *)dest))
return false;
- return !bcmp((void *)(dest - tmpl_size), tmpl, tmpl_size);
+ 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);
+
+ return !bcmp(pad, insn_buff, tmpl_size);
}
-int x86_call_depth_emit_accounting(u8 **pprog, void *func)
+int x86_call_depth_emit_accounting(u8 **pprog, void *func, void *ip)
{
unsigned int tmpl_size = SKL_TMPL_SIZE;
- void *tmpl = skl_call_thunk_template;
+ u8 insn_buff[MAX_PATCH_LEN];
if (!thunks_initialized)
return 0;
@@ -312,7 +326,11 @@ int x86_call_depth_emit_accounting(u8 **pprog, void *func)
if (func && is_callthunk(func))
return 0;
- memcpy(*pprog, tmpl, tmpl_size);
+ memcpy(insn_buff, skl_call_thunk_template, tmpl_size);
+ apply_relocation(insn_buff, tmpl_size, ip,
+ skl_call_thunk_template, tmpl_size);
+
+ memcpy(*pprog, insn_buff, tmpl_size);
*pprog += tmpl_size;
return tmpl_size;
}
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
index 93eabf544031..eb4dbcdf41f1 100644
--- a/arch/x86/kernel/cpu/Makefile
+++ b/arch/x86/kernel/cpu/Makefile
@@ -17,7 +17,8 @@ KMSAN_SANITIZE_common.o := n
# As above, instrumenting secondary CPU boot code causes boot hangs.
KCSAN_SANITIZE_common.o := n
-obj-y := cacheinfo.o scattered.o topology.o
+obj-y := cacheinfo.o scattered.o
+obj-y += topology_common.o topology_ext.o topology_amd.o
obj-y += common.o
obj-y += rdrand.o
obj-y += match.o
@@ -25,14 +26,16 @@ obj-y += bugs.o
obj-y += aperfmperf.o
obj-y += cpuid-deps.o
obj-y += umwait.o
+obj-y += capflags.o powerflags.o
-obj-$(CONFIG_PROC_FS) += proc.o
-obj-y += capflags.o powerflags.o
+obj-$(CONFIG_X86_LOCAL_APIC) += topology.o
-obj-$(CONFIG_IA32_FEAT_CTL) += feat_ctl.o
+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-$(CONFIG_PM) += intel_epb.o
+obj-y += intel.o intel_pconfig.o tsx.o
+obj-$(CONFIG_PM) += intel_epb.o
endif
obj-$(CONFIG_CPU_SUP_AMD) += amd.o
obj-$(CONFIG_CPU_SUP_HYGON) += hygon.o
diff --git a/arch/x86/kernel/cpu/acrn.c b/arch/x86/kernel/cpu/acrn.c
index bfeb18fad63f..2c5b51aad91a 100644
--- a/arch/x86/kernel/cpu/acrn.c
+++ b/arch/x86/kernel/cpu/acrn.c
@@ -26,8 +26,8 @@ static u32 __init acrn_detect(void)
static void __init acrn_init_platform(void)
{
- /* Setup the IDT for ACRN hypervisor callback */
- alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, asm_sysvec_acrn_hv_callback);
+ /* Install system interrupt handler for ACRN hypervisor callback */
+ sysvec_install(HYPERVISOR_CALLBACK_VECTOR, sysvec_acrn_hv_callback);
x86_platform.calibrate_tsc = acrn_get_tsc_khz;
x86_platform.calibrate_cpu = acrn_get_tsc_khz;
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index f3abca334199..9bf17c9c29da 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -20,6 +20,7 @@
#include <asm/delay.h>
#include <asm/debugreg.h>
#include <asm/resctrl.h>
+#include <asm/sev.h>
#ifdef CONFIG_X86_64
# include <asm/mmconfig.h>
@@ -27,13 +28,6 @@
#include "cpu.h"
-/*
- * nodes_per_socket: Stores the number of nodes per socket.
- * Refer to Fam15h Models 00-0fh BKDG - CPUID Fn8000_001E_ECX
- * Node Identifiers[10:8]
- */
-static u32 nodes_per_socket = 1;
-
static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p)
{
u32 gprs[8] = { 0 };
@@ -300,97 +294,6 @@ static int nearby_node(int apicid)
}
#endif
-/*
- * Fix up topo::core_id for pre-F17h systems to be in the
- * [0 .. cores_per_node - 1] range. Not really needed but
- * kept so as not to break existing setups.
- */
-static void legacy_fixup_core_id(struct cpuinfo_x86 *c)
-{
- u32 cus_per_node;
-
- if (c->x86 >= 0x17)
- return;
-
- cus_per_node = c->x86_max_cores / nodes_per_socket;
- c->topo.core_id %= cus_per_node;
-}
-
-/*
- * Fixup core topology information for
- * (1) AMD multi-node processors
- * Assumption: Number of cores in each internal node is the same.
- * (2) AMD processors supporting compute units
- */
-static void amd_get_topology(struct cpuinfo_x86 *c)
-{
- /* get information required for multi-node processors */
- if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
- int err;
- u32 eax, ebx, ecx, edx;
-
- cpuid(0x8000001e, &eax, &ebx, &ecx, &edx);
-
- c->topo.die_id = ecx & 0xff;
-
- if (c->x86 == 0x15)
- c->topo.cu_id = ebx & 0xff;
-
- if (c->x86 >= 0x17) {
- c->topo.core_id = ebx & 0xff;
-
- if (smp_num_siblings > 1)
- c->x86_max_cores /= smp_num_siblings;
- }
-
- /*
- * In case leaf B is available, use it to derive
- * topology information.
- */
- err = detect_extended_topology(c);
- if (!err)
- c->x86_coreid_bits = get_count_order(c->x86_max_cores);
-
- cacheinfo_amd_init_llc_id(c);
-
- } else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) {
- u64 value;
-
- rdmsrl(MSR_FAM10H_NODE_ID, value);
- c->topo.die_id = value & 7;
- c->topo.llc_id = c->topo.die_id;
- } else
- return;
-
- if (nodes_per_socket > 1) {
- set_cpu_cap(c, X86_FEATURE_AMD_DCM);
- legacy_fixup_core_id(c);
- }
-}
-
-/*
- * On a AMD dual core setup the lower bits of the APIC id distinguish the cores.
- * Assumes number of cores is a power of two.
- */
-static void amd_detect_cmp(struct cpuinfo_x86 *c)
-{
- unsigned bits;
-
- bits = c->x86_coreid_bits;
- /* Low order bits define the core id (index of core in socket) */
- c->topo.core_id = c->topo.initial_apicid & ((1 << bits)-1);
- /* Convert the initial APIC ID into the socket ID */
- c->topo.pkg_id = c->topo.initial_apicid >> bits;
- /* use socket ID also for last level cache */
- c->topo.llc_id = c->topo.die_id = c->topo.pkg_id;
-}
-
-u32 amd_get_nodes_per_socket(void)
-{
- return nodes_per_socket;
-}
-EXPORT_SYMBOL_GPL(amd_get_nodes_per_socket);
-
static void srat_detect_node(struct cpuinfo_x86 *c)
{
#ifdef CONFIG_NUMA
@@ -442,29 +345,25 @@ static void srat_detect_node(struct cpuinfo_x86 *c)
#endif
}
-static void early_init_amd_mc(struct cpuinfo_x86 *c)
+static void bsp_determine_snp(struct cpuinfo_x86 *c)
{
-#ifdef CONFIG_SMP
- unsigned bits, ecx;
-
- /* Multi core CPU? */
- if (c->extended_cpuid_level < 0x80000008)
- return;
-
- ecx = cpuid_ecx(0x80000008);
+#ifdef CONFIG_ARCH_HAS_CC_PLATFORM
+ cc_vendor = CC_VENDOR_AMD;
- c->x86_max_cores = (ecx & 0xff) + 1;
-
- /* CPU telling us the core id bits shift? */
- bits = (ecx >> 12) & 0xF;
-
- /* Otherwise recompute */
- if (bits == 0) {
- while ((1 << bits) < c->x86_max_cores)
- bits++;
+ if (cpu_has(c, X86_FEATURE_SEV_SNP)) {
+ /*
+ * RMP table entry format is not architectural and is defined by the
+ * per-processor PPR. Restrict SNP support on the known CPU models
+ * for which the RMP table entry format is currently defined for.
+ */
+ if (!cpu_has(c, X86_FEATURE_HYPERVISOR) &&
+ c->x86 >= 0x19 && snp_probe_rmptable_info()) {
+ cc_platform_set(CC_ATTR_HOST_SEV_SNP);
+ } else {
+ setup_clear_cpu_cap(X86_FEATURE_SEV_SNP);
+ cc_platform_clear(CC_ATTR_HOST_SEV_SNP);
+ }
}
-
- c->x86_coreid_bits = bits;
#endif
}
@@ -500,18 +399,6 @@ static void bsp_init_amd(struct cpuinfo_x86 *c)
if (cpu_has(c, X86_FEATURE_MWAITX))
use_mwaitx_delay();
- if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
- u32 ecx;
-
- ecx = cpuid_ecx(0x8000001e);
- __max_die_per_package = nodes_per_socket = ((ecx >> 8) & 7) + 1;
- } else if (boot_cpu_has(X86_FEATURE_NODEID_MSR)) {
- u64 value;
-
- rdmsrl(MSR_FAM10H_NODE_ID, value);
- __max_die_per_package = nodes_per_socket = ((value >> 3) & 7) + 1;
- }
-
if (!boot_cpu_has(X86_FEATURE_AMD_SSBD) &&
!boot_cpu_has(X86_FEATURE_VIRT_SSBD) &&
c->x86 >= 0x15 && c->x86 <= 0x17) {
@@ -587,6 +474,7 @@ static void bsp_init_amd(struct cpuinfo_x86 *c)
break;
}
+ bsp_determine_snp(c);
return;
warn:
@@ -605,8 +493,8 @@ static void early_detect_mem_encrypt(struct cpuinfo_x86 *c)
* SME feature (set in scattered.c).
* If the kernel has not enabled SME via any means then
* don't advertise the SME feature.
- * For SEV: If BIOS has not enabled SEV then don't advertise the
- * SEV and SEV_ES feature (set in scattered.c).
+ * For SEV: If BIOS has not enabled SEV then don't advertise SEV and
+ * any additional functionality based on it.
*
* In all cases, since support for SME and SEV requires long mode,
* don't advertise the feature under CONFIG_X86_32.
@@ -641,6 +529,7 @@ clear_all:
clear_sev:
setup_clear_cpu_cap(X86_FEATURE_SEV);
setup_clear_cpu_cap(X86_FEATURE_SEV_ES);
+ setup_clear_cpu_cap(X86_FEATURE_SEV_SNP);
}
}
@@ -649,8 +538,6 @@ static void early_init_amd(struct cpuinfo_x86 *c)
u64 value;
u32 dummy;
- early_init_amd_mc(c);
-
if (c->x86 >= 0xf)
set_cpu_cap(c, X86_FEATURE_K8);
@@ -730,9 +617,6 @@ static void early_init_amd(struct cpuinfo_x86 *c)
}
}
- if (cpu_has(c, X86_FEATURE_TOPOEXT))
- smp_num_siblings = ((cpuid_ebx(0x8000001e) >> 8) & 0xff) + 1;
-
if (!cpu_has(c, X86_FEATURE_HYPERVISOR) && !cpu_has(c, X86_FEATURE_IBPB_BRTYPE)) {
if (c->x86 == 0x17 && boot_cpu_has(X86_FEATURE_AMD_IBPB))
setup_force_cpu_cap(X86_FEATURE_IBPB_BRTYPE);
@@ -941,7 +825,7 @@ static void fix_erratum_1386(struct cpuinfo_x86 *c)
void init_spectral_chicken(struct cpuinfo_x86 *c)
{
-#ifdef CONFIG_CPU_UNRET_ENTRY
+#ifdef CONFIG_MITIGATION_UNRET_ENTRY
u64 value;
/*
@@ -969,7 +853,6 @@ static void init_amd_zen_common(void)
static void init_amd_zen1(struct cpuinfo_x86 *c)
{
- init_amd_zen_common();
fix_erratum_1386(c);
/* Fix up CPUID bits, but only if not virtualised. */
@@ -989,11 +872,11 @@ static bool cpu_has_zenbleed_microcode(void)
u32 good_rev = 0;
switch (boot_cpu_data.x86_model) {
- case 0x30 ... 0x3f: good_rev = 0x0830107a; break;
- case 0x60 ... 0x67: good_rev = 0x0860010b; break;
- case 0x68 ... 0x6f: good_rev = 0x08608105; break;
- case 0x70 ... 0x7f: good_rev = 0x08701032; break;
- case 0xa0 ... 0xaf: good_rev = 0x08a00008; break;
+ case 0x30 ... 0x3f: good_rev = 0x0830107b; break;
+ case 0x60 ... 0x67: good_rev = 0x0860010c; break;
+ case 0x68 ... 0x6f: good_rev = 0x08608107; break;
+ case 0x70 ... 0x7f: good_rev = 0x08701033; break;
+ case 0xa0 ... 0xaf: good_rev = 0x08a00009; break;
default:
return false;
@@ -1023,7 +906,6 @@ static void zen2_zenbleed_check(struct cpuinfo_x86 *c)
static void init_amd_zen2(struct cpuinfo_x86 *c)
{
- init_amd_zen_common();
init_spectral_chicken(c);
fix_erratum_1386(c);
zen2_zenbleed_check(c);
@@ -1031,8 +913,6 @@ static void init_amd_zen2(struct cpuinfo_x86 *c)
static void init_amd_zen3(struct cpuinfo_x86 *c)
{
- init_amd_zen_common();
-
if (!cpu_has(c, X86_FEATURE_HYPERVISOR)) {
/*
* Zen3 (Fam19 model < 0x10) parts are not susceptible to
@@ -1046,15 +926,12 @@ static void init_amd_zen3(struct cpuinfo_x86 *c)
static void init_amd_zen4(struct cpuinfo_x86 *c)
{
- init_amd_zen_common();
-
if (!cpu_has(c, X86_FEATURE_HYPERVISOR))
msr_set_bit(MSR_ZEN4_BP_CFG, MSR_ZEN4_BP_CFG_SHARED_BTB_FIX_BIT);
}
static void init_amd_zen5(struct cpuinfo_x86 *c)
{
- init_amd_zen_common();
}
static void init_amd(struct cpuinfo_x86 *c)
@@ -1076,9 +953,6 @@ static void init_amd(struct cpuinfo_x86 *c)
if (cpu_has(c, X86_FEATURE_FSRM))
set_cpu_cap(c, X86_FEATURE_FSRS);
- /* get apicid instead of initial apic id from cpuid */
- c->topo.apicid = read_apic_id();
-
/* K6s reports MCEs but don't actually have all the MSRs */
if (c->x86 < 6)
clear_cpu_cap(c, X86_FEATURE_MCE);
@@ -1094,6 +968,13 @@ static void init_amd(struct cpuinfo_x86 *c)
case 0x16: init_amd_jg(c); break;
}
+ /*
+ * Save up on some future enablement work and do common Zen
+ * settings.
+ */
+ if (c->x86 >= 0x17)
+ init_amd_zen_common();
+
if (boot_cpu_has(X86_FEATURE_ZEN1))
init_amd_zen1(c);
else if (boot_cpu_has(X86_FEATURE_ZEN2))
@@ -1114,8 +995,6 @@ static void init_amd(struct cpuinfo_x86 *c)
cpu_detect_cache_sizes(c);
- amd_detect_cmp(c);
- amd_get_topology(c);
srat_detect_node(c);
init_amd_cacheinfo(c);
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 48d049cd74e7..295463707e68 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -56,7 +56,7 @@ EXPORT_SYMBOL_GPL(x86_spec_ctrl_base);
/* The current value of the SPEC_CTRL MSR with task-specific bits set */
DEFINE_PER_CPU(u64, x86_spec_ctrl_current);
-EXPORT_SYMBOL_GPL(x86_spec_ctrl_current);
+EXPORT_PER_CPU_SYMBOL_GPL(x86_spec_ctrl_current);
u64 x86_pred_cmd __ro_after_init = PRED_CMD_IBPB;
EXPORT_SYMBOL_GPL(x86_pred_cmd);
@@ -422,6 +422,13 @@ static void __init mmio_select_mitigation(void)
if (boot_cpu_has_bug(X86_BUG_MDS) || (boot_cpu_has_bug(X86_BUG_TAA) &&
boot_cpu_has(X86_FEATURE_RTM)))
setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF);
+
+ /*
+ * X86_FEATURE_CLEAR_CPU_BUF could be enabled by other VERW based
+ * mitigations, disable KVM-only mitigation in that case.
+ */
+ if (boot_cpu_has(X86_FEATURE_CLEAR_CPU_BUF))
+ static_branch_disable(&mmio_stale_data_clear);
else
static_branch_enable(&mmio_stale_data_clear);
@@ -474,6 +481,57 @@ static int __init mmio_stale_data_parse_cmdline(char *str)
early_param("mmio_stale_data", mmio_stale_data_parse_cmdline);
#undef pr_fmt
+#define pr_fmt(fmt) "Register File Data Sampling: " fmt
+
+enum rfds_mitigations {
+ RFDS_MITIGATION_OFF,
+ RFDS_MITIGATION_VERW,
+ RFDS_MITIGATION_UCODE_NEEDED,
+};
+
+/* Default mitigation for Register File Data Sampling */
+static enum rfds_mitigations rfds_mitigation __ro_after_init =
+ IS_ENABLED(CONFIG_MITIGATION_RFDS) ? RFDS_MITIGATION_VERW : RFDS_MITIGATION_OFF;
+
+static const char * const rfds_strings[] = {
+ [RFDS_MITIGATION_OFF] = "Vulnerable",
+ [RFDS_MITIGATION_VERW] = "Mitigation: Clear Register File",
+ [RFDS_MITIGATION_UCODE_NEEDED] = "Vulnerable: No microcode",
+};
+
+static void __init rfds_select_mitigation(void)
+{
+ if (!boot_cpu_has_bug(X86_BUG_RFDS) || cpu_mitigations_off()) {
+ rfds_mitigation = RFDS_MITIGATION_OFF;
+ return;
+ }
+ if (rfds_mitigation == RFDS_MITIGATION_OFF)
+ return;
+
+ if (x86_read_arch_cap_msr() & ARCH_CAP_RFDS_CLEAR)
+ setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF);
+ else
+ rfds_mitigation = RFDS_MITIGATION_UCODE_NEEDED;
+}
+
+static __init int rfds_parse_cmdline(char *str)
+{
+ if (!str)
+ return -EINVAL;
+
+ if (!boot_cpu_has_bug(X86_BUG_RFDS))
+ return 0;
+
+ if (!strcmp(str, "off"))
+ rfds_mitigation = RFDS_MITIGATION_OFF;
+ else if (!strcmp(str, "on"))
+ rfds_mitigation = RFDS_MITIGATION_VERW;
+
+ return 0;
+}
+early_param("reg_file_data_sampling", rfds_parse_cmdline);
+
+#undef pr_fmt
#define pr_fmt(fmt) "" fmt
static void __init md_clear_update_mitigation(void)
@@ -498,11 +556,19 @@ static void __init md_clear_update_mitigation(void)
taa_mitigation = TAA_MITIGATION_VERW;
taa_select_mitigation();
}
- if (mmio_mitigation == MMIO_MITIGATION_OFF &&
- boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA)) {
+ /*
+ * MMIO_MITIGATION_OFF is not checked here so that mmio_stale_data_clear
+ * gets updated correctly as per X86_FEATURE_CLEAR_CPU_BUF state.
+ */
+ if (boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA)) {
mmio_mitigation = MMIO_MITIGATION_VERW;
mmio_select_mitigation();
}
+ if (rfds_mitigation == RFDS_MITIGATION_OFF &&
+ boot_cpu_has_bug(X86_BUG_RFDS)) {
+ rfds_mitigation = RFDS_MITIGATION_VERW;
+ rfds_select_mitigation();
+ }
out:
if (boot_cpu_has_bug(X86_BUG_MDS))
pr_info("MDS: %s\n", mds_strings[mds_mitigation]);
@@ -512,6 +578,8 @@ out:
pr_info("MMIO Stale Data: %s\n", mmio_strings[mmio_mitigation]);
else if (boot_cpu_has_bug(X86_BUG_MMIO_UNKNOWN))
pr_info("MMIO Stale Data: Unknown: No mitigations\n");
+ if (boot_cpu_has_bug(X86_BUG_RFDS))
+ pr_info("Register File Data Sampling: %s\n", rfds_strings[rfds_mitigation]);
}
static void __init md_clear_select_mitigation(void)
@@ -519,11 +587,12 @@ static void __init md_clear_select_mitigation(void)
mds_select_mitigation();
taa_select_mitigation();
mmio_select_mitigation();
+ rfds_select_mitigation();
/*
- * As MDS, TAA and MMIO Stale Data mitigations are inter-related, update
- * and print their mitigation after MDS, TAA and MMIO Stale Data
- * mitigation selection is done.
+ * As these mitigations are inter-related and rely on VERW instruction
+ * to clear the microarchitural buffers, update and print their status
+ * after mitigation selection is done for each of these vulnerabilities.
*/
md_clear_update_mitigation();
}
@@ -668,7 +737,7 @@ enum gds_mitigations {
GDS_MITIGATION_HYPERVISOR,
};
-#if IS_ENABLED(CONFIG_GDS_FORCE_MITIGATION)
+#if IS_ENABLED(CONFIG_MITIGATION_GDS_FORCE)
static enum gds_mitigations gds_mitigation __ro_after_init = GDS_MITIGATION_FORCE;
#else
static enum gds_mitigations gds_mitigation __ro_after_init = GDS_MITIGATION_FULL;
@@ -979,10 +1048,10 @@ static void __init retbleed_select_mitigation(void)
return;
case RETBLEED_CMD_UNRET:
- if (IS_ENABLED(CONFIG_CPU_UNRET_ENTRY)) {
+ if (IS_ENABLED(CONFIG_MITIGATION_UNRET_ENTRY)) {
retbleed_mitigation = RETBLEED_MITIGATION_UNRET;
} else {
- pr_err("WARNING: kernel not compiled with CPU_UNRET_ENTRY.\n");
+ pr_err("WARNING: kernel not compiled with MITIGATION_UNRET_ENTRY.\n");
goto do_cmd_auto;
}
break;
@@ -991,24 +1060,24 @@ static void __init retbleed_select_mitigation(void)
if (!boot_cpu_has(X86_FEATURE_IBPB)) {
pr_err("WARNING: CPU does not support IBPB.\n");
goto do_cmd_auto;
- } else if (IS_ENABLED(CONFIG_CPU_IBPB_ENTRY)) {
+ } else if (IS_ENABLED(CONFIG_MITIGATION_IBPB_ENTRY)) {
retbleed_mitigation = RETBLEED_MITIGATION_IBPB;
} else {
- pr_err("WARNING: kernel not compiled with CPU_IBPB_ENTRY.\n");
+ pr_err("WARNING: kernel not compiled with MITIGATION_IBPB_ENTRY.\n");
goto do_cmd_auto;
}
break;
case RETBLEED_CMD_STUFF:
- if (IS_ENABLED(CONFIG_CALL_DEPTH_TRACKING) &&
+ if (IS_ENABLED(CONFIG_MITIGATION_CALL_DEPTH_TRACKING) &&
spectre_v2_enabled == SPECTRE_V2_RETPOLINE) {
retbleed_mitigation = RETBLEED_MITIGATION_STUFF;
} else {
- if (IS_ENABLED(CONFIG_CALL_DEPTH_TRACKING))
+ if (IS_ENABLED(CONFIG_MITIGATION_CALL_DEPTH_TRACKING))
pr_err("WARNING: retbleed=stuff depends on spectre_v2=retpoline\n");
else
- pr_err("WARNING: kernel not compiled with CALL_DEPTH_TRACKING.\n");
+ pr_err("WARNING: kernel not compiled with MITIGATION_CALL_DEPTH_TRACKING.\n");
goto do_cmd_auto;
}
@@ -1018,9 +1087,10 @@ do_cmd_auto:
case RETBLEED_CMD_AUTO:
if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) {
- if (IS_ENABLED(CONFIG_CPU_UNRET_ENTRY))
+ if (IS_ENABLED(CONFIG_MITIGATION_UNRET_ENTRY))
retbleed_mitigation = RETBLEED_MITIGATION_UNRET;
- else if (IS_ENABLED(CONFIG_CPU_IBPB_ENTRY) && boot_cpu_has(X86_FEATURE_IBPB))
+ else if (IS_ENABLED(CONFIG_MITIGATION_IBPB_ENTRY) &&
+ boot_cpu_has(X86_FEATURE_IBPB))
retbleed_mitigation = RETBLEED_MITIGATION_IBPB;
}
@@ -1099,7 +1169,7 @@ static enum spectre_v2_user_mitigation spectre_v2_user_stibp __ro_after_init =
static enum spectre_v2_user_mitigation spectre_v2_user_ibpb __ro_after_init =
SPECTRE_V2_USER_NONE;
-#ifdef CONFIG_RETPOLINE
+#ifdef CONFIG_MITIGATION_RETPOLINE
static bool spectre_v2_bad_module;
bool retpoline_module_ok(bool has_retpoline)
@@ -1412,7 +1482,7 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void)
cmd == SPECTRE_V2_CMD_RETPOLINE_GENERIC ||
cmd == SPECTRE_V2_CMD_EIBRS_LFENCE ||
cmd == SPECTRE_V2_CMD_EIBRS_RETPOLINE) &&
- !IS_ENABLED(CONFIG_RETPOLINE)) {
+ !IS_ENABLED(CONFIG_MITIGATION_RETPOLINE)) {
pr_err("%s selected but not compiled in. Switching to AUTO select\n",
mitigation_options[i].option);
return SPECTRE_V2_CMD_AUTO;
@@ -1435,7 +1505,7 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void)
return SPECTRE_V2_CMD_AUTO;
}
- if (cmd == SPECTRE_V2_CMD_IBRS && !IS_ENABLED(CONFIG_CPU_IBRS_ENTRY)) {
+ if (cmd == SPECTRE_V2_CMD_IBRS && !IS_ENABLED(CONFIG_MITIGATION_IBRS_ENTRY)) {
pr_err("%s selected but not compiled in. Switching to AUTO select\n",
mitigation_options[i].option);
return SPECTRE_V2_CMD_AUTO;
@@ -1466,7 +1536,7 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void)
static enum spectre_v2_mitigation __init spectre_v2_select_retpoline(void)
{
- if (!IS_ENABLED(CONFIG_RETPOLINE)) {
+ if (!IS_ENABLED(CONFIG_MITIGATION_RETPOLINE)) {
pr_err("Kernel not compiled with retpoline; no mitigation available!");
return SPECTRE_V2_NONE;
}
@@ -1537,6 +1607,79 @@ static void __init spectre_v2_determine_rsb_fill_type_at_vmexit(enum spectre_v2_
dump_stack();
}
+/*
+ * Set BHI_DIS_S to prevent indirect branches in kernel to be influenced by
+ * branch history in userspace. Not needed if BHI_NO is set.
+ */
+static bool __init spec_ctrl_bhi_dis(void)
+{
+ if (!boot_cpu_has(X86_FEATURE_BHI_CTRL))
+ return false;
+
+ x86_spec_ctrl_base |= SPEC_CTRL_BHI_DIS_S;
+ update_spec_ctrl(x86_spec_ctrl_base);
+ setup_force_cpu_cap(X86_FEATURE_CLEAR_BHB_HW);
+
+ return true;
+}
+
+enum bhi_mitigations {
+ BHI_MITIGATION_OFF,
+ BHI_MITIGATION_ON,
+ BHI_MITIGATION_AUTO,
+};
+
+static enum bhi_mitigations bhi_mitigation __ro_after_init =
+ IS_ENABLED(CONFIG_SPECTRE_BHI_ON) ? BHI_MITIGATION_ON :
+ IS_ENABLED(CONFIG_SPECTRE_BHI_OFF) ? BHI_MITIGATION_OFF :
+ BHI_MITIGATION_AUTO;
+
+static int __init spectre_bhi_parse_cmdline(char *str)
+{
+ if (!str)
+ return -EINVAL;
+
+ if (!strcmp(str, "off"))
+ bhi_mitigation = BHI_MITIGATION_OFF;
+ else if (!strcmp(str, "on"))
+ bhi_mitigation = BHI_MITIGATION_ON;
+ else if (!strcmp(str, "auto"))
+ bhi_mitigation = BHI_MITIGATION_AUTO;
+ else
+ pr_err("Ignoring unknown spectre_bhi option (%s)", str);
+
+ return 0;
+}
+early_param("spectre_bhi", spectre_bhi_parse_cmdline);
+
+static void __init bhi_select_mitigation(void)
+{
+ if (bhi_mitigation == BHI_MITIGATION_OFF)
+ return;
+
+ /* Retpoline mitigates against BHI unless the CPU has RRSBA behavior */
+ if (cpu_feature_enabled(X86_FEATURE_RETPOLINE) &&
+ !(x86_read_arch_cap_msr() & ARCH_CAP_RRSBA))
+ return;
+
+ 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_AUTO)
+ return;
+
+ /* Mitigate syscalls when the mitigation is forced =on */
+ setup_force_cpu_cap(X86_FEATURE_CLEAR_BHB_LOOP);
+ pr_info("Spectre BHI mitigation: SW BHB clearing on syscall\n");
+}
+
static void __init spectre_v2_select_mitigation(void)
{
enum spectre_v2_mitigation_cmd cmd = spectre_v2_parse_cmdline();
@@ -1561,7 +1704,7 @@ static void __init spectre_v2_select_mitigation(void)
break;
}
- if (IS_ENABLED(CONFIG_CPU_IBRS_ENTRY) &&
+ if (IS_ENABLED(CONFIG_MITIGATION_IBRS_ENTRY) &&
boot_cpu_has_bug(X86_BUG_RETBLEED) &&
retbleed_cmd != RETBLEED_CMD_OFF &&
retbleed_cmd != RETBLEED_CMD_STUFF &&
@@ -1648,6 +1791,9 @@ static void __init spectre_v2_select_mitigation(void)
mode == SPECTRE_V2_RETPOLINE)
spec_ctrl_disable_kernel_rrsba();
+ if (boot_cpu_has(X86_BUG_BHI))
+ bhi_select_mitigation();
+
spectre_v2_enabled = mode;
pr_info("%s\n", spectre_v2_strings[mode]);
@@ -2454,7 +2600,7 @@ static void __init srso_select_mitigation(void)
break;
case SRSO_CMD_SAFE_RET:
- if (IS_ENABLED(CONFIG_CPU_SRSO)) {
+ if (IS_ENABLED(CONFIG_MITIGATION_SRSO)) {
/*
* Enable the return thunk for generated code
* like ftrace, static_call, etc.
@@ -2474,29 +2620,29 @@ static void __init srso_select_mitigation(void)
else
srso_mitigation = SRSO_MITIGATION_SAFE_RET_UCODE_NEEDED;
} else {
- pr_err("WARNING: kernel not compiled with CPU_SRSO.\n");
+ pr_err("WARNING: kernel not compiled with MITIGATION_SRSO.\n");
}
break;
case SRSO_CMD_IBPB:
- if (IS_ENABLED(CONFIG_CPU_IBPB_ENTRY)) {
+ if (IS_ENABLED(CONFIG_MITIGATION_IBPB_ENTRY)) {
if (has_microcode) {
setup_force_cpu_cap(X86_FEATURE_ENTRY_IBPB);
srso_mitigation = SRSO_MITIGATION_IBPB;
}
} else {
- pr_err("WARNING: kernel not compiled with CPU_IBPB_ENTRY.\n");
+ pr_err("WARNING: kernel not compiled with MITIGATION_IBPB_ENTRY.\n");
}
break;
case SRSO_CMD_IBPB_ON_VMEXIT:
- if (IS_ENABLED(CONFIG_CPU_SRSO)) {
+ if (IS_ENABLED(CONFIG_MITIGATION_SRSO)) {
if (!boot_cpu_has(X86_FEATURE_ENTRY_IBPB) && has_microcode) {
setup_force_cpu_cap(X86_FEATURE_IBPB_ON_VMEXIT);
srso_mitigation = SRSO_MITIGATION_IBPB_ON_VMEXIT;
}
} else {
- pr_err("WARNING: kernel not compiled with CPU_SRSO.\n");
+ pr_err("WARNING: kernel not compiled with MITIGATION_SRSO.\n");
}
break;
}
@@ -2612,6 +2758,11 @@ static ssize_t mmio_stale_data_show_state(char *buf)
sched_smt_active() ? "vulnerable" : "disabled");
}
+static ssize_t rfds_show_state(char *buf)
+{
+ return sysfs_emit(buf, "%s\n", rfds_strings[rfds_mitigation]);
+}
+
static char *stibp_state(void)
{
if (spectre_v2_in_eibrs_mode(spectre_v2_enabled) &&
@@ -2620,15 +2771,15 @@ static char *stibp_state(void)
switch (spectre_v2_user_stibp) {
case SPECTRE_V2_USER_NONE:
- return ", STIBP: disabled";
+ return "; STIBP: disabled";
case SPECTRE_V2_USER_STRICT:
- return ", STIBP: forced";
+ return "; STIBP: forced";
case SPECTRE_V2_USER_STRICT_PREFERRED:
- return ", STIBP: always-on";
+ return "; STIBP: always-on";
case SPECTRE_V2_USER_PRCTL:
case SPECTRE_V2_USER_SECCOMP:
if (static_key_enabled(&switch_to_cond_stibp))
- return ", STIBP: conditional";
+ return "; STIBP: conditional";
}
return "";
}
@@ -2637,10 +2788,10 @@ static char *ibpb_state(void)
{
if (boot_cpu_has(X86_FEATURE_IBPB)) {
if (static_key_enabled(&switch_mm_always_ibpb))
- return ", IBPB: always-on";
+ return "; IBPB: always-on";
if (static_key_enabled(&switch_mm_cond_ibpb))
- return ", IBPB: conditional";
- return ", IBPB: disabled";
+ return "; IBPB: conditional";
+ return "; IBPB: disabled";
}
return "";
}
@@ -2650,14 +2801,31 @@ static char *pbrsb_eibrs_state(void)
if (boot_cpu_has_bug(X86_BUG_EIBRS_PBRSB)) {
if (boot_cpu_has(X86_FEATURE_RSB_VMEXIT_LITE) ||
boot_cpu_has(X86_FEATURE_RSB_VMEXIT))
- return ", PBRSB-eIBRS: SW sequence";
+ return "; PBRSB-eIBRS: SW sequence";
else
- return ", PBRSB-eIBRS: Vulnerable";
+ return "; PBRSB-eIBRS: Vulnerable";
} else {
- return ", PBRSB-eIBRS: Not affected";
+ return "; PBRSB-eIBRS: Not affected";
}
}
+static const char * const spectre_bhi_state(void)
+{
+ if (!boot_cpu_has_bug(X86_BUG_BHI))
+ return "; BHI: Not affected";
+ else if (boot_cpu_has(X86_FEATURE_CLEAR_BHB_HW))
+ return "; BHI: BHI_DIS_S";
+ else if (boot_cpu_has(X86_FEATURE_CLEAR_BHB_LOOP))
+ return "; BHI: SW loop, KVM: SW loop";
+ else if (boot_cpu_has(X86_FEATURE_RETPOLINE) &&
+ !(x86_read_arch_cap_msr() & ARCH_CAP_RRSBA))
+ return "; BHI: Retpoline";
+ else if (boot_cpu_has(X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT))
+ return "; BHI: Syscall hardening, KVM: SW loop";
+
+ return "; BHI: Vulnerable (Syscall hardening enabled)";
+}
+
static ssize_t spectre_v2_show_state(char *buf)
{
if (spectre_v2_enabled == SPECTRE_V2_LFENCE)
@@ -2670,13 +2838,15 @@ static ssize_t spectre_v2_show_state(char *buf)
spectre_v2_enabled == SPECTRE_V2_EIBRS_LFENCE)
return sysfs_emit(buf, "Vulnerable: eIBRS+LFENCE with unprivileged eBPF and SMT\n");
- return sysfs_emit(buf, "%s%s%s%s%s%s%s\n",
+ return sysfs_emit(buf, "%s%s%s%s%s%s%s%s\n",
spectre_v2_strings[spectre_v2_enabled],
ibpb_state(),
- boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "",
+ boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? "; IBRS_FW" : "",
stibp_state(),
- boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? ", RSB filling" : "",
+ boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? "; RSB filling" : "",
pbrsb_eibrs_state(),
+ spectre_bhi_state(),
+ /* this should always be at the end */
spectre_v2_module_string());
}
@@ -2771,6 +2941,9 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr
case X86_BUG_GDS:
return gds_show_state(buf);
+ case X86_BUG_RFDS:
+ return rfds_show_state(buf);
+
default:
break;
}
@@ -2845,4 +3018,14 @@ ssize_t cpu_show_gds(struct device *dev, struct device_attribute *attr, char *bu
{
return cpu_show_common(dev, attr, buf, X86_BUG_GDS);
}
+
+ssize_t cpu_show_reg_file_data_sampling(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ return cpu_show_common(dev, attr, buf, X86_BUG_RFDS);
+}
#endif
+
+void __warn_thunk(void)
+{
+ WARN_ONCE(1, "Unpatched return thunk in use. This should not happen!\n");
+}
diff --git a/arch/x86/kernel/cpu/cacheinfo.c b/arch/x86/kernel/cpu/cacheinfo.c
index c131c412db89..392d09c936d6 100644
--- a/arch/x86/kernel/cpu/cacheinfo.c
+++ b/arch/x86/kernel/cpu/cacheinfo.c
@@ -301,7 +301,7 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
eax->split.type = types[leaf];
eax->split.level = levels[leaf];
eax->split.num_threads_sharing = 0;
- eax->split.num_cores_on_die = __this_cpu_read(cpu_info.x86_max_cores) - 1;
+ eax->split.num_cores_on_die = topology_num_cores_per_package();
if (assoc == 0xffff)
@@ -595,7 +595,7 @@ static void amd_init_l3_cache(struct _cpuid4_info_regs *this_leaf, int index)
if (index < 3)
return;
- node = topology_die_id(smp_processor_id());
+ node = topology_amd_node_id(smp_processor_id());
this_leaf->nb = node_to_amd_nb(node);
if (this_leaf->nb && !this_leaf->nb->l3_cache.indices)
amd_calc_l3_indices(this_leaf->nb);
@@ -661,7 +661,7 @@ static int find_num_cache_leaves(struct cpuinfo_x86 *c)
return i;
}
-void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c)
+void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, u16 die_id)
{
/*
* We may have multiple LLCs if L3 caches exist, so check if we
@@ -672,7 +672,7 @@ void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c)
if (c->x86 < 0x17) {
/* LLC is at the node level. */
- c->topo.llc_id = c->topo.die_id;
+ c->topo.llc_id = die_id;
} else if (c->x86 == 0x17 && c->x86_model <= 0x1F) {
/*
* LLC is at the core complex level.
@@ -1118,15 +1118,16 @@ static void cache_cpu_init(void)
unsigned long flags;
local_irq_save(flags);
- cache_disable();
- if (memory_caching_control & CACHE_MTRR)
+ if (memory_caching_control & CACHE_MTRR) {
+ cache_disable();
mtrr_generic_set_state();
+ cache_enable();
+ }
if (memory_caching_control & CACHE_PAT)
pat_cpu_init();
- cache_enable();
local_irq_restore(flags);
}
diff --git a/arch/x86/kernel/cpu/centaur.c b/arch/x86/kernel/cpu/centaur.c
index 345f7d905db6..a3b55db35c96 100644
--- a/arch/x86/kernel/cpu/centaur.c
+++ b/arch/x86/kernel/cpu/centaur.c
@@ -128,10 +128,6 @@ static void init_centaur(struct cpuinfo_x86 *c)
#endif
early_init_centaur(c);
init_intel_cacheinfo(c);
- detect_num_cpu_cores(c);
-#ifdef CONFIG_X86_32
- detect_ht(c);
-#endif
if (c->cpuid_level > 9) {
unsigned int eax = cpuid_eax(10);
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index fbc4e60d027c..754d91857d63 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -61,6 +61,7 @@
#include <asm/microcode.h>
#include <asm/intel-family.h>
#include <asm/cpu_device_id.h>
+#include <asm/fred.h>
#include <asm/uv/uv.h>
#include <asm/ia32.h>
#include <asm/set_memory.h>
@@ -70,11 +71,26 @@
#include "cpu.h"
+DEFINE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info);
+EXPORT_PER_CPU_SYMBOL(cpu_info);
+
u32 elf_hwcap2 __read_mostly;
/* Number of siblings per CPU package */
-int smp_num_siblings = 1;
-EXPORT_SYMBOL(smp_num_siblings);
+unsigned int __max_threads_per_core __ro_after_init = 1;
+EXPORT_SYMBOL(__max_threads_per_core);
+
+unsigned int __max_dies_per_package __ro_after_init = 1;
+EXPORT_SYMBOL(__max_dies_per_package);
+
+unsigned int __max_logical_packages __ro_after_init = 1;
+EXPORT_SYMBOL(__max_logical_packages);
+
+unsigned int __num_cores_per_package __ro_after_init = 1;
+EXPORT_SYMBOL(__num_cores_per_package);
+
+unsigned int __num_threads_per_package __ro_after_init = 1;
+EXPORT_SYMBOL(__num_threads_per_package);
static struct ppin_info {
int feature;
@@ -382,9 +398,8 @@ out:
}
/* These bits should not change their value after CPU init is finished. */
-static const unsigned long cr4_pinned_mask =
- X86_CR4_SMEP | X86_CR4_SMAP | X86_CR4_UMIP |
- X86_CR4_FSGSBASE | X86_CR4_CET;
+static const unsigned long cr4_pinned_mask = X86_CR4_SMEP | X86_CR4_SMAP | X86_CR4_UMIP |
+ X86_CR4_FSGSBASE | X86_CR4_CET | X86_CR4_FRED;
static DEFINE_STATIC_KEY_FALSE_RO(cr_pinning);
static unsigned long cr4_pinned_bits __ro_after_init;
@@ -790,19 +805,6 @@ static void get_model_name(struct cpuinfo_x86 *c)
*(s + 1) = '\0';
}
-void detect_num_cpu_cores(struct cpuinfo_x86 *c)
-{
- unsigned int eax, ebx, ecx, edx;
-
- c->x86_max_cores = 1;
- if (!IS_ENABLED(CONFIG_SMP) || c->cpuid_level < 4)
- return;
-
- cpuid_count(4, 0, &eax, &ebx, &ecx, &edx);
- if (eax & 0x1f)
- c->x86_max_cores = (eax >> 26) + 1;
-}
-
void cpu_detect_cache_sizes(struct cpuinfo_x86 *c)
{
unsigned int n, dummy, ebx, ecx, edx, l2size;
@@ -864,51 +866,6 @@ static void cpu_detect_tlb(struct cpuinfo_x86 *c)
tlb_lld_4m[ENTRIES], tlb_lld_1g[ENTRIES]);
}
-int detect_ht_early(struct cpuinfo_x86 *c)
-{
-#ifdef CONFIG_SMP
- u32 eax, ebx, ecx, edx;
-
- if (!cpu_has(c, X86_FEATURE_HT))
- return -1;
-
- if (cpu_has(c, X86_FEATURE_CMP_LEGACY))
- return -1;
-
- if (cpu_has(c, X86_FEATURE_XTOPOLOGY))
- return -1;
-
- cpuid(1, &eax, &ebx, &ecx, &edx);
-
- smp_num_siblings = (ebx & 0xff0000) >> 16;
- if (smp_num_siblings == 1)
- pr_info_once("CPU0: Hyper-Threading is disabled\n");
-#endif
- return 0;
-}
-
-void detect_ht(struct cpuinfo_x86 *c)
-{
-#ifdef CONFIG_SMP
- int index_msb, core_bits;
-
- if (detect_ht_early(c) < 0)
- return;
-
- index_msb = get_count_order(smp_num_siblings);
- c->topo.pkg_id = apic->phys_pkg_id(c->topo.initial_apicid, index_msb);
-
- smp_num_siblings = smp_num_siblings / c->x86_max_cores;
-
- index_msb = get_count_order(smp_num_siblings);
-
- core_bits = get_count_order(c->x86_max_cores);
-
- c->topo.core_id = apic->phys_pkg_id(c->topo.initial_apicid, index_msb) &
- ((1 << core_bits) - 1);
-#endif
-}
-
static void get_cpu_vendor(struct cpuinfo_x86 *c)
{
char *v = c->x86_vendor_id;
@@ -1163,6 +1120,7 @@ static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c)
#define NO_SPECTRE_V2 BIT(8)
#define NO_MMIO BIT(9)
#define NO_EIBRS_PBRSB BIT(10)
+#define NO_BHI BIT(11)
#define VULNWL(vendor, family, model, whitelist) \
X86_MATCH_VENDOR_FAM_MODEL(vendor, family, model, whitelist)
@@ -1225,18 +1183,18 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
VULNWL_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),
- VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
- VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
- VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
+ VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_BHI),
+ VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_BHI),
+ VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_BHI),
+ VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_BHI),
/* FAMILY_ANY must be last, otherwise 0x0f - 0x12 matches won't work */
- VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_EIBRS_PBRSB),
- VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_EIBRS_PBRSB),
+ VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_EIBRS_PBRSB | NO_BHI),
+ VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_EIBRS_PBRSB | NO_BHI),
/* Zhaoxin Family 7 */
- VULNWL(CENTAUR, 7, X86_MODEL_ANY, NO_SPECTRE_V2 | NO_SWAPGS | NO_MMIO),
- VULNWL(ZHAOXIN, 7, X86_MODEL_ANY, NO_SPECTRE_V2 | NO_SWAPGS | NO_MMIO),
+ VULNWL(CENTAUR, 7, X86_MODEL_ANY, NO_SPECTRE_V2 | NO_SWAPGS | NO_MMIO | NO_BHI),
+ VULNWL(ZHAOXIN, 7, X86_MODEL_ANY, NO_SPECTRE_V2 | NO_SWAPGS | NO_MMIO | NO_BHI),
{}
};
@@ -1267,6 +1225,8 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
#define SRSO BIT(5)
/* CPU is affected by GDS */
#define GDS BIT(6)
+/* CPU is affected by Register File Data Sampling */
+#define RFDS BIT(7)
static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = {
VULNBL_INTEL_STEPPINGS(IVYBRIDGE, X86_STEPPING_ANY, SRBDS),
@@ -1294,9 +1254,18 @@ static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = {
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(ATOM_TREMONT, X86_STEPPING_ANY, MMIO | MMIO_SBDS),
- VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_D, X86_STEPPING_ANY, MMIO),
- VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS),
+ 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_AMD(0x15, RETBLEED),
VULNBL_AMD(0x16, RETBLEED),
@@ -1330,6 +1299,24 @@ static bool arch_cap_mmio_immune(u64 ia32_cap)
ia32_cap & ARCH_CAP_SBDR_SSDP_NO);
}
+static bool __init vulnerable_to_rfds(u64 ia32_cap)
+{
+ /* The "immunity" bit trumps everything else: */
+ if (ia32_cap & ARCH_CAP_RFDS_NO)
+ return false;
+
+ /*
+ * VMMs set ARCH_CAP_RFDS_CLEAR for processors not in the blacklist to
+ * indicate that mitigation is needed because guest is running on a
+ * vulnerable hardware or may migrate to such hardware:
+ */
+ if (ia32_cap & ARCH_CAP_RFDS_CLEAR)
+ return true;
+
+ /* Only consult the blacklist when there is no enumeration: */
+ return cpu_matches(cpu_vuln_blacklist, RFDS);
+}
+
static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
{
u64 ia32_cap = x86_read_arch_cap_msr();
@@ -1355,8 +1342,13 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
/*
* AMD's AutoIBRS is equivalent to Intel's eIBRS - use the Intel feature
* flag and protect from vendor-specific bugs via the whitelist.
+ *
+ * Don't use AutoIBRS when SNP is enabled because it degrades host
+ * userspace indirect branch performance.
*/
- if ((ia32_cap & ARCH_CAP_IBRS_ALL) || cpu_has(c, X86_FEATURE_AUTOIBRS)) {
+ if ((ia32_cap & ARCH_CAP_IBRS_ALL) ||
+ (cpu_has(c, X86_FEATURE_AUTOIBRS) &&
+ !cpu_feature_enabled(X86_FEATURE_SEV_SNP))) {
setup_force_cpu_cap(X86_FEATURE_IBRS_ENHANCED);
if (!cpu_matches(cpu_vuln_whitelist, NO_EIBRS_PBRSB) &&
!(ia32_cap & ARCH_CAP_PBRSB_NO))
@@ -1441,6 +1433,16 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
boot_cpu_has(X86_FEATURE_AVX))
setup_force_cpu_bug(X86_BUG_GDS);
+ if (vulnerable_to_rfds(ia32_cap))
+ setup_force_cpu_bug(X86_BUG_RFDS);
+
+ /* When virtualized, eIBRS could be hidden, assume vulnerable */
+ if (!(ia32_cap & ARCH_CAP_BHI_NO) &&
+ !cpu_matches(cpu_vuln_whitelist, NO_BHI) &&
+ (boot_cpu_has(X86_FEATURE_IBRS_ENHANCED) ||
+ boot_cpu_has(X86_FEATURE_HYPERVISOR)))
+ setup_force_cpu_bug(X86_BUG_BHI);
+
if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN))
return;
@@ -1592,6 +1594,8 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c)
get_cpu_address_sizes(c);
cpu_parse_early_param();
+ cpu_init_topology(c);
+
if (this_cpu->c_early_init)
this_cpu->c_early_init(c);
@@ -1603,6 +1607,7 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c)
} else {
setup_clear_cpu_cap(X86_FEATURE_CPUID);
get_cpu_address_sizes(c);
+ cpu_init_topology(c);
}
setup_force_cpu_cap(X86_FEATURE_ALWAYS);
@@ -1748,18 +1753,6 @@ static void generic_identify(struct cpuinfo_x86 *c)
get_cpu_address_sizes(c);
- if (c->cpuid_level >= 0x00000001) {
- c->topo.initial_apicid = (cpuid_ebx(1) >> 24) & 0xFF;
-#ifdef CONFIG_X86_32
-# ifdef CONFIG_SMP
- c->topo.apicid = apic->phys_pkg_id(c->topo.initial_apicid, 0);
-# else
- c->topo.apicid = c->topo.initial_apicid;
-# endif
-#endif
- c->topo.pkg_id = c->topo.initial_apicid;
- }
-
get_model_name(c); /* Default name */
/*
@@ -1781,29 +1774,6 @@ static void generic_identify(struct cpuinfo_x86 *c)
}
/*
- * Validate that ACPI/mptables have the same information about the
- * effective APIC id and update the package map.
- */
-static void validate_apic_and_package_id(struct cpuinfo_x86 *c)
-{
-#ifdef CONFIG_SMP
- unsigned int cpu = smp_processor_id();
- u32 apicid;
-
- apicid = apic->cpu_present_to_apicid(cpu);
-
- if (apicid != c->topo.apicid) {
- pr_err(FW_BUG "CPU%u: APIC id mismatch. Firmware: %x APIC: %x\n",
- cpu, apicid, c->topo.initial_apicid);
- }
- BUG_ON(topology_update_package_map(c->topo.pkg_id, cpu));
- BUG_ON(topology_update_die_map(c->topo.die_id, cpu));
-#else
- c->topo.logical_pkg_id = 0;
-#endif
-}
-
-/*
* This does the hard work of actually picking apart the CPU stuff...
*/
static void identify_cpu(struct cpuinfo_x86 *c)
@@ -1816,11 +1786,6 @@ static void identify_cpu(struct cpuinfo_x86 *c)
c->x86_model = c->x86_stepping = 0; /* So far unknown... */
c->x86_vendor_id[0] = '\0'; /* Unset */
c->x86_model_id[0] = '\0'; /* Unset */
- c->x86_max_cores = 1;
- c->x86_coreid_bits = 0;
- c->topo.cu_id = 0xff;
- c->topo.llc_id = BAD_APICID;
- c->topo.l2c_id = BAD_APICID;
#ifdef CONFIG_X86_64
c->x86_clflush_size = 64;
c->x86_phys_bits = 36;
@@ -1839,17 +1804,14 @@ static void identify_cpu(struct cpuinfo_x86 *c)
generic_identify(c);
+ cpu_parse_topology(c);
+
if (this_cpu->c_identify)
this_cpu->c_identify(c);
/* Clear/Set all flags overridden by options, after probe */
apply_forced_caps(c);
-#ifdef CONFIG_X86_64
- c->topo.apicid = apic->phys_pkg_id(c->topo.initial_apicid, 0);
-#endif
-
-
/*
* Set default APIC and TSC_DEADLINE MSR fencing flag. AMD and
* Hygon will clear it in ->c_init() below.
@@ -1903,10 +1865,6 @@ static void identify_cpu(struct cpuinfo_x86 *c)
c->x86, c->x86_model);
}
-#ifdef CONFIG_X86_64
- detect_ht(c);
-#endif
-
x86_init_rdrand(c);
setup_pku(c);
setup_cet(c);
@@ -1938,8 +1896,6 @@ static void identify_cpu(struct cpuinfo_x86 *c)
/* Init Machine Check Exception if available. */
mcheck_cpu_init(c);
- select_idle_routine(c);
-
#ifdef CONFIG_NUMA
numa_add_cpu(smp_processor_id());
#endif
@@ -1998,7 +1954,6 @@ void identify_secondary_cpu(struct cpuinfo_x86 *c)
#ifdef CONFIG_X86_32
enable_sep_cpu();
#endif
- validate_apic_and_package_id(c);
x86_spec_ctrl_setup_ap();
update_srbds_msr();
if (boot_cpu_has_bug(X86_BUG_GDS))
@@ -2050,6 +2005,7 @@ DEFINE_PER_CPU_ALIGNED(struct pcpu_hot, pcpu_hot) = {
.top_of_stack = TOP_OF_INIT_STACK,
};
EXPORT_PER_CPU_SYMBOL(pcpu_hot);
+EXPORT_PER_CPU_SYMBOL(const_pcpu_hot);
#ifdef CONFIG_X86_64
DEFINE_PER_CPU_FIRST(struct fixed_percpu_data,
@@ -2067,10 +2023,8 @@ static void wrmsrl_cstar(unsigned long val)
wrmsrl(MSR_CSTAR, val);
}
-/* May not be marked __init: used by software suspend */
-void syscall_init(void)
+static inline void idt_syscall_init(void)
{
- wrmsr(MSR_STAR, 0, (__USER32_CS << 16) | __KERNEL_CS);
wrmsrl(MSR_LSTAR, (unsigned long)entry_SYSCALL_64);
if (ia32_enabled()) {
@@ -2104,6 +2058,23 @@ void syscall_init(void)
X86_EFLAGS_AC|X86_EFLAGS_ID);
}
+/* May not be marked __init: used by software suspend */
+void syscall_init(void)
+{
+ /* The default user and kernel segments */
+ wrmsr(MSR_STAR, 0, (__USER32_CS << 16) | __KERNEL_CS);
+
+ /*
+ * Except the IA32_STAR MSR, there is NO need to setup SYSCALL and
+ * SYSENTER MSRs for FRED, because FRED uses the ring 3 FRED
+ * entrypoint for SYSCALL and SYSENTER, and ERETU is the only legit
+ * instruction to return to ring 3 (both sysexit and sysret cause
+ * #UD when FRED is enabled).
+ */
+ if (!cpu_feature_enabled(X86_FEATURE_FRED))
+ idt_syscall_init();
+}
+
#else /* CONFIG_X86_64 */
#ifdef CONFIG_STACKPROTECTOR
@@ -2207,8 +2178,9 @@ void cpu_init_exception_handling(void)
/* paranoid_entry() gets the CPU number from the GDT */
setup_getcpu(cpu);
- /* IST vectors need TSS to be set up. */
- tss_setup_ist(tss);
+ /* For IDT mode, IST vectors need to be set in TSS. */
+ if (!cpu_feature_enabled(X86_FEATURE_FRED))
+ tss_setup_ist(tss);
tss_setup_io_bitmap(tss);
set_tss_desc(cpu, &get_cpu_entry_area(cpu)->tss.x86_tss);
@@ -2217,8 +2189,10 @@ void cpu_init_exception_handling(void)
/* GHCB needs to be setup to handle #VC. */
setup_ghcb();
- /* Finally load the IDT */
- load_current_idt();
+ if (cpu_feature_enabled(X86_FEATURE_FRED))
+ cpu_init_fred_exceptions();
+ else
+ load_current_idt();
}
/*
@@ -2341,13 +2315,17 @@ void arch_smt_update(void)
void __init arch_cpu_finalize_init(void)
{
+ struct cpuinfo_x86 *c = this_cpu_ptr(&cpu_info);
+
identify_boot_cpu();
+ select_idle_routine();
+
/*
* identify_boot_cpu() initialized SMT support information, let the
* core code know.
*/
- cpu_smt_set_num_threads(smp_num_siblings, smp_num_siblings);
+ cpu_smt_set_num_threads(__max_threads_per_core, __max_threads_per_core);
if (!IS_ENABLED(CONFIG_SMP)) {
pr_info("CPU: ");
@@ -2377,6 +2355,13 @@ void __init arch_cpu_finalize_init(void)
fpu__init_system();
fpu__init_cpu();
+ /*
+ * Ensure that access to the per CPU representation has the initial
+ * boot CPU configuration.
+ */
+ *c = boot_cpu_data;
+ c->initialized = true;
+
alternative_instructions();
if (IS_ENABLED(CONFIG_X86_64)) {
diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h
index 885281ae79a5..ea9e07d57c8d 100644
--- a/arch/x86/kernel/cpu/cpu.h
+++ b/arch/x86/kernel/cpu/cpu.h
@@ -2,6 +2,11 @@
#ifndef ARCH_X86_CPU_H
#define ARCH_X86_CPU_H
+#include <asm/cpu.h>
+#include <asm/topology.h>
+
+#include "topology.h"
+
/* attempt to consolidate cpu attributes */
struct cpu_dev {
const char *c_vendor;
@@ -71,14 +76,9 @@ extern void init_intel_cacheinfo(struct cpuinfo_x86 *c);
extern void init_amd_cacheinfo(struct cpuinfo_x86 *c);
extern void init_hygon_cacheinfo(struct cpuinfo_x86 *c);
-extern void detect_num_cpu_cores(struct cpuinfo_x86 *c);
-extern int detect_extended_topology_early(struct cpuinfo_x86 *c);
-extern int detect_extended_topology(struct cpuinfo_x86 *c);
-extern int detect_ht_early(struct cpuinfo_x86 *c);
-extern void detect_ht(struct cpuinfo_x86 *c);
extern void check_null_seg_clears_base(struct cpuinfo_x86 *c);
-void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c);
+void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, u16 die_id);
void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c);
unsigned int aperfmperf_get_khz(int cpu);
@@ -96,4 +96,5 @@ static inline bool spectre_v2_in_eibrs_mode(enum spectre_v2_mitigation mode)
mode == SPECTRE_V2_EIBRS_RETPOLINE ||
mode == SPECTRE_V2_EIBRS_LFENCE;
}
+
#endif /* ARCH_X86_CPU_H */
diff --git a/arch/x86/kernel/cpu/cpuid-deps.c b/arch/x86/kernel/cpu/cpuid-deps.c
index e462c1d3800a..b7174209d855 100644
--- a/arch/x86/kernel/cpu/cpuid-deps.c
+++ b/arch/x86/kernel/cpu/cpuid-deps.c
@@ -82,6 +82,8 @@ static const struct cpuid_dep cpuid_deps[] = {
{ X86_FEATURE_XFD, X86_FEATURE_XGETBV1 },
{ X86_FEATURE_AMX_TILE, X86_FEATURE_XFD },
{ X86_FEATURE_SHSTK, X86_FEATURE_XSAVES },
+ { X86_FEATURE_FRED, X86_FEATURE_LKGS },
+ { X86_FEATURE_FRED, X86_FEATURE_WRMSRNS },
{}
};
diff --git a/arch/x86/kernel/cpu/debugfs.c b/arch/x86/kernel/cpu/debugfs.c
index 0c179d684b3b..3baf3e435834 100644
--- a/arch/x86/kernel/cpu/debugfs.c
+++ b/arch/x86/kernel/cpu/debugfs.c
@@ -5,6 +5,8 @@
#include <asm/apic.h>
#include <asm/processor.h>
+#include "cpu.h"
+
static int cpu_debug_show(struct seq_file *m, void *p)
{
unsigned long cpu = (unsigned long)m->private;
@@ -24,9 +26,12 @@ static int cpu_debug_show(struct seq_file *m, void *p)
seq_printf(m, "logical_die_id: %u\n", c->topo.logical_die_id);
seq_printf(m, "llc_id: %u\n", c->topo.llc_id);
seq_printf(m, "l2c_id: %u\n", c->topo.l2c_id);
- seq_printf(m, "max_cores: %u\n", c->x86_max_cores);
- seq_printf(m, "max_die_per_pkg: %u\n", __max_die_per_package);
- seq_printf(m, "smp_num_siblings: %u\n", smp_num_siblings);
+ seq_printf(m, "amd_node_id: %u\n", c->topo.amd_node_id);
+ seq_printf(m, "amd_nodes_per_pkg: %u\n", topology_amd_nodes_per_pkg());
+ seq_printf(m, "num_threads: %u\n", __num_threads_per_package);
+ seq_printf(m, "num_cores: %u\n", __num_cores_per_package);
+ seq_printf(m, "max_dies_per_pkg: %u\n", __max_dies_per_package);
+ seq_printf(m, "max_threads_per_core:%u\n", __max_threads_per_core);
return 0;
}
@@ -42,12 +47,48 @@ static const struct file_operations dfs_cpu_ops = {
.release = single_release,
};
+static int dom_debug_show(struct seq_file *m, void *p)
+{
+ static const char *domain_names[TOPO_MAX_DOMAIN] = {
+ [TOPO_SMT_DOMAIN] = "Thread",
+ [TOPO_CORE_DOMAIN] = "Core",
+ [TOPO_MODULE_DOMAIN] = "Module",
+ [TOPO_TILE_DOMAIN] = "Tile",
+ [TOPO_DIE_DOMAIN] = "Die",
+ [TOPO_DIEGRP_DOMAIN] = "DieGrp",
+ [TOPO_PKG_DOMAIN] = "Package",
+ };
+ unsigned int dom, nthreads = 1;
+
+ for (dom = 0; dom < TOPO_MAX_DOMAIN; dom++) {
+ nthreads *= x86_topo_system.dom_size[dom];
+ seq_printf(m, "domain: %-10s shift: %u dom_size: %5u max_threads: %5u\n",
+ domain_names[dom], x86_topo_system.dom_shifts[dom],
+ x86_topo_system.dom_size[dom], nthreads);
+ }
+ return 0;
+}
+
+static int dom_debug_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, dom_debug_show, inode->i_private);
+}
+
+static const struct file_operations dfs_dom_ops = {
+ .open = dom_debug_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
static __init int cpu_init_debugfs(void)
{
struct dentry *dir, *base = debugfs_create_dir("topo", arch_debugfs_dir);
unsigned long id;
char name[24];
+ debugfs_create_file("domains", 0444, base, NULL, &dfs_dom_ops);
+
dir = debugfs_create_dir("cpus", base);
for_each_possible_cpu(id) {
sprintf(name, "%lu", id);
diff --git a/arch/x86/kernel/cpu/feat_ctl.c b/arch/x86/kernel/cpu/feat_ctl.c
index 03851240c3e3..1640ae76548f 100644
--- a/arch/x86/kernel/cpu/feat_ctl.c
+++ b/arch/x86/kernel/cpu/feat_ctl.c
@@ -72,6 +72,8 @@ static void init_vmx_capabilities(struct cpuinfo_x86 *c)
c->vmx_capability[MISC_FEATURES] |= VMX_F(EPT_AD);
if (ept & VMX_EPT_1GB_PAGE_BIT)
c->vmx_capability[MISC_FEATURES] |= VMX_F(EPT_1GB);
+ if (ept & VMX_EPT_PAGE_WALK_5_BIT)
+ c->vmx_capability[MISC_FEATURES] |= VMX_F(EPT_5LEVEL);
/* Synthetic APIC features that are aggregates of multiple features. */
if ((c->vmx_capability[PRIMARY_CTLS] & VMX_F(VIRTUAL_TPR)) &&
diff --git a/arch/x86/kernel/cpu/hygon.c b/arch/x86/kernel/cpu/hygon.c
index f0cd95502faa..c5191b06f9f2 100644
--- a/arch/x86/kernel/cpu/hygon.c
+++ b/arch/x86/kernel/cpu/hygon.c
@@ -18,14 +18,6 @@
#include "cpu.h"
-#define APICID_SOCKET_ID_BIT 6
-
-/*
- * nodes_per_socket: Stores the number of nodes per socket.
- * Refer to CPUID Fn8000_001E_ECX Node Identifiers[10:8]
- */
-static u32 nodes_per_socket = 1;
-
#ifdef CONFIG_NUMA
/*
* To workaround broken NUMA config. Read the comment in
@@ -49,80 +41,6 @@ static int nearby_node(int apicid)
}
#endif
-static void hygon_get_topology_early(struct cpuinfo_x86 *c)
-{
- if (cpu_has(c, X86_FEATURE_TOPOEXT))
- smp_num_siblings = ((cpuid_ebx(0x8000001e) >> 8) & 0xff) + 1;
-}
-
-/*
- * Fixup core topology information for
- * (1) Hygon multi-node processors
- * Assumption: Number of cores in each internal node is the same.
- * (2) Hygon processors supporting compute units
- */
-static void hygon_get_topology(struct cpuinfo_x86 *c)
-{
- /* get information required for multi-node processors */
- if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
- int err;
- u32 eax, ebx, ecx, edx;
-
- cpuid(0x8000001e, &eax, &ebx, &ecx, &edx);
-
- c->topo.die_id = ecx & 0xff;
-
- c->topo.core_id = ebx & 0xff;
-
- if (smp_num_siblings > 1)
- c->x86_max_cores /= smp_num_siblings;
-
- /*
- * In case leaf B is available, use it to derive
- * topology information.
- */
- err = detect_extended_topology(c);
- if (!err)
- c->x86_coreid_bits = get_count_order(c->x86_max_cores);
-
- /*
- * Socket ID is ApicId[6] for the processors with model <= 0x3
- * when running on host.
- */
- if (!boot_cpu_has(X86_FEATURE_HYPERVISOR) && c->x86_model <= 0x3)
- c->topo.pkg_id = c->topo.apicid >> APICID_SOCKET_ID_BIT;
-
- cacheinfo_hygon_init_llc_id(c);
- } else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) {
- u64 value;
-
- rdmsrl(MSR_FAM10H_NODE_ID, value);
- c->topo.die_id = value & 7;
- c->topo.llc_id = c->topo.die_id;
- } else
- return;
-
- if (nodes_per_socket > 1)
- set_cpu_cap(c, X86_FEATURE_AMD_DCM);
-}
-
-/*
- * On Hygon setup the lower bits of the APIC id distinguish the cores.
- * Assumes number of cores is a power of two.
- */
-static void hygon_detect_cmp(struct cpuinfo_x86 *c)
-{
- unsigned int bits;
-
- bits = c->x86_coreid_bits;
- /* Low order bits define the core id (index of core in socket) */
- c->topo.core_id = c->topo.initial_apicid & ((1 << bits)-1);
- /* Convert the initial APIC ID into the socket ID */
- c->topo.pkg_id = c->topo.initial_apicid >> bits;
- /* Use package ID also for last level cache */
- c->topo.llc_id = c->topo.die_id = c->topo.pkg_id;
-}
-
static void srat_detect_node(struct cpuinfo_x86 *c)
{
#ifdef CONFIG_NUMA
@@ -173,32 +91,6 @@ static void srat_detect_node(struct cpuinfo_x86 *c)
#endif
}
-static void early_init_hygon_mc(struct cpuinfo_x86 *c)
-{
-#ifdef CONFIG_SMP
- unsigned int bits, ecx;
-
- /* Multi core CPU? */
- if (c->extended_cpuid_level < 0x80000008)
- return;
-
- ecx = cpuid_ecx(0x80000008);
-
- c->x86_max_cores = (ecx & 0xff) + 1;
-
- /* CPU telling us the core id bits shift? */
- bits = (ecx >> 12) & 0xF;
-
- /* Otherwise recompute */
- if (bits == 0) {
- while ((1 << bits) < c->x86_max_cores)
- bits++;
- }
-
- c->x86_coreid_bits = bits;
-#endif
-}
-
static void bsp_init_hygon(struct cpuinfo_x86 *c)
{
if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) {
@@ -212,18 +104,6 @@ static void bsp_init_hygon(struct cpuinfo_x86 *c)
if (cpu_has(c, X86_FEATURE_MWAITX))
use_mwaitx_delay();
- if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
- u32 ecx;
-
- ecx = cpuid_ecx(0x8000001e);
- __max_die_per_package = nodes_per_socket = ((ecx >> 8) & 7) + 1;
- } else if (boot_cpu_has(X86_FEATURE_NODEID_MSR)) {
- u64 value;
-
- rdmsrl(MSR_FAM10H_NODE_ID, value);
- __max_die_per_package = nodes_per_socket = ((value >> 3) & 7) + 1;
- }
-
if (!boot_cpu_has(X86_FEATURE_AMD_SSBD) &&
!boot_cpu_has(X86_FEATURE_VIRT_SSBD)) {
/*
@@ -242,8 +122,6 @@ static void early_init_hygon(struct cpuinfo_x86 *c)
{
u32 dummy;
- early_init_hygon_mc(c);
-
set_cpu_cap(c, X86_FEATURE_K8);
rdmsr_safe(MSR_AMD64_PATCH_LEVEL, &c->microcode, &dummy);
@@ -284,8 +162,6 @@ static void early_init_hygon(struct cpuinfo_x86 *c)
* we can set it unconditionally.
*/
set_cpu_cap(c, X86_FEATURE_VMMCALL);
-
- hygon_get_topology_early(c);
}
static void init_hygon(struct cpuinfo_x86 *c)
@@ -302,9 +178,6 @@ static void init_hygon(struct cpuinfo_x86 *c)
set_cpu_cap(c, X86_FEATURE_REP_GOOD);
- /* get apicid instead of initial apic id from cpuid */
- c->topo.apicid = read_apic_id();
-
/*
* XXX someone from Hygon needs to confirm this DTRT
*
@@ -316,8 +189,6 @@ static void init_hygon(struct cpuinfo_x86 *c)
cpu_detect_cache_sizes(c);
- hygon_detect_cmp(c);
- hygon_get_topology(c);
srat_detect_node(c);
init_hygon_cacheinfo(c);
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 40dec9b56f87..be30d7fa2e66 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -401,13 +401,6 @@ static void early_init_intel(struct cpuinfo_x86 *c)
check_memory_type_self_snoop_errata(c);
/*
- * Get the number of SMT siblings early from the extended topology
- * leaf, if available. Otherwise try the legacy SMT detection.
- */
- if (detect_extended_topology_early(c) < 0)
- detect_ht_early(c);
-
- /*
* Adjust the number of physical bits early because it affects the
* valid bits of the MTRR mask registers.
*/
@@ -610,24 +603,6 @@ static void init_intel(struct cpuinfo_x86 *c)
intel_workarounds(c);
- /*
- * Detect the extended topology information if available. This
- * will reinitialise the initial_apicid which will be used
- * in init_intel_cacheinfo()
- */
- detect_extended_topology(c);
-
- if (!cpu_has(c, X86_FEATURE_XTOPOLOGY)) {
- /*
- * let's use the legacy cpuid vector 0x1 and 0x4 for topology
- * detection.
- */
- detect_num_cpu_cores(c);
-#ifdef CONFIG_X86_32
- detect_ht(c);
-#endif
- }
-
init_intel_cacheinfo(c);
if (c->cpuid_level > 9) {
diff --git a/arch/x86/kernel/cpu/intel_pconfig.c b/arch/x86/kernel/cpu/intel_pconfig.c
index 0771a905b286..5be2b1790282 100644
--- a/arch/x86/kernel/cpu/intel_pconfig.c
+++ b/arch/x86/kernel/cpu/intel_pconfig.c
@@ -7,6 +7,8 @@
* 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>
diff --git a/arch/x86/kernel/cpu/mce/amd.c b/arch/x86/kernel/cpu/mce/amd.c
index 2b46eb0fdf3a..9a0133ef7e20 100644
--- a/arch/x86/kernel/cpu/mce/amd.c
+++ b/arch/x86/kernel/cpu/mce/amd.c
@@ -1231,7 +1231,7 @@ static int threshold_create_bank(struct threshold_bank **bp, unsigned int cpu,
return -ENODEV;
if (is_shared_bank(bank)) {
- nb = node_to_amd_nb(topology_die_id(cpu));
+ nb = node_to_amd_nb(topology_amd_node_id(cpu));
/* threshold descriptor already initialized on this node? */
if (nb && nb->bank4) {
@@ -1335,7 +1335,7 @@ static void threshold_remove_bank(struct threshold_bank *bank)
* The last CPU on this node using the shared bank is going
* away, remove that bank now.
*/
- nb = node_to_amd_nb(topology_die_id(smp_processor_id()));
+ nb = node_to_amd_nb(topology_amd_node_id(smp_processor_id()));
nb->bank4 = NULL;
}
diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c
index bc39252bc54f..84d41be6d06b 100644
--- a/arch/x86/kernel/cpu/mce/core.c
+++ b/arch/x86/kernel/cpu/mce/core.c
@@ -46,6 +46,7 @@
#include <linux/hardirq.h>
#include <linux/kexec.h>
+#include <asm/fred.h>
#include <asm/intel-family.h>
#include <asm/processor.h>
#include <asm/traps.h>
@@ -2166,6 +2167,31 @@ DEFINE_IDTENTRY_MCE_USER(exc_machine_check)
exc_machine_check_user(regs);
local_db_restore(dr7);
}
+
+#ifdef CONFIG_X86_FRED
+/*
+ * When occurred on different ring level, i.e., from user or kernel
+ * context, #MCE needs to be handled on different stack: User #MCE
+ * on current task stack, while kernel #MCE on a dedicated stack.
+ *
+ * This is exactly how FRED event delivery invokes an exception
+ * handler: ring 3 event on level 0 stack, i.e., current task stack;
+ * ring 0 event on the #MCE dedicated stack specified in the
+ * IA32_FRED_STKLVLS MSR. So unlike IDT, the FRED machine check entry
+ * stub doesn't do stack switch.
+ */
+DEFINE_FREDENTRY_MCE(exc_machine_check)
+{
+ unsigned long dr7;
+
+ dr7 = local_db_save();
+ if (user_mode(regs))
+ exc_machine_check_user(regs);
+ else
+ exc_machine_check_kernel(regs);
+ local_db_restore(dr7);
+}
+#endif
#else
/* 32bit unified entry point */
DEFINE_IDTENTRY_RAW(exc_machine_check)
@@ -2431,7 +2457,7 @@ static void mce_enable_ce(void *all)
__mcheck_cpu_init_timer();
}
-static struct bus_type mce_subsys = {
+static const struct bus_type mce_subsys = {
.name = "machinecheck",
.dev_name = "machinecheck",
};
@@ -2474,12 +2500,14 @@ static ssize_t set_bank(struct device *s, struct device_attribute *attr,
return -EINVAL;
b = &per_cpu(mce_banks_array, s->id)[bank];
-
if (!b->init)
return -ENODEV;
b->ctl = new;
+
+ mutex_lock(&mce_sysfs_mutex);
mce_restart();
+ mutex_unlock(&mce_sysfs_mutex);
return size;
}
diff --git a/arch/x86/kernel/cpu/mce/inject.c b/arch/x86/kernel/cpu/mce/inject.c
index 72f0695c3dc1..94953d749475 100644
--- a/arch/x86/kernel/cpu/mce/inject.c
+++ b/arch/x86/kernel/cpu/mce/inject.c
@@ -430,11 +430,9 @@ static void trigger_thr_int(void *info)
static u32 get_nbc_for_node(int node_id)
{
- struct cpuinfo_x86 *c = &boot_cpu_data;
u32 cores_per_node;
- cores_per_node = (c->x86_max_cores * smp_num_siblings) / amd_get_nodes_per_socket();
-
+ cores_per_node = topology_num_threads_per_package() / topology_amd_nodes_per_pkg();
return cores_per_node * node_id;
}
@@ -543,8 +541,8 @@ static void do_inject(void)
if (boot_cpu_has(X86_FEATURE_AMD_DCM) &&
b == 4 &&
boot_cpu_data.x86 < 0x17) {
- toggle_nb_mca_mst_cpu(topology_die_id(cpu));
- cpu = get_nbc_for_node(topology_die_id(cpu));
+ toggle_nb_mca_mst_cpu(topology_amd_node_id(cpu));
+ cpu = get_nbc_for_node(topology_amd_node_id(cpu));
}
cpus_read_lock();
diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
index 857e608af641..5f0414452b67 100644
--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -641,7 +641,7 @@ static __init void calc_llc_size_per_core(struct cpuinfo_x86 *c)
{
u64 llc_size = c->x86_cache_size * 1024ULL;
- do_div(llc_size, c->x86_max_cores);
+ do_div(llc_size, topology_num_cores_per_package());
llc_size_per_core = (unsigned int)llc_size;
}
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 01fa06dd06b6..e0fd57a8ba84 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -45,70 +45,70 @@ bool hyperv_paravisor_present __ro_after_init;
EXPORT_SYMBOL_GPL(hyperv_paravisor_present);
#if IS_ENABLED(CONFIG_HYPERV)
-static inline unsigned int hv_get_nested_reg(unsigned int reg)
+static inline unsigned int hv_get_nested_msr(unsigned int reg)
{
- if (hv_is_sint_reg(reg))
- return reg - HV_REGISTER_SINT0 + HV_REGISTER_NESTED_SINT0;
+ if (hv_is_sint_msr(reg))
+ return reg - HV_X64_MSR_SINT0 + HV_X64_MSR_NESTED_SINT0;
switch (reg) {
- case HV_REGISTER_SIMP:
- return HV_REGISTER_NESTED_SIMP;
- case HV_REGISTER_SIEFP:
- return HV_REGISTER_NESTED_SIEFP;
- case HV_REGISTER_SVERSION:
- return HV_REGISTER_NESTED_SVERSION;
- case HV_REGISTER_SCONTROL:
- return HV_REGISTER_NESTED_SCONTROL;
- case HV_REGISTER_EOM:
- return HV_REGISTER_NESTED_EOM;
+ case HV_X64_MSR_SIMP:
+ return HV_X64_MSR_NESTED_SIMP;
+ case HV_X64_MSR_SIEFP:
+ return HV_X64_MSR_NESTED_SIEFP;
+ case HV_X64_MSR_SVERSION:
+ return HV_X64_MSR_NESTED_SVERSION;
+ case HV_X64_MSR_SCONTROL:
+ return HV_X64_MSR_NESTED_SCONTROL;
+ case HV_X64_MSR_EOM:
+ return HV_X64_MSR_NESTED_EOM;
default:
return reg;
}
}
-u64 hv_get_non_nested_register(unsigned int reg)
+u64 hv_get_non_nested_msr(unsigned int reg)
{
u64 value;
- if (hv_is_synic_reg(reg) && ms_hyperv.paravisor_present)
+ if (hv_is_synic_msr(reg) && ms_hyperv.paravisor_present)
hv_ivm_msr_read(reg, &value);
else
rdmsrl(reg, value);
return value;
}
-EXPORT_SYMBOL_GPL(hv_get_non_nested_register);
+EXPORT_SYMBOL_GPL(hv_get_non_nested_msr);
-void hv_set_non_nested_register(unsigned int reg, u64 value)
+void hv_set_non_nested_msr(unsigned int reg, u64 value)
{
- if (hv_is_synic_reg(reg) && ms_hyperv.paravisor_present) {
+ if (hv_is_synic_msr(reg) && ms_hyperv.paravisor_present) {
hv_ivm_msr_write(reg, value);
/* Write proxy bit via wrmsl instruction */
- if (hv_is_sint_reg(reg))
+ if (hv_is_sint_msr(reg))
wrmsrl(reg, value | 1 << 20);
} else {
wrmsrl(reg, value);
}
}
-EXPORT_SYMBOL_GPL(hv_set_non_nested_register);
+EXPORT_SYMBOL_GPL(hv_set_non_nested_msr);
-u64 hv_get_register(unsigned int reg)
+u64 hv_get_msr(unsigned int reg)
{
if (hv_nested)
- reg = hv_get_nested_reg(reg);
+ reg = hv_get_nested_msr(reg);
- return hv_get_non_nested_register(reg);
+ return hv_get_non_nested_msr(reg);
}
-EXPORT_SYMBOL_GPL(hv_get_register);
+EXPORT_SYMBOL_GPL(hv_get_msr);
-void hv_set_register(unsigned int reg, u64 value)
+void hv_set_msr(unsigned int reg, u64 value)
{
if (hv_nested)
- reg = hv_get_nested_reg(reg);
+ reg = hv_get_nested_msr(reg);
- hv_set_non_nested_register(reg, value);
+ hv_set_non_nested_msr(reg, value);
}
-EXPORT_SYMBOL_GPL(hv_set_register);
+EXPORT_SYMBOL_GPL(hv_set_msr);
static void (*vmbus_handler)(void);
static void (*hv_stimer0_handler)(void);
@@ -209,7 +209,9 @@ static void hv_machine_shutdown(void)
if (kexec_in_progress)
hyperv_cleanup();
}
+#endif /* CONFIG_KEXEC_CORE */
+#ifdef CONFIG_CRASH_DUMP
static void hv_machine_crash_shutdown(struct pt_regs *regs)
{
if (hv_crash_handler)
@@ -221,7 +223,7 @@ static void hv_machine_crash_shutdown(struct pt_regs *regs)
/* Disable the hypercall page when there is only 1 active CPU. */
hyperv_cleanup();
}
-#endif /* CONFIG_KEXEC_CORE */
+#endif /* CONFIG_CRASH_DUMP */
#endif /* CONFIG_HYPERV */
static uint32_t __init ms_hyperv_platform(void)
@@ -350,13 +352,24 @@ static void __init reduced_hw_init(void)
x86_init.irqs.pre_vector_init = x86_init_noop;
}
+int hv_get_hypervisor_version(union hv_hypervisor_version_info *info)
+{
+ unsigned int hv_max_functions;
+
+ hv_max_functions = cpuid_eax(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS);
+ if (hv_max_functions < HYPERV_CPUID_VERSION) {
+ pr_err("%s: Could not detect Hyper-V version\n", __func__);
+ return -ENODEV;
+ }
+
+ cpuid(HYPERV_CPUID_VERSION, &info->eax, &info->ebx, &info->ecx, &info->edx);
+
+ return 0;
+}
+
static void __init ms_hyperv_init_platform(void)
{
int hv_max_functions_eax;
- int hv_host_info_eax;
- int hv_host_info_ebx;
- int hv_host_info_ecx;
- int hv_host_info_edx;
#ifdef CONFIG_PARAVIRT
pv_info.name = "Hyper-V";
@@ -407,21 +420,6 @@ static void __init ms_hyperv_init_platform(void)
pr_info("Hyper-V: running on a nested hypervisor\n");
}
- /*
- * Extract host information.
- */
- if (hv_max_functions_eax >= HYPERV_CPUID_VERSION) {
- hv_host_info_eax = cpuid_eax(HYPERV_CPUID_VERSION);
- hv_host_info_ebx = cpuid_ebx(HYPERV_CPUID_VERSION);
- hv_host_info_ecx = cpuid_ecx(HYPERV_CPUID_VERSION);
- hv_host_info_edx = cpuid_edx(HYPERV_CPUID_VERSION);
-
- pr_info("Hyper-V: Host Build %d.%d.%d.%d-%d-%d\n",
- hv_host_info_ebx >> 16, hv_host_info_ebx & 0xFFFF,
- hv_host_info_eax, hv_host_info_edx & 0xFFFFFF,
- hv_host_info_ecx, hv_host_info_edx >> 24);
- }
-
if (ms_hyperv.features & HV_ACCESS_FREQUENCY_MSRS &&
ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) {
x86_platform.calibrate_tsc = hv_get_tsc_khz;
@@ -454,7 +452,7 @@ static void __init ms_hyperv_init_platform(void)
/* To be supported: more work is required. */
ms_hyperv.features &= ~HV_MSR_REFERENCE_TSC_AVAILABLE;
- /* HV_REGISTER_CRASH_CTL is unsupported. */
+ /* HV_MSR_CRASH_CTL is unsupported. */
ms_hyperv.misc_features &= ~HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE;
/* Don't trust Hyper-V's TLB-flushing hypercalls. */
@@ -495,10 +493,14 @@ static void __init ms_hyperv_init_platform(void)
no_timer_check = 1;
#endif
-#if IS_ENABLED(CONFIG_HYPERV) && defined(CONFIG_KEXEC_CORE)
+#if IS_ENABLED(CONFIG_HYPERV)
+#if defined(CONFIG_KEXEC_CORE)
machine_ops.shutdown = hv_machine_shutdown;
+#endif
+#if defined(CONFIG_CRASH_DUMP)
machine_ops.crash_shutdown = hv_machine_crash_shutdown;
#endif
+#endif
if (ms_hyperv.features & HV_ACCESS_TSC_INVARIANT) {
/*
* Writing to synthetic MSR 0x40000118 updates/changes the
@@ -539,19 +541,18 @@ static void __init ms_hyperv_init_platform(void)
*/
x86_platform.apic_post_init = hyperv_init;
hyperv_setup_mmu_ops();
- /* Setup the IDT for hypervisor callback */
- alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, asm_sysvec_hyperv_callback);
- /* Setup the IDT for reenlightenment notifications */
+ /* Install system interrupt handler for hypervisor callback */
+ sysvec_install(HYPERVISOR_CALLBACK_VECTOR, sysvec_hyperv_callback);
+
+ /* Install system interrupt handler for reenlightenment notifications */
if (ms_hyperv.features & HV_ACCESS_REENLIGHTENMENT) {
- alloc_intr_gate(HYPERV_REENLIGHTENMENT_VECTOR,
- asm_sysvec_hyperv_reenlightenment);
+ sysvec_install(HYPERV_REENLIGHTENMENT_VECTOR, sysvec_hyperv_reenlightenment);
}
- /* Setup the IDT for stimer0 */
+ /* Install system interrupt handler for stimer0 */
if (ms_hyperv.misc_features & HV_STIMER_DIRECT_MODE_AVAILABLE) {
- alloc_intr_gate(HYPERV_STIMER0_VECTOR,
- asm_sysvec_hyperv_stimer0);
+ sysvec_install(HYPERV_STIMER0_VECTOR, sysvec_hyperv_stimer0);
}
# ifdef CONFIG_SMP
@@ -643,6 +644,7 @@ const __initconst struct hypervisor_x86 x86_hyper_ms_hyperv = {
.init.x2apic_available = ms_hyperv_x2apic_available,
.init.msi_ext_dest_id = ms_hyperv_msi_ext_dest_id,
.init.init_platform = ms_hyperv_init_platform,
+ .init.guest_late_init = ms_hyperv_late_init,
#ifdef CONFIG_AMD_MEM_ENCRYPT
.runtime.sev_es_hcall_prepare = hv_sev_es_hcall_prepare,
.runtime.sev_es_hcall_finish = hv_sev_es_hcall_finish,
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c
index d3524778a545..7b29ebda024f 100644
--- a/arch/x86/kernel/cpu/mtrr/generic.c
+++ b/arch/x86/kernel/cpu/mtrr/generic.c
@@ -108,6 +108,9 @@ static inline void k8_check_syscfg_dram_mod_en(void)
(boot_cpu_data.x86 >= 0x0f)))
return;
+ if (cc_platform_has(CC_ATTR_HOST_SEV_SNP))
+ return;
+
rdmsr(MSR_AMD64_SYSCFG, lo, hi);
if (lo & K8_MTRRFIXRANGE_DRAM_MODIFY) {
pr_err(FW_WARN "MTRR: CPU %u: SYSCFG[MtrrFixDramModEn]"
diff --git a/arch/x86/kernel/cpu/rdrand.c b/arch/x86/kernel/cpu/rdrand.c
index 26a427fa84ea..eeac00d20926 100644
--- a/arch/x86/kernel/cpu/rdrand.c
+++ b/arch/x86/kernel/cpu/rdrand.c
@@ -6,6 +6,7 @@
* Authors: Fenghua Yu <fenghua.yu@intel.com>,
* H. Peter Anvin <hpa@linux.intel.com>
*/
+#include <linux/printk.h>
#include <asm/processor.h>
#include <asm/archrandom.h>
diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c
index 19e0681f0435..83e40341583e 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -16,6 +16,7 @@
#define pr_fmt(fmt) "resctrl: " fmt
+#include <linux/cpu.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/cacheinfo.h>
@@ -25,8 +26,15 @@
#include <asm/resctrl.h>
#include "internal.h"
-/* Mutex to protect rdtgroup access. */
-DEFINE_MUTEX(rdtgroup_mutex);
+/*
+ * rdt_domain structures are kfree()d when their last CPU goes offline,
+ * and allocated when the first CPU in a new domain comes online.
+ * The rdt_resource's domain list is updated when this happens. Readers of
+ * the domain list must either take cpus_read_lock(), or rely on an RCU
+ * read-side critical section, to avoid observing concurrent modification.
+ * All writers take this mutex:
+ */
+static DEFINE_MUTEX(domain_list_lock);
/*
* The cached resctrl_pqr_state is strictly per CPU and can never be
@@ -136,15 +144,15 @@ static inline void cache_alloc_hsw_probe(void)
{
struct rdt_hw_resource *hw_res = &rdt_resources_all[RDT_RESOURCE_L3];
struct rdt_resource *r = &hw_res->r_resctrl;
- u32 l, h, max_cbm = BIT_MASK(20) - 1;
+ u64 max_cbm = BIT_ULL_MASK(20) - 1, l3_cbm_0;
- if (wrmsr_safe(MSR_IA32_L3_CBM_BASE, max_cbm, 0))
+ if (wrmsrl_safe(MSR_IA32_L3_CBM_BASE, max_cbm))
return;
- rdmsr(MSR_IA32_L3_CBM_BASE, l, h);
+ rdmsrl(MSR_IA32_L3_CBM_BASE, l3_cbm_0);
/* If all the bits were set in MSR, return success */
- if (l != max_cbm)
+ if (l3_cbm_0 != max_cbm)
return;
hw_res->num_closid = 4;
@@ -231,9 +239,7 @@ static bool __get_mem_config_intel(struct rdt_resource *r)
static bool __rdt_get_mem_config_amd(struct rdt_resource *r)
{
struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
- union cpuid_0x10_3_eax eax;
- union cpuid_0x10_x_edx edx;
- u32 ebx, ecx, subleaf;
+ u32 eax, ebx, ecx, edx, subleaf;
/*
* Query CPUID_Fn80000020_EDX_x01 for MBA and
@@ -241,9 +247,9 @@ static bool __rdt_get_mem_config_amd(struct rdt_resource *r)
*/
subleaf = (r->rid == RDT_RESOURCE_SMBA) ? 2 : 1;
- cpuid_count(0x80000020, subleaf, &eax.full, &ebx, &ecx, &edx.full);
- hw_res->num_closid = edx.split.cos_max + 1;
- r->default_ctrl = MAX_MBA_BW_AMD;
+ cpuid_count(0x80000020, subleaf, &eax, &ebx, &ecx, &edx);
+ hw_res->num_closid = edx + 1;
+ r->default_ctrl = 1 << eax;
/* AMD does not use delay */
r->membw.delay_linear = false;
@@ -512,6 +518,8 @@ static void domain_add_cpu(int cpu, struct rdt_resource *r)
struct rdt_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);
@@ -545,11 +553,12 @@ static void domain_add_cpu(int cpu, struct rdt_resource *r)
return;
}
- list_add_tail(&d->list, add_pos);
+ list_add_tail_rcu(&d->list, add_pos);
err = resctrl_online_domain(r, d);
if (err) {
- list_del(&d->list);
+ list_del_rcu(&d->list);
+ synchronize_rcu();
domain_free(hw_dom);
}
}
@@ -560,6 +569,8 @@ static void domain_remove_cpu(int cpu, struct rdt_resource *r)
struct rdt_hw_domain *hw_dom;
struct rdt_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);
@@ -570,7 +581,8 @@ static void domain_remove_cpu(int cpu, struct rdt_resource *r)
cpumask_clear_cpu(cpu, &d->cpu_mask);
if (cpumask_empty(&d->cpu_mask)) {
resctrl_offline_domain(r, d);
- list_del(&d->list);
+ list_del_rcu(&d->list);
+ synchronize_rcu();
/*
* rdt_domain "d" is going to be freed below, so clear
@@ -582,73 +594,47 @@ static void domain_remove_cpu(int cpu, struct rdt_resource *r)
return;
}
-
- if (r == &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl) {
- if (is_mbm_enabled() && cpu == d->mbm_work_cpu) {
- cancel_delayed_work(&d->mbm_over);
- mbm_setup_overflow_handler(d, 0);
- }
- if (is_llc_occupancy_enabled() && cpu == d->cqm_work_cpu &&
- has_busy_rmid(r, d)) {
- cancel_delayed_work(&d->cqm_limbo);
- cqm_setup_limbo_handler(d, 0);
- }
- }
}
static void clear_closid_rmid(int cpu)
{
struct resctrl_pqr_state *state = this_cpu_ptr(&pqr_state);
- state->default_closid = 0;
- state->default_rmid = 0;
- state->cur_closid = 0;
- state->cur_rmid = 0;
- wrmsr(MSR_IA32_PQR_ASSOC, 0, 0);
+ state->default_closid = RESCTRL_RESERVED_CLOSID;
+ state->default_rmid = RESCTRL_RESERVED_RMID;
+ state->cur_closid = RESCTRL_RESERVED_CLOSID;
+ state->cur_rmid = RESCTRL_RESERVED_RMID;
+ wrmsr(MSR_IA32_PQR_ASSOC, RESCTRL_RESERVED_RMID,
+ RESCTRL_RESERVED_CLOSID);
}
-static int resctrl_online_cpu(unsigned int cpu)
+static int resctrl_arch_online_cpu(unsigned int cpu)
{
struct rdt_resource *r;
- mutex_lock(&rdtgroup_mutex);
+ mutex_lock(&domain_list_lock);
for_each_capable_rdt_resource(r)
domain_add_cpu(cpu, r);
- /* The cpu is set in default rdtgroup after online. */
- cpumask_set_cpu(cpu, &rdtgroup_default.cpu_mask);
+ mutex_unlock(&domain_list_lock);
+
clear_closid_rmid(cpu);
- mutex_unlock(&rdtgroup_mutex);
+ resctrl_online_cpu(cpu);
return 0;
}
-static void clear_childcpus(struct rdtgroup *r, unsigned int cpu)
-{
- struct rdtgroup *cr;
-
- list_for_each_entry(cr, &r->mon.crdtgrp_list, mon.crdtgrp_list) {
- if (cpumask_test_and_clear_cpu(cpu, &cr->cpu_mask)) {
- break;
- }
- }
-}
-
-static int resctrl_offline_cpu(unsigned int cpu)
+static int resctrl_arch_offline_cpu(unsigned int cpu)
{
- struct rdtgroup *rdtgrp;
struct rdt_resource *r;
- mutex_lock(&rdtgroup_mutex);
+ resctrl_offline_cpu(cpu);
+
+ mutex_lock(&domain_list_lock);
for_each_capable_rdt_resource(r)
domain_remove_cpu(cpu, r);
- list_for_each_entry(rdtgrp, &rdt_all_groups, rdtgroup_list) {
- if (cpumask_test_and_clear_cpu(cpu, &rdtgrp->cpu_mask)) {
- clear_childcpus(rdtgrp, cpu);
- break;
- }
- }
+ mutex_unlock(&domain_list_lock);
+
clear_closid_rmid(cpu);
- mutex_unlock(&rdtgroup_mutex);
return 0;
}
@@ -968,7 +954,8 @@ static int __init resctrl_late_init(void)
state = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
"x86/resctrl/cat:online:",
- resctrl_online_cpu, resctrl_offline_cpu);
+ resctrl_arch_online_cpu,
+ resctrl_arch_offline_cpu);
if (state < 0)
return state;
@@ -992,8 +979,14 @@ late_initcall(resctrl_late_init);
static void __exit resctrl_exit(void)
{
+ struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
+
cpuhp_remove_state(rdt_online);
+
rdtgroup_exit();
+
+ if (r->mon_capable)
+ rdt_put_mon_l3_config();
}
__exitcall(resctrl_exit);
diff --git a/arch/x86/kernel/cpu/resctrl/ctrlmondata.c b/arch/x86/kernel/cpu/resctrl/ctrlmondata.c
index beccb0e87ba7..7997b47743a2 100644
--- a/arch/x86/kernel/cpu/resctrl/ctrlmondata.c
+++ b/arch/x86/kernel/cpu/resctrl/ctrlmondata.c
@@ -19,6 +19,8 @@
#include <linux/kernfs.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
+#include <linux/tick.h>
+
#include "internal.h"
/*
@@ -210,6 +212,9 @@ static int parse_line(char *line, struct resctrl_schema *s,
struct rdt_domain *d;
unsigned long dom_id;
+ /* Walking r->domains, ensure it can't race with cpuhp */
+ lockdep_assert_cpus_held();
+
if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP &&
(r->rid == RDT_RESOURCE_MBA || r->rid == RDT_RESOURCE_SMBA)) {
rdt_last_cmd_puts("Cannot pseudo-lock MBA resource\n");
@@ -314,6 +319,9 @@ int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid)
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;
@@ -379,11 +387,9 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
return -EINVAL;
buf[nbytes - 1] = '\0';
- cpus_read_lock();
rdtgrp = rdtgroup_kn_lock_live(of->kn);
if (!rdtgrp) {
rdtgroup_kn_unlock(of->kn);
- cpus_read_unlock();
return -ENOENT;
}
rdt_last_cmd_clear();
@@ -445,7 +451,6 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
out:
rdt_staged_configs_clear();
rdtgroup_kn_unlock(of->kn);
- cpus_read_unlock();
return ret ?: nbytes;
}
@@ -465,6 +470,9 @@ static void show_doms(struct seq_file *s, struct resctrl_schema *schema, int clo
bool sep = false;
u32 ctrl_val;
+ /* Walking r->domains, ensure it can't race with cpuhp */
+ lockdep_assert_cpus_held();
+
seq_printf(s, "%*s:", max_name_width, schema->name);
list_for_each_entry(dom, &r->domains, list) {
if (sep)
@@ -522,12 +530,24 @@ int rdtgroup_schemata_show(struct kernfs_open_file *of,
return ret;
}
+static int smp_mon_event_count(void *arg)
+{
+ mon_event_count(arg);
+
+ return 0;
+}
+
void mon_event_read(struct rmid_read *rr, struct rdt_resource *r,
struct rdt_domain *d, struct rdtgroup *rdtgrp,
int evtid, int first)
{
+ int cpu;
+
+ /* When picking a CPU from cpu_mask, ensure it can't race with cpuhp */
+ lockdep_assert_cpus_held();
+
/*
- * setup the parameters to send to the IPI to read the data.
+ * Setup the parameters to pass to mon_event_count() to read the data.
*/
rr->rgrp = rdtgrp;
rr->evtid = evtid;
@@ -535,8 +555,26 @@ void mon_event_read(struct rmid_read *rr, struct rdt_resource *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)) {
+ rr->err = -EINVAL;
+ return;
+ }
+
+ cpu = cpumask_any_housekeeping(&d->cpu_mask, RESCTRL_PICK_ANY_CPU);
+
+ /*
+ * cpumask_any_housekeeping() prefers housekeeping CPUs, but
+ * are all the CPUs nohz_full? If yes, pick a CPU to IPI.
+ * MPAM's resctrl_arch_rmid_read() is unable to read the
+ * 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);
+ else
+ smp_call_on_cpu(cpu, smp_mon_event_count, rr, false);
- smp_call_function_any(&d->cpu_mask, mon_event_count, rr, 1);
+ resctrl_arch_mon_ctx_free(r, evtid, rr->arch_mon_ctx);
}
int rdtgroup_mondata_show(struct seq_file *m, void *arg)
diff --git a/arch/x86/kernel/cpu/resctrl/internal.h b/arch/x86/kernel/cpu/resctrl/internal.h
index a4f1aa15f0a2..1a8687f8073a 100644
--- a/arch/x86/kernel/cpu/resctrl/internal.h
+++ b/arch/x86/kernel/cpu/resctrl/internal.h
@@ -7,6 +7,9 @@
#include <linux/kernfs.h>
#include <linux/fs_context.h>
#include <linux/jump_label.h>
+#include <linux/tick.h>
+
+#include <asm/resctrl.h>
#define L3_QOS_CDP_ENABLE 0x01ULL
@@ -18,7 +21,6 @@
#define MBM_OVERFLOW_INTERVAL 1000
#define MAX_MBA_BW 100u
#define MBA_IS_LINEAR 0x4
-#define MAX_MBA_BW_AMD 0x800
#define MBM_CNTR_WIDTH_OFFSET_AMD 20
#define RMID_VAL_ERROR BIT_ULL(63)
@@ -54,6 +56,47 @@
/* Max event bits supported */
#define MAX_EVT_CONFIG_BITS GENMASK(6, 0)
+/**
+ * cpumask_any_housekeeping() - Choose any CPU in @mask, preferring those that
+ * aren't marked nohz_full
+ * @mask: The mask to pick a CPU from.
+ * @exclude_cpu:The CPU to avoid picking.
+ *
+ * Returns a CPU from @mask, but not @exclude_cpu. If there are housekeeping
+ * CPUs that don't use nohz_full, these are preferred. Pass
+ * RESCTRL_PICK_ANY_CPU to avoid excluding any CPUs.
+ *
+ * When a CPU is excluded, returns >= nr_cpu_ids if no CPUs are available.
+ */
+static inline unsigned int
+cpumask_any_housekeeping(const struct cpumask *mask, int exclude_cpu)
+{
+ unsigned int cpu, hk_cpu;
+
+ if (exclude_cpu == RESCTRL_PICK_ANY_CPU)
+ cpu = cpumask_any(mask);
+ else
+ cpu = cpumask_any_but(mask, exclude_cpu);
+
+ /* Only continue if tick_nohz_full_mask has been initialized. */
+ if (!tick_nohz_full_enabled())
+ return cpu;
+
+ /* If the CPU picked isn't marked nohz_full nothing more needs doing. */
+ if (cpu < nr_cpu_ids && !tick_nohz_full_cpu(cpu))
+ return cpu;
+
+ /* Try to find a CPU that isn't nohz_full to use in preference */
+ hk_cpu = cpumask_nth_andnot(0, mask, tick_nohz_full_mask);
+ if (hk_cpu == exclude_cpu)
+ hk_cpu = cpumask_nth_andnot(1, mask, tick_nohz_full_mask);
+
+ if (hk_cpu < nr_cpu_ids)
+ cpu = hk_cpu;
+
+ return cpu;
+}
+
struct rdt_fs_context {
struct kernfs_fs_context kfc;
bool enable_cdpl2;
@@ -69,9 +112,6 @@ static inline struct rdt_fs_context *rdt_fc2context(struct fs_context *fc)
return container_of(kfc, struct rdt_fs_context, kfc);
}
-DECLARE_STATIC_KEY_FALSE(rdt_enable_key);
-DECLARE_STATIC_KEY_FALSE(rdt_mon_enable_key);
-
/**
* struct mon_evt - Entry in the event list of a resource
* @evtid: event id
@@ -112,12 +152,12 @@ struct rmid_read {
bool first;
int err;
u64 val;
+ void *arch_mon_ctx;
};
-extern bool rdt_alloc_capable;
-extern bool rdt_mon_capable;
extern unsigned int rdt_mon_features;
extern struct list_head resctrl_schema_all;
+extern bool resctrl_mounted;
enum rdt_group_type {
RDTCTRL_GROUP = 0,
@@ -296,14 +336,10 @@ struct rftype {
* struct mbm_state - status for each MBM counter in each domain
* @prev_bw_bytes: Previous bytes value read for bandwidth calculation
* @prev_bw: The most recent bandwidth in MBps
- * @delta_bw: Difference between the current and previous bandwidth
- * @delta_comp: Indicates whether to compute the delta_bw
*/
struct mbm_state {
u64 prev_bw_bytes;
u32 prev_bw;
- u32 delta_bw;
- bool delta_comp;
};
/**
@@ -395,6 +431,8 @@ struct rdt_parse_data {
* @msr_update: Function pointer to update QOS MSRs
* @mon_scale: cqm counter * mon_scale = occupancy in bytes
* @mbm_width: Monitor width, to detect and correct for overflow.
+ * @mbm_cfg_mask: Bandwidth sources that can be tracked when Bandwidth
+ * Monitoring Event Configuration (BMEC) is supported.
* @cdp_enabled: CDP state of this resource
*
* Members of this structure are either private to the architecture
@@ -409,6 +447,7 @@ struct rdt_hw_resource {
struct rdt_resource *r);
unsigned int mon_scale;
unsigned int mbm_width;
+ unsigned int mbm_cfg_mask;
bool cdp_enabled;
};
@@ -426,8 +465,6 @@ extern struct mutex rdtgroup_mutex;
extern struct rdt_hw_resource rdt_resources_all[];
extern struct rdtgroup rdtgroup_default;
-DECLARE_STATIC_KEY_FALSE(rdt_alloc_enable_key);
-
extern struct dentry *debugfs_resctrl;
enum resctrl_res_level {
@@ -543,9 +580,10 @@ void rdtgroup_pseudo_lock_remove(struct rdtgroup *rdtgrp);
struct rdt_domain *get_domain_from_cpu(int cpu, struct rdt_resource *r);
int closids_supported(void);
void closid_free(int closid);
-int alloc_rmid(void);
-void free_rmid(u32 rmid);
+int alloc_rmid(u32 closid);
+void free_rmid(u32 closid, u32 rmid);
int rdt_get_mon_l3_config(struct rdt_resource *r);
+void __exit rdt_put_mon_l3_config(void);
bool __init rdt_cpu_has(int flag);
void mon_event_count(void *info);
int rdtgroup_mondata_show(struct seq_file *m, void *arg);
@@ -553,17 +591,21 @@ 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,
- unsigned long delay_ms);
+ 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_domain *dom, unsigned long delay_ms,
+ int exclude_cpu);
void cqm_handle_limbo(struct work_struct *work);
-bool has_busy_rmid(struct rdt_resource *r, struct rdt_domain *d);
+bool has_busy_rmid(struct rdt_domain *d);
void __check_limbo(struct rdt_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);
void rdt_staged_configs_clear(void);
+bool closid_allocated(unsigned int closid);
+int resctrl_find_cleanest_closid(void);
#endif /* _ASM_X86_RESCTRL_INTERNAL_H */
diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c
index f136ac046851..c34a35ec0f03 100644
--- a/arch/x86/kernel/cpu/resctrl/monitor.c
+++ b/arch/x86/kernel/cpu/resctrl/monitor.c
@@ -15,6 +15,7 @@
* Software Developer Manual June 2016, volume 3, section 17.17.
*/
+#include <linux/cpu.h>
#include <linux/module.h>
#include <linux/sizes.h>
#include <linux/slab.h>
@@ -24,7 +25,20 @@
#include "internal.h"
+/**
+ * struct rmid_entry - dirty tracking for all RMID.
+ * @closid: The CLOSID for this entry.
+ * @rmid: The RMID for this entry.
+ * @busy: The number of domains with cached data using this RMID.
+ * @list: Member of the rmid_free_lru list when busy == 0.
+ *
+ * Depending on the architecture the correct monitor is accessed using
+ * both @closid and @rmid, or @rmid only.
+ *
+ * Take the rdtgroup_mutex when accessing.
+ */
struct rmid_entry {
+ u32 closid;
u32 rmid;
int busy;
struct list_head list;
@@ -38,6 +52,13 @@ struct rmid_entry {
static LIST_HEAD(rmid_free_lru);
/*
+ * @closid_num_dirty_rmid The number of dirty RMID each CLOSID has.
+ * Only allocated when CONFIG_RESCTRL_RMID_DEPENDS_ON_CLOSID is defined.
+ * Indexed by CLOSID. Protected by rdtgroup_mutex.
+ */
+static u32 *closid_num_dirty_rmid;
+
+/*
* @rmid_limbo_count - count of currently unused but (potentially)
* dirty RMIDs.
* This counts RMIDs that no one is currently using but that
@@ -136,12 +157,29 @@ static inline u64 get_corrected_mbm_count(u32 rmid, unsigned long val)
return val;
}
-static inline struct rmid_entry *__rmid_entry(u32 rmid)
+/*
+ * x86 and arm64 differ in their handling of monitoring.
+ * x86's RMID are independent numbers, there is only one source of traffic
+ * with an RMID value of '1'.
+ * arm64's PMG extends the PARTID/CLOSID space, there are multiple sources of
+ * traffic with a PMG value of '1', one for each CLOSID, meaning the RMID
+ * value is no longer unique.
+ * To account for this, resctrl uses an index. On x86 this is just the RMID,
+ * on arm64 it encodes the CLOSID and RMID. This gives a unique number.
+ *
+ * The domain's rmid_busy_llc and rmid_ptrs[] are sized by index. The arch code
+ * must accept an attempt to read every index.
+ */
+static inline struct rmid_entry *__rmid_entry(u32 idx)
{
struct rmid_entry *entry;
+ u32 closid, rmid;
+
+ entry = &rmid_ptrs[idx];
+ resctrl_arch_rmid_idx_decode(idx, &closid, &rmid);
- entry = &rmid_ptrs[rmid];
- WARN_ON(entry->rmid != rmid);
+ WARN_ON_ONCE(entry->closid != closid);
+ WARN_ON_ONCE(entry->rmid != rmid);
return entry;
}
@@ -190,7 +228,8 @@ static struct arch_mbm_state *get_arch_mbm_state(struct rdt_hw_domain *hw_dom,
}
void resctrl_arch_reset_rmid(struct rdt_resource *r, struct rdt_domain *d,
- u32 rmid, enum resctrl_event_id eventid)
+ u32 unused, u32 rmid,
+ enum resctrl_event_id eventid)
{
struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);
struct arch_mbm_state *am;
@@ -230,7 +269,8 @@ static u64 mbm_overflow_count(u64 prev_msr, u64 cur_msr, unsigned int width)
}
int resctrl_arch_rmid_read(struct rdt_resource *r, struct rdt_domain *d,
- u32 rmid, enum resctrl_event_id eventid, u64 *val)
+ u32 unused, u32 rmid, enum resctrl_event_id eventid,
+ u64 *val, void *ignored)
{
struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);
@@ -238,6 +278,8 @@ int resctrl_arch_rmid_read(struct rdt_resource *r, struct rdt_domain *d,
u64 msr_val, chunks;
int ret;
+ resctrl_arch_rmid_read_context_check();
+
if (!cpumask_test_cpu(smp_processor_id(), &d->cpu_mask))
return -EINVAL;
@@ -260,6 +302,17 @@ int resctrl_arch_rmid_read(struct rdt_resource *r, struct rdt_domain *d,
return 0;
}
+static void limbo_release_entry(struct rmid_entry *entry)
+{
+ lockdep_assert_held(&rdtgroup_mutex);
+
+ rmid_limbo_count--;
+ list_add_tail(&entry->list, &rmid_free_lru);
+
+ if (IS_ENABLED(CONFIG_RESCTRL_RMID_DEPENDS_ON_CLOSID))
+ closid_num_dirty_rmid[entry->closid]--;
+}
+
/*
* Check the RMIDs that are marked as busy for this domain. If the
* reported LLC occupancy is below the threshold clear the busy bit and
@@ -269,11 +322,20 @@ int resctrl_arch_rmid_read(struct rdt_resource *r, struct rdt_domain *d,
void __check_limbo(struct rdt_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();
struct rmid_entry *entry;
- u32 crmid = 1, nrmid;
+ u32 idx, cur_idx = 1;
+ void *arch_mon_ctx;
bool rmid_dirty;
u64 val = 0;
+ arch_mon_ctx = resctrl_arch_mon_ctx_alloc(r, QOS_L3_OCCUP_EVENT_ID);
+ if (IS_ERR(arch_mon_ctx)) {
+ pr_warn_ratelimited("Failed to allocate monitor context: %ld",
+ PTR_ERR(arch_mon_ctx));
+ return;
+ }
+
/*
* Skip RMID 0 and start from RMID 1 and check all the RMIDs that
* are marked as busy for occupancy < threshold. If the occupancy
@@ -281,53 +343,125 @@ void __check_limbo(struct rdt_domain *d, bool force_free)
* RMID and move it to the free list when the counter reaches 0.
*/
for (;;) {
- nrmid = find_next_bit(d->rmid_busy_llc, r->num_rmid, crmid);
- if (nrmid >= r->num_rmid)
+ idx = find_next_bit(d->rmid_busy_llc, idx_limit, cur_idx);
+ if (idx >= idx_limit)
break;
- entry = __rmid_entry(nrmid);
-
- if (resctrl_arch_rmid_read(r, d, entry->rmid,
- QOS_L3_OCCUP_EVENT_ID, &val)) {
+ entry = __rmid_entry(idx);
+ if (resctrl_arch_rmid_read(r, d, entry->closid, entry->rmid,
+ QOS_L3_OCCUP_EVENT_ID, &val,
+ arch_mon_ctx)) {
rmid_dirty = true;
} else {
rmid_dirty = (val >= resctrl_rmid_realloc_threshold);
}
if (force_free || !rmid_dirty) {
- clear_bit(entry->rmid, d->rmid_busy_llc);
- if (!--entry->busy) {
- rmid_limbo_count--;
- list_add_tail(&entry->list, &rmid_free_lru);
- }
+ clear_bit(idx, d->rmid_busy_llc);
+ if (!--entry->busy)
+ limbo_release_entry(entry);
}
- crmid = nrmid + 1;
+ cur_idx = idx + 1;
}
+
+ resctrl_arch_mon_ctx_free(r, QOS_L3_OCCUP_EVENT_ID, arch_mon_ctx);
}
-bool has_busy_rmid(struct rdt_resource *r, struct rdt_domain *d)
+bool has_busy_rmid(struct rdt_domain *d)
{
- return find_first_bit(d->rmid_busy_llc, r->num_rmid) != r->num_rmid;
+ u32 idx_limit = resctrl_arch_system_num_rmid_idx();
+
+ return find_first_bit(d->rmid_busy_llc, idx_limit) != idx_limit;
+}
+
+static struct rmid_entry *resctrl_find_free_rmid(u32 closid)
+{
+ struct rmid_entry *itr;
+ u32 itr_idx, cmp_idx;
+
+ if (list_empty(&rmid_free_lru))
+ return rmid_limbo_count ? ERR_PTR(-EBUSY) : ERR_PTR(-ENOSPC);
+
+ list_for_each_entry(itr, &rmid_free_lru, list) {
+ /*
+ * Get the index of this free RMID, and the index it would need
+ * to be if it were used with this CLOSID.
+ * If the CLOSID is irrelevant on this architecture, the two
+ * index values are always the same on every entry and thus the
+ * very first entry will be returned.
+ */
+ itr_idx = resctrl_arch_rmid_idx_encode(itr->closid, itr->rmid);
+ cmp_idx = resctrl_arch_rmid_idx_encode(closid, itr->rmid);
+
+ if (itr_idx == cmp_idx)
+ return itr;
+ }
+
+ return ERR_PTR(-ENOSPC);
+}
+
+/**
+ * resctrl_find_cleanest_closid() - Find a CLOSID where all the associated
+ * RMID are clean, or the CLOSID that has
+ * the most clean RMID.
+ *
+ * MPAM's equivalent of RMID are per-CLOSID, meaning a freshly allocated CLOSID
+ * may not be able to allocate clean RMID. To avoid this the allocator will
+ * choose the CLOSID with the most clean RMID.
+ *
+ * When the CLOSID and RMID are independent numbers, the first free CLOSID will
+ * be returned.
+ */
+int resctrl_find_cleanest_closid(void)
+{
+ u32 cleanest_closid = ~0;
+ int i = 0;
+
+ lockdep_assert_held(&rdtgroup_mutex);
+
+ if (!IS_ENABLED(CONFIG_RESCTRL_RMID_DEPENDS_ON_CLOSID))
+ return -EIO;
+
+ for (i = 0; i < closids_supported(); i++) {
+ int num_dirty;
+
+ if (closid_allocated(i))
+ continue;
+
+ num_dirty = closid_num_dirty_rmid[i];
+ if (num_dirty == 0)
+ return i;
+
+ if (cleanest_closid == ~0)
+ cleanest_closid = i;
+
+ if (num_dirty < closid_num_dirty_rmid[cleanest_closid])
+ cleanest_closid = i;
+ }
+
+ if (cleanest_closid == ~0)
+ return -ENOSPC;
+
+ return cleanest_closid;
}
/*
- * As of now the RMIDs allocation is global.
- * However we keep track of which packages the RMIDs
- * are used to optimize the limbo list management.
+ * For MPAM the RMID value is not unique, and has to be considered with
+ * the CLOSID. The (CLOSID, RMID) pair is allocated on all domains, which
+ * allows all domains to be managed by a single free list.
+ * Each domain also has a rmid_busy_llc to reduce the work of the limbo handler.
*/
-int alloc_rmid(void)
+int alloc_rmid(u32 closid)
{
struct rmid_entry *entry;
lockdep_assert_held(&rdtgroup_mutex);
- if (list_empty(&rmid_free_lru))
- return rmid_limbo_count ? -EBUSY : -ENOSPC;
+ entry = resctrl_find_free_rmid(closid);
+ if (IS_ERR(entry))
+ return PTR_ERR(entry);
- entry = list_first_entry(&rmid_free_lru,
- struct rmid_entry, list);
list_del(&entry->list);
-
return entry->rmid;
}
@@ -335,47 +469,50 @@ 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;
- int cpu, err;
- u64 val = 0;
+ u32 idx;
+
+ lockdep_assert_held(&rdtgroup_mutex);
+
+ /* Walking r->domains, ensure it can't race with cpuhp */
+ lockdep_assert_cpus_held();
+
+ idx = resctrl_arch_rmid_idx_encode(entry->closid, entry->rmid);
entry->busy = 0;
- cpu = get_cpu();
list_for_each_entry(d, &r->domains, list) {
- if (cpumask_test_cpu(cpu, &d->cpu_mask)) {
- err = resctrl_arch_rmid_read(r, d, entry->rmid,
- QOS_L3_OCCUP_EVENT_ID,
- &val);
- if (err || val <= resctrl_rmid_realloc_threshold)
- continue;
- }
-
/*
* For the first limbo RMID in the domain,
* setup up the limbo worker.
*/
- if (!has_busy_rmid(r, d))
- cqm_setup_limbo_handler(d, CQM_LIMBOCHECK_INTERVAL);
- set_bit(entry->rmid, d->rmid_busy_llc);
+ if (!has_busy_rmid(d))
+ cqm_setup_limbo_handler(d, CQM_LIMBOCHECK_INTERVAL,
+ RESCTRL_PICK_ANY_CPU);
+ set_bit(idx, d->rmid_busy_llc);
entry->busy++;
}
- put_cpu();
- if (entry->busy)
- rmid_limbo_count++;
- else
- list_add_tail(&entry->list, &rmid_free_lru);
+ rmid_limbo_count++;
+ if (IS_ENABLED(CONFIG_RESCTRL_RMID_DEPENDS_ON_CLOSID))
+ closid_num_dirty_rmid[entry->closid]++;
}
-void free_rmid(u32 rmid)
+void free_rmid(u32 closid, u32 rmid)
{
+ u32 idx = resctrl_arch_rmid_idx_encode(closid, rmid);
struct rmid_entry *entry;
- if (!rmid)
- return;
-
lockdep_assert_held(&rdtgroup_mutex);
- entry = __rmid_entry(rmid);
+ /*
+ * Do not allow the default rmid to be free'd. Comparing by index
+ * allows architectures that ignore the closid parameter to avoid an
+ * unnecessary check.
+ */
+ if (idx == resctrl_arch_rmid_idx_encode(RESCTRL_RESERVED_CLOSID,
+ RESCTRL_RESERVED_RMID))
+ return;
+
+ entry = __rmid_entry(idx);
if (is_llc_occupancy_enabled())
add_rmid_to_limbo(entry);
@@ -383,33 +520,36 @@ void free_rmid(u32 rmid)
list_add_tail(&entry->list, &rmid_free_lru);
}
-static struct mbm_state *get_mbm_state(struct rdt_domain *d, u32 rmid,
- enum resctrl_event_id evtid)
+static struct mbm_state *get_mbm_state(struct rdt_domain *d, u32 closid,
+ u32 rmid, enum resctrl_event_id evtid)
{
+ u32 idx = resctrl_arch_rmid_idx_encode(closid, rmid);
+
switch (evtid) {
case QOS_L3_MBM_TOTAL_EVENT_ID:
- return &d->mbm_total[rmid];
+ return &d->mbm_total[idx];
case QOS_L3_MBM_LOCAL_EVENT_ID:
- return &d->mbm_local[rmid];
+ return &d->mbm_local[idx];
default:
return NULL;
}
}
-static int __mon_event_count(u32 rmid, struct rmid_read *rr)
+static int __mon_event_count(u32 closid, u32 rmid, struct rmid_read *rr)
{
struct mbm_state *m;
u64 tval = 0;
if (rr->first) {
- resctrl_arch_reset_rmid(rr->r, rr->d, rmid, rr->evtid);
- m = get_mbm_state(rr->d, rmid, rr->evtid);
+ resctrl_arch_reset_rmid(rr->r, rr->d, closid, rmid, rr->evtid);
+ m = get_mbm_state(rr->d, closid, rmid, rr->evtid);
if (m)
memset(m, 0, sizeof(struct mbm_state));
return 0;
}
- rr->err = resctrl_arch_rmid_read(rr->r, rr->d, rmid, rr->evtid, &tval);
+ 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;
@@ -421,6 +561,7 @@ static int __mon_event_count(u32 rmid, struct rmid_read *rr)
/*
* mbm_bw_count() - Update bw count from values previously read by
* __mon_event_count().
+ * @closid: The closid used to identify the cached mbm_state.
* @rmid: The rmid used to identify the cached mbm_state.
* @rr: The struct rmid_read populated by __mon_event_count().
*
@@ -429,9 +570,10 @@ static int __mon_event_count(u32 rmid, struct rmid_read *rr)
* __mon_event_count() is compared with the chunks value from the previous
* invocation. This must be called once per second to maintain values in MBps.
*/
-static void mbm_bw_count(u32 rmid, struct rmid_read *rr)
+static void mbm_bw_count(u32 closid, u32 rmid, struct rmid_read *rr)
{
- struct mbm_state *m = &rr->d->mbm_local[rmid];
+ u32 idx = resctrl_arch_rmid_idx_encode(closid, rmid);
+ struct mbm_state *m = &rr->d->mbm_local[idx];
u64 cur_bw, bytes, cur_bytes;
cur_bytes = rr->val;
@@ -440,14 +582,11 @@ static void mbm_bw_count(u32 rmid, struct rmid_read *rr)
cur_bw = bytes / SZ_1M;
- if (m->delta_comp)
- m->delta_bw = abs(cur_bw - m->prev_bw);
- m->delta_comp = false;
m->prev_bw = cur_bw;
}
/*
- * This is called via IPI to read the CQM/MBM counters
+ * This is scheduled by mon_event_read() to read the CQM/MBM counters
* on a domain.
*/
void mon_event_count(void *info)
@@ -459,7 +598,7 @@ void mon_event_count(void *info)
rdtgrp = rr->rgrp;
- ret = __mon_event_count(rdtgrp->mon.rmid, rr);
+ ret = __mon_event_count(rdtgrp->closid, rdtgrp->mon.rmid, rr);
/*
* For Ctrl groups read data from child monitor groups and
@@ -470,7 +609,8 @@ void mon_event_count(void *info)
if (rdtgrp->type == RDTCTRL_GROUP) {
list_for_each_entry(entry, head, mon.crdtgrp_list) {
- if (__mon_event_count(entry->mon.rmid, rr) == 0)
+ if (__mon_event_count(entry->closid, entry->mon.rmid,
+ rr) == 0)
ret = 0;
}
}
@@ -520,9 +660,9 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm)
{
u32 closid, rmid, cur_msr_val, new_msr_val;
struct mbm_state *pmbm_data, *cmbm_data;
- u32 cur_bw, delta_bw, user_bw;
struct rdt_resource *r_mba;
struct rdt_domain *dom_mba;
+ u32 cur_bw, user_bw, idx;
struct list_head *head;
struct rdtgroup *entry;
@@ -533,7 +673,8 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm)
closid = rgrp->closid;
rmid = rgrp->mon.rmid;
- pmbm_data = &dom_mbm->mbm_local[rmid];
+ 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);
if (!dom_mba) {
@@ -543,7 +684,6 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm)
cur_bw = pmbm_data->prev_bw;
user_bw = dom_mba->mbps_val[closid];
- delta_bw = pmbm_data->delta_bw;
/* MBA resource doesn't support CDP */
cur_msr_val = resctrl_arch_get_config(r_mba, dom_mba, closid, CDP_NONE);
@@ -555,52 +695,35 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm)
list_for_each_entry(entry, head, mon.crdtgrp_list) {
cmbm_data = &dom_mbm->mbm_local[entry->mon.rmid];
cur_bw += cmbm_data->prev_bw;
- delta_bw += cmbm_data->delta_bw;
}
/*
* Scale up/down the bandwidth linearly for the ctrl group. The
* bandwidth step is the bandwidth granularity specified by the
* hardware.
- *
- * The delta_bw is used when increasing the bandwidth so that we
- * dont alternately increase and decrease the control values
- * continuously.
- *
- * For ex: consider cur_bw = 90MBps, user_bw = 100MBps and if
- * bandwidth step is 20MBps(> user_bw - cur_bw), we would keep
- * switching between 90 and 110 continuously if we only check
- * cur_bw < user_bw.
+ * Always increase throttling if current bandwidth is above the
+ * target set by user.
+ * But avoid thrashing up and down on every poll by checking
+ * whether a decrease in throttling is likely to push the group
+ * back over target. E.g. if currently throttling to 30% of bandwidth
+ * on a system with 10% granularity steps, check whether moving to
+ * 40% would go past the limit by multiplying current bandwidth by
+ * "(30 + 10) / 30".
*/
if (cur_msr_val > r_mba->membw.min_bw && user_bw < cur_bw) {
new_msr_val = cur_msr_val - r_mba->membw.bw_gran;
} else if (cur_msr_val < MAX_MBA_BW &&
- (user_bw > (cur_bw + delta_bw))) {
+ (user_bw > (cur_bw * (cur_msr_val + r_mba->membw.min_bw) / cur_msr_val))) {
new_msr_val = cur_msr_val + r_mba->membw.bw_gran;
} else {
return;
}
resctrl_arch_update_one(r_mba, dom_mba, closid, CDP_NONE, new_msr_val);
-
- /*
- * Delta values are updated dynamically package wise for each
- * rdtgrp every time the throttle MSR changes value.
- *
- * This is because (1)the increase in bandwidth is not perfectly
- * linear and only "approximately" linear even when the hardware
- * says it is linear.(2)Also since MBA is a core specific
- * mechanism, the delta values vary based on number of cores used
- * by the rdtgrp.
- */
- pmbm_data->delta_comp = true;
- list_for_each_entry(entry, head, mon.crdtgrp_list) {
- cmbm_data = &dom_mbm->mbm_local[entry->mon.rmid];
- cmbm_data->delta_comp = true;
- }
}
-static void mbm_update(struct rdt_resource *r, struct rdt_domain *d, int rmid)
+static void mbm_update(struct rdt_resource *r, struct rdt_domain *d,
+ u32 closid, u32 rmid)
{
struct rmid_read rr;
@@ -615,12 +738,28 @@ static void mbm_update(struct rdt_resource *r, struct rdt_domain *d, int rmid)
if (is_mbm_total_enabled()) {
rr.evtid = QOS_L3_MBM_TOTAL_EVENT_ID;
rr.val = 0;
- __mon_event_count(rmid, &rr);
+ rr.arch_mon_ctx = resctrl_arch_mon_ctx_alloc(rr.r, rr.evtid);
+ if (IS_ERR(rr.arch_mon_ctx)) {
+ pr_warn_ratelimited("Failed to allocate monitor context: %ld",
+ PTR_ERR(rr.arch_mon_ctx));
+ return;
+ }
+
+ __mon_event_count(closid, rmid, &rr);
+
+ resctrl_arch_mon_ctx_free(rr.r, rr.evtid, rr.arch_mon_ctx);
}
if (is_mbm_local_enabled()) {
rr.evtid = QOS_L3_MBM_LOCAL_EVENT_ID;
rr.val = 0;
- __mon_event_count(rmid, &rr);
+ rr.arch_mon_ctx = resctrl_arch_mon_ctx_alloc(rr.r, rr.evtid);
+ if (IS_ERR(rr.arch_mon_ctx)) {
+ pr_warn_ratelimited("Failed to allocate monitor context: %ld",
+ PTR_ERR(rr.arch_mon_ctx));
+ return;
+ }
+
+ __mon_event_count(closid, rmid, &rr);
/*
* Call the MBA software controller only for the
@@ -628,7 +767,9 @@ static void mbm_update(struct rdt_resource *r, struct rdt_domain *d, int rmid)
* the software controller explicitly.
*/
if (is_mba_sc(NULL))
- mbm_bw_count(rmid, &rr);
+ mbm_bw_count(closid, rmid, &rr);
+
+ resctrl_arch_mon_ctx_free(rr.r, rr.evtid, rr.arch_mon_ctx);
}
}
@@ -639,106 +780,193 @@ static void mbm_update(struct rdt_resource *r, struct rdt_domain *d, int rmid)
void cqm_handle_limbo(struct work_struct *work)
{
unsigned long delay = msecs_to_jiffies(CQM_LIMBOCHECK_INTERVAL);
- int cpu = smp_processor_id();
- struct rdt_resource *r;
struct rdt_domain *d;
+ cpus_read_lock();
mutex_lock(&rdtgroup_mutex);
- r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
d = container_of(work, struct rdt_domain, cqm_limbo.work);
__check_limbo(d, false);
- if (has_busy_rmid(r, d))
- schedule_delayed_work_on(cpu, &d->cqm_limbo, delay);
+ if (has_busy_rmid(d)) {
+ d->cqm_work_cpu = cpumask_any_housekeeping(&d->cpu_mask,
+ RESCTRL_PICK_ANY_CPU);
+ schedule_delayed_work_on(d->cqm_work_cpu, &d->cqm_limbo,
+ delay);
+ }
mutex_unlock(&rdtgroup_mutex);
+ cpus_read_unlock();
}
-void cqm_setup_limbo_handler(struct rdt_domain *dom, unsigned long delay_ms)
+/**
+ * cqm_setup_limbo_handler() - Schedule the limbo handler to run for this
+ * domain.
+ * @dom: The domain the limbo handler should run for.
+ * @delay_ms: How far in the future the handler should run.
+ * @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,
+ int exclude_cpu)
{
unsigned long delay = msecs_to_jiffies(delay_ms);
int cpu;
- cpu = cpumask_any(&dom->cpu_mask);
+ cpu = cpumask_any_housekeeping(&dom->cpu_mask, exclude_cpu);
dom->cqm_work_cpu = cpu;
- schedule_delayed_work_on(cpu, &dom->cqm_limbo, delay);
+ if (cpu < nr_cpu_ids)
+ schedule_delayed_work_on(cpu, &dom->cqm_limbo, delay);
}
void mbm_handle_overflow(struct work_struct *work)
{
unsigned long delay = msecs_to_jiffies(MBM_OVERFLOW_INTERVAL);
struct rdtgroup *prgrp, *crgrp;
- int cpu = smp_processor_id();
struct list_head *head;
struct rdt_resource *r;
struct rdt_domain *d;
+ cpus_read_lock();
mutex_lock(&rdtgroup_mutex);
- if (!static_branch_likely(&rdt_mon_enable_key))
+ /*
+ * If the filesystem has been unmounted this work no longer needs to
+ * run.
+ */
+ if (!resctrl_mounted || !resctrl_arch_mon_capable())
goto out_unlock;
r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
d = container_of(work, struct rdt_domain, mbm_over.work);
list_for_each_entry(prgrp, &rdt_all_groups, rdtgroup_list) {
- mbm_update(r, d, prgrp->mon.rmid);
+ mbm_update(r, d, prgrp->closid, prgrp->mon.rmid);
head = &prgrp->mon.crdtgrp_list;
list_for_each_entry(crgrp, head, mon.crdtgrp_list)
- mbm_update(r, d, crgrp->mon.rmid);
+ mbm_update(r, d, crgrp->closid, crgrp->mon.rmid);
if (is_mba_sc(NULL))
update_mba_bw(prgrp, d);
}
- schedule_delayed_work_on(cpu, &d->mbm_over, delay);
+ /*
+ * 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,
+ RESCTRL_PICK_ANY_CPU);
+ schedule_delayed_work_on(d->mbm_work_cpu, &d->mbm_over, delay);
out_unlock:
mutex_unlock(&rdtgroup_mutex);
+ cpus_read_unlock();
}
-void mbm_setup_overflow_handler(struct rdt_domain *dom, unsigned long delay_ms)
+/**
+ * mbm_setup_overflow_handler() - Schedule the overflow handler to run for this
+ * domain.
+ * @dom: The domain the overflow handler should run for.
+ * @delay_ms: How far in the future the handler should run.
+ * @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,
+ int exclude_cpu)
{
unsigned long delay = msecs_to_jiffies(delay_ms);
int cpu;
- if (!static_branch_likely(&rdt_mon_enable_key))
+ /*
+ * When a domain comes online there is no guarantee the filesystem is
+ * mounted. If not, there is no need to catch counter overflow.
+ */
+ if (!resctrl_mounted || !resctrl_arch_mon_capable())
return;
- cpu = cpumask_any(&dom->cpu_mask);
+ cpu = cpumask_any_housekeeping(&dom->cpu_mask, exclude_cpu);
dom->mbm_work_cpu = cpu;
- schedule_delayed_work_on(cpu, &dom->mbm_over, delay);
+
+ if (cpu < nr_cpu_ids)
+ schedule_delayed_work_on(cpu, &dom->mbm_over, delay);
}
static int dom_data_init(struct rdt_resource *r)
{
+ u32 idx_limit = resctrl_arch_system_num_rmid_idx();
+ u32 num_closid = resctrl_arch_get_num_closid(r);
struct rmid_entry *entry = NULL;
- int i, nr_rmids;
+ int err = 0, i;
+ u32 idx;
+
+ mutex_lock(&rdtgroup_mutex);
+ if (IS_ENABLED(CONFIG_RESCTRL_RMID_DEPENDS_ON_CLOSID)) {
+ u32 *tmp;
+
+ /*
+ * If the architecture hasn't provided a sanitised value here,
+ * this may result in larger arrays than necessary. Resctrl will
+ * use a smaller system wide value based on the resources in
+ * use.
+ */
+ tmp = kcalloc(num_closid, sizeof(*tmp), GFP_KERNEL);
+ if (!tmp) {
+ err = -ENOMEM;
+ goto out_unlock;
+ }
- nr_rmids = r->num_rmid;
- rmid_ptrs = kcalloc(nr_rmids, sizeof(struct rmid_entry), GFP_KERNEL);
- if (!rmid_ptrs)
- return -ENOMEM;
+ closid_num_dirty_rmid = tmp;
+ }
+
+ rmid_ptrs = kcalloc(idx_limit, sizeof(struct rmid_entry), GFP_KERNEL);
+ if (!rmid_ptrs) {
+ if (IS_ENABLED(CONFIG_RESCTRL_RMID_DEPENDS_ON_CLOSID)) {
+ kfree(closid_num_dirty_rmid);
+ closid_num_dirty_rmid = NULL;
+ }
+ err = -ENOMEM;
+ goto out_unlock;
+ }
- for (i = 0; i < nr_rmids; i++) {
+ for (i = 0; i < idx_limit; i++) {
entry = &rmid_ptrs[i];
INIT_LIST_HEAD(&entry->list);
- entry->rmid = i;
+ resctrl_arch_rmid_idx_decode(i, &entry->closid, &entry->rmid);
list_add_tail(&entry->list, &rmid_free_lru);
}
/*
- * RMID 0 is special and is always allocated. It's used for all
- * tasks that are not monitored.
+ * RESCTRL_RESERVED_CLOSID and RESCTRL_RESERVED_RMID are special and
+ * are always allocated. These are used for the rdtgroup_default
+ * control group, which will be setup later in rdtgroup_init().
*/
- entry = __rmid_entry(0);
+ idx = resctrl_arch_rmid_idx_encode(RESCTRL_RESERVED_CLOSID,
+ RESCTRL_RESERVED_RMID);
+ entry = __rmid_entry(idx);
list_del(&entry->list);
- return 0;
+out_unlock:
+ mutex_unlock(&rdtgroup_mutex);
+
+ return err;
+}
+
+static void __exit dom_data_exit(void)
+{
+ mutex_lock(&rdtgroup_mutex);
+
+ if (IS_ENABLED(CONFIG_RESCTRL_RMID_DEPENDS_ON_CLOSID)) {
+ kfree(closid_num_dirty_rmid);
+ closid_num_dirty_rmid = NULL;
+ }
+
+ kfree(rmid_ptrs);
+ rmid_ptrs = NULL;
+
+ mutex_unlock(&rdtgroup_mutex);
}
static struct mon_evt llc_occupancy_event = {
@@ -813,6 +1041,12 @@ int __init rdt_get_mon_l3_config(struct rdt_resource *r)
return ret;
if (rdt_cpu_has(X86_FEATURE_BMEC)) {
+ u32 eax, ebx, ecx, edx;
+
+ /* Detect list of bandwidth sources that can be tracked */
+ cpuid_count(0x80000020, 3, &eax, &ebx, &ecx, &edx);
+ hw_res->mbm_cfg_mask = ecx & MAX_EVT_CONFIG_BITS;
+
if (rdt_cpu_has(X86_FEATURE_CQM_MBM_TOTAL)) {
mbm_total_event.configurable = true;
mbm_config_rftype_init("mbm_total_bytes_config");
@@ -830,6 +1064,11 @@ int __init rdt_get_mon_l3_config(struct rdt_resource *r)
return 0;
}
+void __exit rdt_put_mon_l3_config(void)
+{
+ dom_data_exit();
+}
+
void __init intel_rdt_mbm_apply_quirk(void)
{
int cf_index;
diff --git a/arch/x86/kernel/cpu/resctrl/pseudo_lock.c b/arch/x86/kernel/cpu/resctrl/pseudo_lock.c
index 8f559eeae08e..884b88e25141 100644
--- a/arch/x86/kernel/cpu/resctrl/pseudo_lock.c
+++ b/arch/x86/kernel/cpu/resctrl/pseudo_lock.c
@@ -581,7 +581,7 @@ static int rdtgroup_locksetup_user_restrict(struct rdtgroup *rdtgrp)
if (ret)
goto err_cpus;
- if (rdt_mon_capable) {
+ if (resctrl_arch_mon_capable()) {
ret = rdtgroup_kn_mode_restrict(rdtgrp, "mon_groups");
if (ret)
goto err_cpus_list;
@@ -628,7 +628,7 @@ static int rdtgroup_locksetup_user_restore(struct rdtgroup *rdtgrp)
if (ret)
goto err_cpus;
- if (rdt_mon_capable) {
+ if (resctrl_arch_mon_capable()) {
ret = rdtgroup_kn_mode_restore(rdtgrp, "mon_groups", 0777);
if (ret)
goto err_cpus_list;
@@ -752,7 +752,7 @@ int rdtgroup_locksetup_enter(struct rdtgroup *rdtgrp)
* anymore when this group would be used for pseudo-locking. This
* is safe to call on platforms not capable of monitoring.
*/
- free_rmid(rdtgrp->mon.rmid);
+ free_rmid(rdtgrp->closid, rdtgrp->mon.rmid);
ret = 0;
goto out;
@@ -776,8 +776,8 @@ int rdtgroup_locksetup_exit(struct rdtgroup *rdtgrp)
{
int ret;
- if (rdt_mon_capable) {
- ret = alloc_rmid();
+ if (resctrl_arch_mon_capable()) {
+ ret = alloc_rmid(rdtgrp->closid);
if (ret < 0) {
rdt_last_cmd_puts("Out of RMIDs\n");
return ret;
@@ -787,7 +787,7 @@ int rdtgroup_locksetup_exit(struct rdtgroup *rdtgrp)
ret = rdtgroup_locksetup_user_restore(rdtgrp);
if (ret) {
- free_rmid(rdtgrp->mon.rmid);
+ free_rmid(rdtgrp->closid, rdtgrp->mon.rmid);
return ret;
}
@@ -844,6 +844,9 @@ bool rdtgroup_pseudo_locked_in_hierarchy(struct rdt_domain *d)
struct rdt_domain *d_i;
bool ret = false;
+ /* Walking r->domains, ensure it can't race with cpuhp */
+ lockdep_assert_cpus_held();
+
if (!zalloc_cpumask_var(&cpu_with_psl, GFP_KERNEL))
return true;
diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c
index 69a1de92384a..011e17efb1a6 100644
--- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c
+++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c
@@ -35,6 +35,10 @@
DEFINE_STATIC_KEY_FALSE(rdt_enable_key);
DEFINE_STATIC_KEY_FALSE(rdt_mon_enable_key);
DEFINE_STATIC_KEY_FALSE(rdt_alloc_enable_key);
+
+/* Mutex to protect rdtgroup access. */
+DEFINE_MUTEX(rdtgroup_mutex);
+
static struct kernfs_root *rdt_root;
struct rdtgroup rdtgroup_default;
LIST_HEAD(rdt_all_groups);
@@ -42,6 +46,9 @@ LIST_HEAD(rdt_all_groups);
/* list of entries for the schemata file */
LIST_HEAD(resctrl_schema_all);
+/* The filesystem can only be mounted once. */
+bool resctrl_mounted;
+
/* Kernel fs node for "info" directory under root */
static struct kernfs_node *kn_info;
@@ -102,7 +109,7 @@ void rdt_staged_configs_clear(void)
*
* Using a global CLOSID across all resources has some advantages and
* some drawbacks:
- * + We can simply set "current->closid" to assign a task to a resource
+ * + We can simply set current's closid to assign a task to a resource
* group.
* + Context switch code can avoid extra memory references deciding which
* CLOSID to load into the PQR_ASSOC MSR
@@ -111,7 +118,7 @@ void rdt_staged_configs_clear(void)
* - Our choices on how to configure each resource become progressively more
* limited as the number of resources grows.
*/
-static int closid_free_map;
+static unsigned long closid_free_map;
static int closid_free_map_len;
int closids_supported(void)
@@ -130,26 +137,39 @@ static void closid_init(void)
closid_free_map = BIT_MASK(rdt_min_closid) - 1;
- /* CLOSID 0 is always reserved for the default group */
- closid_free_map &= ~1;
+ /* RESCTRL_RESERVED_CLOSID is always reserved for the default group */
+ __clear_bit(RESCTRL_RESERVED_CLOSID, &closid_free_map);
closid_free_map_len = rdt_min_closid;
}
static int closid_alloc(void)
{
- u32 closid = ffs(closid_free_map);
+ int cleanest_closid;
+ u32 closid;
- if (closid == 0)
- return -ENOSPC;
- closid--;
- closid_free_map &= ~(1 << closid);
+ lockdep_assert_held(&rdtgroup_mutex);
+
+ if (IS_ENABLED(CONFIG_RESCTRL_RMID_DEPENDS_ON_CLOSID)) {
+ cleanest_closid = resctrl_find_cleanest_closid();
+ if (cleanest_closid < 0)
+ return cleanest_closid;
+ closid = cleanest_closid;
+ } else {
+ closid = ffs(closid_free_map);
+ if (closid == 0)
+ return -ENOSPC;
+ closid--;
+ }
+ __clear_bit(closid, &closid_free_map);
return closid;
}
void closid_free(int closid)
{
- closid_free_map |= 1 << closid;
+ lockdep_assert_held(&rdtgroup_mutex);
+
+ __set_bit(closid, &closid_free_map);
}
/**
@@ -159,9 +179,11 @@ void closid_free(int closid)
* Return: true if @closid is currently associated with a resource group,
* false if @closid is free
*/
-static bool closid_allocated(unsigned int closid)
+bool closid_allocated(unsigned int closid)
{
- return (closid_free_map & (1 << closid)) == 0;
+ lockdep_assert_held(&rdtgroup_mutex);
+
+ return !test_bit(closid, &closid_free_map);
}
/**
@@ -559,14 +581,26 @@ static void update_task_closid_rmid(struct task_struct *t)
_update_task_closid_rmid(t);
}
+static bool task_in_rdtgroup(struct task_struct *tsk, struct rdtgroup *rdtgrp)
+{
+ u32 closid, rmid = rdtgrp->mon.rmid;
+
+ if (rdtgrp->type == RDTCTRL_GROUP)
+ closid = rdtgrp->closid;
+ else if (rdtgrp->type == RDTMON_GROUP)
+ closid = rdtgrp->mon.parent->closid;
+ else
+ return false;
+
+ return resctrl_arch_match_closid(tsk, closid) &&
+ resctrl_arch_match_rmid(tsk, closid, rmid);
+}
+
static int __rdtgroup_move_task(struct task_struct *tsk,
struct rdtgroup *rdtgrp)
{
/* If the task is already in rdtgrp, no need to move the task. */
- if ((rdtgrp->type == RDTCTRL_GROUP && tsk->closid == rdtgrp->closid &&
- tsk->rmid == rdtgrp->mon.rmid) ||
- (rdtgrp->type == RDTMON_GROUP && tsk->rmid == rdtgrp->mon.rmid &&
- tsk->closid == rdtgrp->mon.parent->closid))
+ if (task_in_rdtgroup(tsk, rdtgrp))
return 0;
/*
@@ -577,19 +611,19 @@ static int __rdtgroup_move_task(struct task_struct *tsk,
* For monitor groups, can move the tasks only from
* their parent CTRL group.
*/
-
- if (rdtgrp->type == RDTCTRL_GROUP) {
- WRITE_ONCE(tsk->closid, rdtgrp->closid);
- WRITE_ONCE(tsk->rmid, rdtgrp->mon.rmid);
- } else if (rdtgrp->type == RDTMON_GROUP) {
- if (rdtgrp->mon.parent->closid == tsk->closid) {
- WRITE_ONCE(tsk->rmid, rdtgrp->mon.rmid);
- } else {
- rdt_last_cmd_puts("Can't move task to different control group\n");
- return -EINVAL;
- }
+ if (rdtgrp->type == RDTMON_GROUP &&
+ !resctrl_arch_match_closid(tsk, rdtgrp->mon.parent->closid)) {
+ rdt_last_cmd_puts("Can't move task to different control group\n");
+ return -EINVAL;
}
+ if (rdtgrp->type == RDTMON_GROUP)
+ resctrl_arch_set_closid_rmid(tsk, rdtgrp->mon.parent->closid,
+ rdtgrp->mon.rmid);
+ else
+ resctrl_arch_set_closid_rmid(tsk, rdtgrp->closid,
+ rdtgrp->mon.rmid);
+
/*
* Ensure the task's closid and rmid are written before determining if
* the task is current that will decide if it will be interrupted.
@@ -611,14 +645,15 @@ static int __rdtgroup_move_task(struct task_struct *tsk,
static bool is_closid_match(struct task_struct *t, struct rdtgroup *r)
{
- return (rdt_alloc_capable &&
- (r->type == RDTCTRL_GROUP) && (t->closid == r->closid));
+ return (resctrl_arch_alloc_capable() && (r->type == RDTCTRL_GROUP) &&
+ resctrl_arch_match_closid(t, r->closid));
}
static bool is_rmid_match(struct task_struct *t, struct rdtgroup *r)
{
- return (rdt_mon_capable &&
- (r->type == RDTMON_GROUP) && (t->rmid == r->mon.rmid));
+ return (resctrl_arch_mon_capable() && (r->type == RDTMON_GROUP) &&
+ resctrl_arch_match_rmid(t, r->mon.parent->closid,
+ r->mon.rmid));
}
/**
@@ -853,7 +888,7 @@ int proc_resctrl_show(struct seq_file *s, struct pid_namespace *ns,
mutex_lock(&rdtgroup_mutex);
/* Return empty if resctrl has not been mounted. */
- if (!static_branch_unlikely(&rdt_enable_key)) {
+ if (!resctrl_mounted) {
seq_puts(s, "res:\nmon:\n");
goto unlock;
}
@@ -869,7 +904,7 @@ int proc_resctrl_show(struct seq_file *s, struct pid_namespace *ns,
rdtg->mode != RDT_MODE_EXCLUSIVE)
continue;
- if (rdtg->closid != tsk->closid)
+ if (!resctrl_arch_match_closid(tsk, rdtg->closid))
continue;
seq_printf(s, "res:%s%s\n", (rdtg == &rdtgroup_default) ? "/" : "",
@@ -877,7 +912,8 @@ int proc_resctrl_show(struct seq_file *s, struct pid_namespace *ns,
seq_puts(s, "mon:");
list_for_each_entry(crg, &rdtg->mon.crdtgrp_list,
mon.crdtgrp_list) {
- if (tsk->rmid != crg->mon.rmid)
+ if (!resctrl_arch_match_rmid(tsk, crg->mon.parent->closid,
+ crg->mon.rmid))
continue;
seq_printf(s, "%s", crg->kn->name);
break;
@@ -982,6 +1018,7 @@ static int rdt_bit_usage_show(struct kernfs_open_file *of,
bool sep = false;
u32 ctrl_val;
+ cpus_read_lock();
mutex_lock(&rdtgroup_mutex);
hw_shareable = r->cache.shareable_bits;
list_for_each_entry(dom, &r->domains, list) {
@@ -1042,6 +1079,7 @@ static int rdt_bit_usage_show(struct kernfs_open_file *of,
}
seq_putc(seq, '\n');
mutex_unlock(&rdtgroup_mutex);
+ cpus_read_unlock();
return 0;
}
@@ -1297,6 +1335,9 @@ static bool rdtgroup_mode_test_exclusive(struct rdtgroup *rdtgrp)
struct rdt_domain *d;
u32 ctrl;
+ /* Walking r->domains, ensure it can't race with cpuhp */
+ lockdep_assert_cpus_held();
+
list_for_each_entry(s, &resctrl_schema_all, list) {
r = s->res;
if (r->rid == RDT_RESOURCE_MBA || r->rid == RDT_RESOURCE_SMBA)
@@ -1561,6 +1602,7 @@ static int mbm_config_show(struct seq_file *s, struct rdt_resource *r, u32 evtid
struct rdt_domain *dom;
bool sep = false;
+ cpus_read_lock();
mutex_lock(&rdtgroup_mutex);
list_for_each_entry(dom, &r->domains, list) {
@@ -1577,6 +1619,7 @@ static int mbm_config_show(struct seq_file *s, struct rdt_resource *r, u32 evtid
seq_puts(s, "\n");
mutex_unlock(&rdtgroup_mutex);
+ cpus_read_unlock();
return 0;
}
@@ -1614,17 +1657,10 @@ static void mon_event_config_write(void *info)
wrmsr(MSR_IA32_EVT_CFG_BASE + index, mon_info->mon_config, 0);
}
-static int mbm_config_write_domain(struct rdt_resource *r,
- struct rdt_domain *d, u32 evtid, u32 val)
+static void mbm_config_write_domain(struct rdt_resource *r,
+ struct rdt_domain *d, u32 evtid, u32 val)
{
struct mon_config_info mon_info = {0};
- int ret = 0;
-
- /* mon_config cannot be more than the supported set of events */
- if (val > MAX_EVT_CONFIG_BITS) {
- rdt_last_cmd_puts("Invalid event configuration\n");
- return -EINVAL;
- }
/*
* Read the current config value first. If both are the same then
@@ -1633,7 +1669,7 @@ static int mbm_config_write_domain(struct rdt_resource *r,
mon_info.evtid = evtid;
mondata_config_read(d, &mon_info);
if (mon_info.mon_config == val)
- goto out;
+ return;
mon_info.mon_config = val;
@@ -1656,17 +1692,17 @@ static int mbm_config_write_domain(struct rdt_resource *r,
* mbm_local and mbm_total counts for all the RMIDs.
*/
resctrl_arch_reset_rmid_all(r, d);
-
-out:
- return ret;
}
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;
- int ret = 0;
+
+ /* Walking r->domains, ensure it can't race with cpuhp */
+ lockdep_assert_cpus_held();
next:
if (!tok || tok[0] == '\0')
@@ -1686,11 +1722,16 @@ next:
return -EINVAL;
}
+ /* Value from user cannot be more than the supported set of events */
+ if ((val & hw_res->mbm_cfg_mask) != val) {
+ rdt_last_cmd_printf("Invalid event configuration: max valid mask is 0x%02x\n",
+ hw_res->mbm_cfg_mask);
+ return -EINVAL;
+ }
+
list_for_each_entry(d, &r->domains, list) {
if (d->id == dom_id) {
- ret = mbm_config_write_domain(r, d, evtid, val);
- if (ret)
- return -EINVAL;
+ mbm_config_write_domain(r, d, evtid, val);
goto next;
}
}
@@ -1709,6 +1750,7 @@ static ssize_t mbm_total_bytes_config_write(struct kernfs_open_file *of,
if (nbytes == 0 || buf[nbytes - 1] != '\n')
return -EINVAL;
+ cpus_read_lock();
mutex_lock(&rdtgroup_mutex);
rdt_last_cmd_clear();
@@ -1718,6 +1760,7 @@ static ssize_t mbm_total_bytes_config_write(struct kernfs_open_file *of,
ret = mon_config_write(r, buf, QOS_L3_MBM_TOTAL_EVENT_ID);
mutex_unlock(&rdtgroup_mutex);
+ cpus_read_unlock();
return ret ?: nbytes;
}
@@ -1733,6 +1776,7 @@ static ssize_t mbm_local_bytes_config_write(struct kernfs_open_file *of,
if (nbytes == 0 || buf[nbytes - 1] != '\n')
return -EINVAL;
+ cpus_read_lock();
mutex_lock(&rdtgroup_mutex);
rdt_last_cmd_clear();
@@ -1742,6 +1786,7 @@ static ssize_t mbm_local_bytes_config_write(struct kernfs_open_file *of,
ret = mon_config_write(r, buf, QOS_L3_MBM_LOCAL_EVENT_ID);
mutex_unlock(&rdtgroup_mutex);
+ cpus_read_unlock();
return ret ?: nbytes;
}
@@ -2218,6 +2263,9 @@ static int set_cache_qos_cfg(int level, bool enable)
struct rdt_domain *d;
int cpu;
+ /* Walking r->domains, ensure it can't race with cpuhp */
+ lockdep_assert_cpus_held();
+
if (level == RDT_RESOURCE_L3)
update = l3_qos_cfg_update;
else if (level == RDT_RESOURCE_L2)
@@ -2417,6 +2465,7 @@ struct rdtgroup *rdtgroup_kn_lock_live(struct kernfs_node *kn)
rdtgroup_kn_get(rdtgrp, kn);
+ cpus_read_lock();
mutex_lock(&rdtgroup_mutex);
/* Was this group deleted while we waited? */
@@ -2434,6 +2483,8 @@ void rdtgroup_kn_unlock(struct kernfs_node *kn)
return;
mutex_unlock(&rdtgroup_mutex);
+ cpus_read_unlock();
+
rdtgroup_kn_put(rdtgrp, kn);
}
@@ -2584,7 +2635,7 @@ static int rdt_get_tree(struct fs_context *fc)
/*
* resctrl file system can only be mounted once.
*/
- if (static_branch_unlikely(&rdt_enable_key)) {
+ if (resctrl_mounted) {
ret = -EBUSY;
goto out;
}
@@ -2605,7 +2656,7 @@ static int rdt_get_tree(struct fs_context *fc)
closid_init();
- if (rdt_mon_capable)
+ if (resctrl_arch_mon_capable())
flags |= RFTYPE_MON;
ret = rdtgroup_add_files(rdtgroup_default.kn, flags);
@@ -2618,7 +2669,7 @@ static int rdt_get_tree(struct fs_context *fc)
if (ret < 0)
goto out_schemata_free;
- if (rdt_mon_capable) {
+ if (resctrl_arch_mon_capable()) {
ret = mongroup_create_dir(rdtgroup_default.kn,
&rdtgroup_default, "mon_groups",
&kn_mongrp);
@@ -2640,18 +2691,19 @@ static int rdt_get_tree(struct fs_context *fc)
if (ret < 0)
goto out_psl;
- if (rdt_alloc_capable)
- static_branch_enable_cpuslocked(&rdt_alloc_enable_key);
- if (rdt_mon_capable)
- static_branch_enable_cpuslocked(&rdt_mon_enable_key);
+ if (resctrl_arch_alloc_capable())
+ resctrl_arch_enable_alloc();
+ if (resctrl_arch_mon_capable())
+ resctrl_arch_enable_mon();
- if (rdt_alloc_capable || rdt_mon_capable)
- static_branch_enable_cpuslocked(&rdt_enable_key);
+ if (resctrl_arch_alloc_capable() || resctrl_arch_mon_capable())
+ resctrl_mounted = true;
if (is_mbm_enabled()) {
r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
list_for_each_entry(dom, &r->domains, list)
- mbm_setup_overflow_handler(dom, MBM_OVERFLOW_INTERVAL);
+ mbm_setup_overflow_handler(dom, MBM_OVERFLOW_INTERVAL,
+ RESCTRL_PICK_ANY_CPU);
}
goto out;
@@ -2659,10 +2711,10 @@ static int rdt_get_tree(struct fs_context *fc)
out_psl:
rdt_pseudo_lock_release();
out_mondata:
- if (rdt_mon_capable)
+ if (resctrl_arch_mon_capable())
kernfs_remove(kn_mondata);
out_mongrp:
- if (rdt_mon_capable)
+ if (resctrl_arch_mon_capable())
kernfs_remove(kn_mongrp);
out_info:
kernfs_remove(kn_info);
@@ -2765,6 +2817,9 @@ static int reset_all_ctrls(struct rdt_resource *r)
struct rdt_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;
@@ -2810,8 +2865,8 @@ static void rdt_move_group_tasks(struct rdtgroup *from, struct rdtgroup *to,
for_each_process_thread(p, t) {
if (!from || is_closid_match(t, from) ||
is_rmid_match(t, from)) {
- WRITE_ONCE(t->closid, to->closid);
- WRITE_ONCE(t->rmid, to->mon.rmid);
+ resctrl_arch_set_closid_rmid(t, to->closid,
+ to->mon.rmid);
/*
* Order the closid/rmid stores above before the loads
@@ -2842,7 +2897,7 @@ static void free_all_child_rdtgrp(struct rdtgroup *rdtgrp)
head = &rdtgrp->mon.crdtgrp_list;
list_for_each_entry_safe(sentry, stmp, head, mon.crdtgrp_list) {
- free_rmid(sentry->mon.rmid);
+ free_rmid(sentry->closid, sentry->mon.rmid);
list_del(&sentry->mon.crdtgrp_list);
if (atomic_read(&sentry->waitcount) != 0)
@@ -2882,7 +2937,7 @@ static void rmdir_all_sub(void)
cpumask_or(&rdtgroup_default.cpu_mask,
&rdtgroup_default.cpu_mask, &rdtgrp->cpu_mask);
- free_rmid(rdtgrp->mon.rmid);
+ free_rmid(rdtgrp->closid, rdtgrp->mon.rmid);
kernfs_remove(rdtgrp->kn);
list_del(&rdtgrp->rdtgroup_list);
@@ -2917,9 +2972,11 @@ static void rdt_kill_sb(struct super_block *sb)
rdtgroup_default.mode = RDT_MODE_SHAREABLE;
schemata_list_destroy();
rdtgroup_destroy_root();
- static_branch_disable_cpuslocked(&rdt_alloc_enable_key);
- static_branch_disable_cpuslocked(&rdt_mon_enable_key);
- static_branch_disable_cpuslocked(&rdt_enable_key);
+ if (resctrl_arch_alloc_capable())
+ resctrl_arch_disable_alloc();
+ if (resctrl_arch_mon_capable())
+ resctrl_arch_disable_mon();
+ resctrl_mounted = false;
kernfs_kill_sb(sb);
mutex_unlock(&rdtgroup_mutex);
cpus_read_unlock();
@@ -3047,6 +3104,9 @@ static int mkdir_mondata_subdir_alldom(struct kernfs_node *parent_kn,
struct rdt_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) {
ret = mkdir_mondata_subdir(parent_kn, dom, r, prgrp);
if (ret)
@@ -3293,6 +3353,36 @@ out:
return ret;
}
+static int mkdir_rdt_prepare_rmid_alloc(struct rdtgroup *rdtgrp)
+{
+ int ret;
+
+ if (!resctrl_arch_mon_capable())
+ return 0;
+
+ ret = alloc_rmid(rdtgrp->closid);
+ if (ret < 0) {
+ rdt_last_cmd_puts("Out of RMIDs\n");
+ return ret;
+ }
+ rdtgrp->mon.rmid = ret;
+
+ ret = mkdir_mondata_all(rdtgrp->kn, rdtgrp, &rdtgrp->mon.mon_data_kn);
+ if (ret) {
+ rdt_last_cmd_puts("kernfs subdir error\n");
+ free_rmid(rdtgrp->closid, rdtgrp->mon.rmid);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void mkdir_rdt_prepare_rmid_free(struct rdtgroup *rgrp)
+{
+ if (resctrl_arch_mon_capable())
+ free_rmid(rgrp->closid, rgrp->mon.rmid);
+}
+
static int mkdir_rdt_prepare(struct kernfs_node *parent_kn,
const char *name, umode_t mode,
enum rdt_group_type rtype, struct rdtgroup **r)
@@ -3353,7 +3443,7 @@ static int mkdir_rdt_prepare(struct kernfs_node *parent_kn,
if (rtype == RDTCTRL_GROUP) {
files = RFTYPE_BASE | RFTYPE_CTRL;
- if (rdt_mon_capable)
+ if (resctrl_arch_mon_capable())
files |= RFTYPE_MON;
} else {
files = RFTYPE_BASE | RFTYPE_MON;
@@ -3365,29 +3455,11 @@ static int mkdir_rdt_prepare(struct kernfs_node *parent_kn,
goto out_destroy;
}
- if (rdt_mon_capable) {
- ret = alloc_rmid();
- if (ret < 0) {
- rdt_last_cmd_puts("Out of RMIDs\n");
- goto out_destroy;
- }
- rdtgrp->mon.rmid = ret;
-
- ret = mkdir_mondata_all(kn, rdtgrp, &rdtgrp->mon.mon_data_kn);
- if (ret) {
- rdt_last_cmd_puts("kernfs subdir error\n");
- goto out_idfree;
- }
- }
- kernfs_activate(kn);
-
/*
* The caller unlocks the parent_kn upon success.
*/
return 0;
-out_idfree:
- free_rmid(rdtgrp->mon.rmid);
out_destroy:
kernfs_put(rdtgrp->kn);
kernfs_remove(rdtgrp->kn);
@@ -3401,7 +3473,6 @@ out_unlock:
static void mkdir_rdt_prepare_clean(struct rdtgroup *rgrp)
{
kernfs_remove(rgrp->kn);
- free_rmid(rgrp->mon.rmid);
rdtgroup_remove(rgrp);
}
@@ -3423,12 +3494,21 @@ static int rdtgroup_mkdir_mon(struct kernfs_node *parent_kn,
prgrp = rdtgrp->mon.parent;
rdtgrp->closid = prgrp->closid;
+ ret = mkdir_rdt_prepare_rmid_alloc(rdtgrp);
+ if (ret) {
+ mkdir_rdt_prepare_clean(rdtgrp);
+ goto out_unlock;
+ }
+
+ kernfs_activate(rdtgrp->kn);
+
/*
* Add the rdtgrp to the list of rdtgrps the parent
* ctrl_mon group has to track.
*/
list_add_tail(&rdtgrp->mon.crdtgrp_list, &prgrp->mon.crdtgrp_list);
+out_unlock:
rdtgroup_kn_unlock(parent_kn);
return ret;
}
@@ -3459,13 +3539,20 @@ static int rdtgroup_mkdir_ctrl_mon(struct kernfs_node *parent_kn,
ret = 0;
rdtgrp->closid = closid;
+
+ ret = mkdir_rdt_prepare_rmid_alloc(rdtgrp);
+ if (ret)
+ goto out_closid_free;
+
+ kernfs_activate(rdtgrp->kn);
+
ret = rdtgroup_init_alloc(rdtgrp);
if (ret < 0)
- goto out_id_free;
+ goto out_rmid_free;
list_add(&rdtgrp->rdtgroup_list, &rdt_all_groups);
- if (rdt_mon_capable) {
+ if (resctrl_arch_mon_capable()) {
/*
* Create an empty mon_groups directory to hold the subset
* of tasks and cpus to monitor.
@@ -3481,7 +3568,9 @@ static int rdtgroup_mkdir_ctrl_mon(struct kernfs_node *parent_kn,
out_del_list:
list_del(&rdtgrp->rdtgroup_list);
-out_id_free:
+out_rmid_free:
+ mkdir_rdt_prepare_rmid_free(rdtgrp);
+out_closid_free:
closid_free(closid);
out_common_fail:
mkdir_rdt_prepare_clean(rdtgrp);
@@ -3518,14 +3607,14 @@ static int rdtgroup_mkdir(struct kernfs_node *parent_kn, const char *name,
* allocation is supported, add a control and monitoring
* subdirectory
*/
- if (rdt_alloc_capable && parent_kn == rdtgroup_default.kn)
+ if (resctrl_arch_alloc_capable() && parent_kn == rdtgroup_default.kn)
return rdtgroup_mkdir_ctrl_mon(parent_kn, name, mode);
/*
* If RDT monitoring is supported and the parent directory is a valid
* "mon_groups" directory, add a monitoring subdirectory.
*/
- if (rdt_mon_capable && is_mon_groups(parent_kn, name))
+ if (resctrl_arch_mon_capable() && is_mon_groups(parent_kn, name))
return rdtgroup_mkdir_mon(parent_kn, name, mode);
return -EPERM;
@@ -3550,7 +3639,7 @@ static int rdtgroup_rmdir_mon(struct rdtgroup *rdtgrp, cpumask_var_t tmpmask)
update_closid_rmid(tmpmask, NULL);
rdtgrp->flags = RDT_DELETED;
- free_rmid(rdtgrp->mon.rmid);
+ free_rmid(rdtgrp->closid, rdtgrp->mon.rmid);
/*
* Remove the rdtgrp from the parent ctrl_mon group's list
@@ -3596,8 +3685,8 @@ static int rdtgroup_rmdir_ctrl(struct rdtgroup *rdtgrp, cpumask_var_t tmpmask)
cpumask_or(tmpmask, tmpmask, &rdtgrp->cpu_mask);
update_closid_rmid(tmpmask, NULL);
+ free_rmid(rdtgrp->closid, rdtgrp->mon.rmid);
closid_free(rdtgrp->closid);
- free_rmid(rdtgrp->mon.rmid);
rdtgroup_ctrl_remove(rdtgrp);
@@ -3829,8 +3918,8 @@ static void __init rdtgroup_setup_default(void)
{
mutex_lock(&rdtgroup_mutex);
- rdtgroup_default.closid = 0;
- rdtgroup_default.mon.rmid = 0;
+ rdtgroup_default.closid = RESCTRL_RESERVED_CLOSID;
+ rdtgroup_default.mon.rmid = RESCTRL_RESERVED_RMID;
rdtgroup_default.type = RDTCTRL_GROUP;
INIT_LIST_HEAD(&rdtgroup_default.mon.crdtgrp_list);
@@ -3848,24 +3937,24 @@ static void domain_destroy_mon_state(struct rdt_domain *d)
void resctrl_offline_domain(struct rdt_resource *r, struct rdt_domain *d)
{
- lockdep_assert_held(&rdtgroup_mutex);
+ mutex_lock(&rdtgroup_mutex);
if (supports_mba_mbps() && r->rid == RDT_RESOURCE_MBA)
mba_sc_domain_destroy(r, d);
if (!r->mon_capable)
- return;
+ goto out_unlock;
/*
* If resctrl is mounted, remove all the
* per domain monitor data directories.
*/
- if (static_branch_unlikely(&rdt_mon_enable_key))
+ if (resctrl_mounted && resctrl_arch_mon_capable())
rmdir_mondata_subdir_allrdtgrp(r, d->id);
if (is_mbm_enabled())
cancel_delayed_work(&d->mbm_over);
- if (is_llc_occupancy_enabled() && has_busy_rmid(r, d)) {
+ if (is_llc_occupancy_enabled() && has_busy_rmid(d)) {
/*
* When a package is going down, forcefully
* decrement rmid->ebusy. There is no way to know
@@ -3879,20 +3968,24 @@ 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)
{
+ u32 idx_limit = resctrl_arch_system_num_rmid_idx();
size_t tsize;
if (is_llc_occupancy_enabled()) {
- d->rmid_busy_llc = bitmap_zalloc(r->num_rmid, GFP_KERNEL);
+ d->rmid_busy_llc = bitmap_zalloc(idx_limit, GFP_KERNEL);
if (!d->rmid_busy_llc)
return -ENOMEM;
}
if (is_mbm_total_enabled()) {
tsize = sizeof(*d->mbm_total);
- d->mbm_total = kcalloc(r->num_rmid, tsize, GFP_KERNEL);
+ d->mbm_total = kcalloc(idx_limit, tsize, GFP_KERNEL);
if (!d->mbm_total) {
bitmap_free(d->rmid_busy_llc);
return -ENOMEM;
@@ -3900,7 +3993,7 @@ static int domain_setup_mon_state(struct rdt_resource *r, struct rdt_domain *d)
}
if (is_mbm_local_enabled()) {
tsize = sizeof(*d->mbm_local);
- d->mbm_local = kcalloc(r->num_rmid, tsize, GFP_KERNEL);
+ d->mbm_local = kcalloc(idx_limit, tsize, GFP_KERNEL);
if (!d->mbm_local) {
bitmap_free(d->rmid_busy_llc);
kfree(d->mbm_total);
@@ -3913,34 +4006,97 @@ static int domain_setup_mon_state(struct rdt_resource *r, struct rdt_domain *d)
int resctrl_online_domain(struct rdt_resource *r, struct rdt_domain *d)
{
- int err;
+ int err = 0;
- lockdep_assert_held(&rdtgroup_mutex);
+ mutex_lock(&rdtgroup_mutex);
- if (supports_mba_mbps() && r->rid == RDT_RESOURCE_MBA)
+ if (supports_mba_mbps() && r->rid == RDT_RESOURCE_MBA) {
/* RDT_RESOURCE_MBA is never mon_capable */
- return mba_sc_domain_allocate(r, d);
+ err = mba_sc_domain_allocate(r, d);
+ goto out_unlock;
+ }
if (!r->mon_capable)
- return 0;
+ goto out_unlock;
err = domain_setup_mon_state(r, d);
if (err)
- return err;
+ goto out_unlock;
if (is_mbm_enabled()) {
INIT_DELAYED_WORK(&d->mbm_over, mbm_handle_overflow);
- mbm_setup_overflow_handler(d, MBM_OVERFLOW_INTERVAL);
+ mbm_setup_overflow_handler(d, MBM_OVERFLOW_INTERVAL,
+ RESCTRL_PICK_ANY_CPU);
}
if (is_llc_occupancy_enabled())
INIT_DELAYED_WORK(&d->cqm_limbo, cqm_handle_limbo);
- /* If resctrl is mounted, add per domain monitor data directories. */
- if (static_branch_unlikely(&rdt_mon_enable_key))
+ /*
+ * If the filesystem is not mounted then only the default resource group
+ * exists. Creation of its directories is deferred until mount time
+ * by rdt_get_tree() calling mkdir_mondata_all().
+ * If resctrl is mounted, add per domain monitor data directories.
+ */
+ if (resctrl_mounted && resctrl_arch_mon_capable())
mkdir_mondata_subdir_allrdtgrp(r, d);
- return 0;
+out_unlock:
+ mutex_unlock(&rdtgroup_mutex);
+
+ return err;
+}
+
+void resctrl_online_cpu(unsigned int cpu)
+{
+ mutex_lock(&rdtgroup_mutex);
+ /* The CPU is set in default rdtgroup after online. */
+ cpumask_set_cpu(cpu, &rdtgroup_default.cpu_mask);
+ mutex_unlock(&rdtgroup_mutex);
+}
+
+static void clear_childcpus(struct rdtgroup *r, unsigned int cpu)
+{
+ struct rdtgroup *cr;
+
+ list_for_each_entry(cr, &r->mon.crdtgrp_list, mon.crdtgrp_list) {
+ if (cpumask_test_and_clear_cpu(cpu, &cr->cpu_mask))
+ break;
+ }
+}
+
+void resctrl_offline_cpu(unsigned int cpu)
+{
+ struct rdt_resource *l3 = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
+ struct rdtgroup *rdtgrp;
+ struct rdt_domain *d;
+
+ mutex_lock(&rdtgroup_mutex);
+ list_for_each_entry(rdtgrp, &rdt_all_groups, rdtgroup_list) {
+ if (cpumask_test_and_clear_cpu(cpu, &rdtgrp->cpu_mask)) {
+ clear_childcpus(rdtgrp, cpu);
+ break;
+ }
+ }
+
+ if (!l3->mon_capable)
+ goto out_unlock;
+
+ d = get_domain_from_cpu(cpu, l3);
+ if (d) {
+ if (is_mbm_enabled() && cpu == d->mbm_work_cpu) {
+ cancel_delayed_work(&d->mbm_over);
+ mbm_setup_overflow_handler(d, 0, cpu);
+ }
+ if (is_llc_occupancy_enabled() && cpu == d->cqm_work_cpu &&
+ has_busy_rmid(d)) {
+ cancel_delayed_work(&d->cqm_limbo);
+ cqm_setup_limbo_handler(d, 0, cpu);
+ }
+ }
+
+out_unlock:
+ mutex_unlock(&rdtgroup_mutex);
}
/*
diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c
index 0dad49a09b7a..af5aa2c754c2 100644
--- a/arch/x86/kernel/cpu/scattered.c
+++ b/arch/x86/kernel/cpu/scattered.c
@@ -28,6 +28,7 @@ static const struct cpuid_bit cpuid_bits[] = {
{ X86_FEATURE_EPB, CPUID_ECX, 3, 0x00000006, 0 },
{ X86_FEATURE_INTEL_PPIN, CPUID_EBX, 0, 0x00000007, 1 },
{ X86_FEATURE_RRSBA_CTRL, CPUID_EDX, 2, 0x00000007, 2 },
+ { X86_FEATURE_BHI_CTRL, CPUID_EDX, 4, 0x00000007, 2 },
{ X86_FEATURE_CQM_LLC, CPUID_EDX, 1, 0x0000000f, 0 },
{ X86_FEATURE_CQM_OCCUP_LLC, CPUID_EDX, 0, 0x0000000f, 1 },
{ X86_FEATURE_CQM_MBM_TOTAL, CPUID_EDX, 1, 0x0000000f, 1 },
@@ -49,6 +50,7 @@ static const struct cpuid_bit cpuid_bits[] = {
{ X86_FEATURE_BMEC, CPUID_EBX, 3, 0x80000020, 0 },
{ X86_FEATURE_PERFMON_V2, CPUID_EAX, 0, 0x80000022, 0 },
{ X86_FEATURE_AMD_LBR_V2, CPUID_EAX, 1, 0x80000022, 0 },
+ { X86_FEATURE_AMD_LBR_PMC_FREEZE, CPUID_EAX, 2, 0x80000022, 0 },
{ 0, 0, 0, 0, 0 }
};
diff --git a/arch/x86/kernel/cpu/topology.c b/arch/x86/kernel/cpu/topology.c
index dc136703566f..aaca8d235dc2 100644
--- a/arch/x86/kernel/cpu/topology.c
+++ b/arch/x86/kernel/cpu/topology.c
@@ -1,167 +1,521 @@
-// SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0-only
/*
- * Check for extended topology enumeration cpuid leaf 0xb and if it
- * exists, use it for populating initial_apicid and cpu topology
- * detection.
+ * CPU/APIC topology
+ *
+ * The APIC IDs describe the system topology in multiple domain levels.
+ * The CPUID topology parser provides the information which part of the
+ * APIC ID is associated to the individual levels:
+ *
+ * [PACKAGE][DIEGRP][DIE][TILE][MODULE][CORE][THREAD]
+ *
+ * The root space contains the package (socket) IDs.
+ *
+ * Not enumerated levels consume 0 bits space, but conceptually they are
+ * always represented. If e.g. only CORE and THREAD levels are enumerated
+ * then the DIE, MODULE and TILE have the same physical ID as the PACKAGE.
+ *
+ * If SMT is not supported, then the THREAD domain is still used. It then
+ * has the same physical ID as the CORE domain and is the only child of
+ * the core domain.
+ *
+ * This allows a unified view on the system independent of the enumerated
+ * domain levels without requiring any conditionals in the code.
*/
-
+#define pr_fmt(fmt) "CPU topo: " fmt
#include <linux/cpu.h>
+
+#include <xen/xen.h>
+
#include <asm/apic.h>
-#include <asm/memtype.h>
-#include <asm/processor.h>
+#include <asm/hypervisor.h>
+#include <asm/io_apic.h>
+#include <asm/mpspec.h>
+#include <asm/smp.h>
#include "cpu.h"
-/* leaf 0xb SMT level */
-#define SMT_LEVEL 0
+/*
+ * Map cpu index to physical APIC ID
+ */
+DEFINE_EARLY_PER_CPU_READ_MOSTLY(u32, x86_cpu_to_apicid, BAD_APICID);
+DEFINE_EARLY_PER_CPU_READ_MOSTLY(u32, x86_cpu_to_acpiid, CPU_ACPIID_INVALID);
+EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_apicid);
+EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_acpiid);
-/* extended topology sub-leaf types */
-#define INVALID_TYPE 0
-#define SMT_TYPE 1
-#define CORE_TYPE 2
-#define DIE_TYPE 5
+/* Bitmap of physically present CPUs. */
+DECLARE_BITMAP(phys_cpu_present_map, MAX_LOCAL_APIC) __read_mostly;
-#define LEAFB_SUBTYPE(ecx) (((ecx) >> 8) & 0xff)
-#define BITS_SHIFT_NEXT_LEVEL(eax) ((eax) & 0x1f)
-#define LEVEL_MAX_SIBLINGS(ebx) ((ebx) & 0xffff)
+/* Used for CPU number allocation and parallel CPU bringup */
+u32 cpuid_to_apicid[] __ro_after_init = { [0 ... NR_CPUS - 1] = BAD_APICID, };
+
+/* Bitmaps to mark registered APICs at each topology domain */
+static struct { DECLARE_BITMAP(map, MAX_LOCAL_APIC); } apic_maps[TOPO_MAX_DOMAIN] __ro_after_init;
+
+/*
+ * Keep track of assigned, disabled and rejected CPUs. Present assigned
+ * with 1 as CPU #0 is reserved for the boot CPU.
+ */
+static struct {
+ unsigned int nr_assigned_cpus;
+ unsigned int nr_disabled_cpus;
+ unsigned int nr_rejected_cpus;
+ u32 boot_cpu_apic_id;
+ u32 real_bsp_apic_id;
+} topo_info __ro_after_init = {
+ .nr_assigned_cpus = 1,
+ .boot_cpu_apic_id = BAD_APICID,
+ .real_bsp_apic_id = BAD_APICID,
+};
-unsigned int __max_die_per_package __read_mostly = 1;
-EXPORT_SYMBOL(__max_die_per_package);
+#define domain_weight(_dom) bitmap_weight(apic_maps[_dom].map, MAX_LOCAL_APIC)
+
+bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
+{
+ return phys_id == (u64)cpuid_to_apicid[cpu];
+}
#ifdef CONFIG_SMP
+static void cpu_mark_primary_thread(unsigned int cpu, unsigned int apicid)
+{
+ if (!(apicid & (__max_threads_per_core - 1)))
+ cpumask_set_cpu(cpu, &__cpu_primary_thread_mask);
+}
+#else
+static inline void cpu_mark_primary_thread(unsigned int cpu, unsigned int apicid) { }
+#endif
+
/*
- * Check if given CPUID extended topology "leaf" is implemented
+ * Convert the APIC ID to a domain level ID by masking out the low bits
+ * below the domain level @dom.
*/
-static int check_extended_topology_leaf(int leaf)
+static inline u32 topo_apicid(u32 apicid, enum x86_topology_domains dom)
+{
+ if (dom == TOPO_SMT_DOMAIN)
+ return apicid;
+ return apicid & (UINT_MAX << x86_topo_system.dom_shifts[dom - 1]);
+}
+
+static int topo_lookup_cpuid(u32 apic_id)
{
- unsigned int eax, ebx, ecx, edx;
+ int i;
- cpuid_count(leaf, SMT_LEVEL, &eax, &ebx, &ecx, &edx);
+ /* CPU# to APICID mapping is persistent once it is established */
+ for (i = 0; i < topo_info.nr_assigned_cpus; i++) {
+ if (cpuid_to_apicid[i] == apic_id)
+ return i;
+ }
+ return -ENODEV;
+}
- if (ebx == 0 || (LEAFB_SUBTYPE(ecx) != SMT_TYPE))
- return -1;
+static __init int topo_get_cpunr(u32 apic_id)
+{
+ int cpu = topo_lookup_cpuid(apic_id);
- return 0;
+ if (cpu >= 0)
+ return cpu;
+
+ return topo_info.nr_assigned_cpus++;
}
-/*
- * Return best CPUID Extended Topology Leaf supported
+
+static void topo_set_cpuids(unsigned int cpu, u32 apic_id, u32 acpi_id)
+{
+#if defined(CONFIG_SMP) || defined(CONFIG_X86_64)
+ early_per_cpu(x86_cpu_to_apicid, cpu) = apic_id;
+ early_per_cpu(x86_cpu_to_acpiid, cpu) = acpi_id;
+#endif
+ set_cpu_possible(cpu, true);
+ set_cpu_present(cpu, true);
+}
+
+static __init bool check_for_real_bsp(u32 apic_id)
+{
+ /*
+ * There is no real good way to detect whether this a kdump()
+ * kernel, but except on the Voyager SMP monstrosity which is not
+ * longer supported, the real BSP APIC ID is the first one which is
+ * enumerated by firmware. That allows to detect whether the boot
+ * CPU is the real BSP. If it is not, then do not register the APIC
+ * because sending INIT to the real BSP would reset the whole
+ * system.
+ *
+ * The first APIC ID which is enumerated by firmware is detectable
+ * because the boot CPU APIC ID is registered before that without
+ * invoking this code.
+ */
+ if (topo_info.real_bsp_apic_id != BAD_APICID)
+ return false;
+
+ if (apic_id == topo_info.boot_cpu_apic_id) {
+ topo_info.real_bsp_apic_id = apic_id;
+ return false;
+ }
+
+ pr_warn("Boot CPU APIC ID not the first enumerated APIC ID: %x > %x\n",
+ topo_info.boot_cpu_apic_id, apic_id);
+ pr_warn("Crash kernel detected. Disabling real BSP to prevent machine INIT\n");
+
+ topo_info.real_bsp_apic_id = apic_id;
+ return true;
+}
+
+static unsigned int topo_unit_count(u32 lvlid, enum x86_topology_domains at_level,
+ unsigned long *map)
+{
+ unsigned int id, end, cnt = 0;
+
+ /* Calculate the exclusive end */
+ end = lvlid + (1U << x86_topo_system.dom_shifts[at_level]);
+
+ /* Unfortunately there is no bitmap_weight_range() */
+ for (id = find_next_bit(map, end, lvlid); id < end; id = find_next_bit(map, end, ++id))
+ cnt++;
+ return cnt;
+}
+
+static __init void topo_register_apic(u32 apic_id, u32 acpi_id, bool present)
+{
+ int cpu, dom;
+
+ if (present) {
+ set_bit(apic_id, phys_cpu_present_map);
+
+ /*
+ * Double registration is valid in case of the boot CPU
+ * APIC because that is registered before the enumeration
+ * of the APICs via firmware parsers or VM guest
+ * mechanisms.
+ */
+ if (apic_id == topo_info.boot_cpu_apic_id)
+ cpu = 0;
+ else
+ cpu = topo_get_cpunr(apic_id);
+
+ cpuid_to_apicid[cpu] = apic_id;
+ topo_set_cpuids(cpu, apic_id, acpi_id);
+ } else {
+ u32 pkgid = topo_apicid(apic_id, TOPO_PKG_DOMAIN);
+
+ /*
+ * Check for present APICs in the same package when running
+ * on bare metal. Allow the bogosity in a guest.
+ */
+ if (hypervisor_is_type(X86_HYPER_NATIVE) &&
+ topo_unit_count(pkgid, TOPO_PKG_DOMAIN, phys_cpu_present_map)) {
+ pr_info_once("Ignoring hot-pluggable APIC ID %x in present package.\n",
+ apic_id);
+ topo_info.nr_rejected_cpus++;
+ return;
+ }
+
+ topo_info.nr_disabled_cpus++;
+ }
+
+ /* Register present and possible CPUs in the domain maps */
+ for (dom = TOPO_SMT_DOMAIN; dom < TOPO_MAX_DOMAIN; dom++)
+ set_bit(topo_apicid(apic_id, dom), apic_maps[dom].map);
+}
+
+/**
+ * topology_register_apic - Register an APIC in early topology maps
+ * @apic_id: The APIC ID to set up
+ * @acpi_id: The ACPI ID associated to the APIC
+ * @present: True if the corresponding CPU is present
*/
-static int detect_extended_topology_leaf(struct cpuinfo_x86 *c)
+void __init topology_register_apic(u32 apic_id, u32 acpi_id, bool present)
{
- if (c->cpuid_level >= 0x1f) {
- if (check_extended_topology_leaf(0x1f) == 0)
- return 0x1f;
+ if (apic_id >= MAX_LOCAL_APIC) {
+ pr_err_once("APIC ID %x exceeds kernel limit of: %x\n", apic_id, MAX_LOCAL_APIC - 1);
+ topo_info.nr_rejected_cpus++;
+ return;
+ }
+
+ if (check_for_real_bsp(apic_id)) {
+ topo_info.nr_rejected_cpus++;
+ return;
}
- if (c->cpuid_level >= 0xb) {
- if (check_extended_topology_leaf(0xb) == 0)
- return 0xb;
+ /* CPU numbers exhausted? */
+ if (apic_id != topo_info.boot_cpu_apic_id && topo_info.nr_assigned_cpus >= nr_cpu_ids) {
+ pr_warn_once("CPU limit of %d reached. Ignoring further CPUs\n", nr_cpu_ids);
+ topo_info.nr_rejected_cpus++;
+ return;
}
- return -1;
+ topo_register_apic(apic_id, acpi_id, present);
+}
+
+/**
+ * topology_register_boot_apic - Register the boot CPU APIC
+ * @apic_id: The APIC ID to set up
+ *
+ * Separate so CPU #0 can be assigned
+ */
+void __init topology_register_boot_apic(u32 apic_id)
+{
+ WARN_ON_ONCE(topo_info.boot_cpu_apic_id != BAD_APICID);
+
+ topo_info.boot_cpu_apic_id = apic_id;
+ topo_register_apic(apic_id, CPU_ACPIID_INVALID, true);
+}
+
+/**
+ * topology_get_logical_id - Retrieve the logical ID at a given topology domain level
+ * @apicid: The APIC ID for which to lookup the logical ID
+ * @at_level: The topology domain level to use
+ *
+ * @apicid must be a full APIC ID, not the normalized variant. It's valid to have
+ * all bits below the domain level specified by @at_level to be clear. So both
+ * real APIC IDs and backshifted normalized APIC IDs work correctly.
+ *
+ * Returns:
+ * - >= 0: The requested logical ID
+ * - -ERANGE: @apicid is out of range
+ * - -ENODEV: @apicid is not registered
+ */
+int topology_get_logical_id(u32 apicid, enum x86_topology_domains at_level)
+{
+ /* Remove the bits below @at_level to get the proper level ID of @apicid */
+ unsigned int lvlid = topo_apicid(apicid, at_level);
+
+ if (lvlid >= MAX_LOCAL_APIC)
+ return -ERANGE;
+ if (!test_bit(lvlid, apic_maps[at_level].map))
+ return -ENODEV;
+ /* Get the number of set bits before @lvlid. */
+ return bitmap_weight(apic_maps[at_level].map, lvlid);
+}
+EXPORT_SYMBOL_GPL(topology_get_logical_id);
+
+/**
+ * topology_unit_count - Retrieve the count of specified units at a given topology domain level
+ * @apicid: The APIC ID which specifies the search range
+ * @which_units: The domain level specifying the units to count
+ * @at_level: The domain level at which @which_units have to be counted
+ *
+ * This returns the number of possible units according to the enumerated
+ * information.
+ *
+ * E.g. topology_count_units(apicid, TOPO_CORE_DOMAIN, TOPO_PKG_DOMAIN)
+ * counts the number of possible cores in the package to which @apicid
+ * belongs.
+ *
+ * @at_level must obviously be greater than @which_level to produce useful
+ * results. If @at_level is equal to @which_units the result is
+ * unsurprisingly 1. If @at_level is less than @which_units the results
+ * is by definition undefined and the function returns 0.
+ */
+unsigned int topology_unit_count(u32 apicid, enum x86_topology_domains which_units,
+ enum x86_topology_domains at_level)
+{
+ /* Remove the bits below @at_level to get the proper level ID of @apicid */
+ unsigned int lvlid = topo_apicid(apicid, at_level);
+
+ if (lvlid >= MAX_LOCAL_APIC)
+ return 0;
+ if (!test_bit(lvlid, apic_maps[at_level].map))
+ return 0;
+ if (which_units > at_level)
+ return 0;
+ if (which_units == at_level)
+ return 1;
+ return topo_unit_count(lvlid, at_level, apic_maps[which_units].map);
+}
+
+#ifdef CONFIG_ACPI_HOTPLUG_CPU
+/**
+ * topology_hotplug_apic - Handle a physical hotplugged APIC after boot
+ * @apic_id: The APIC ID to set up
+ * @acpi_id: The ACPI ID associated to the APIC
+ */
+int topology_hotplug_apic(u32 apic_id, u32 acpi_id)
+{
+ int cpu;
+
+ if (apic_id >= MAX_LOCAL_APIC)
+ return -EINVAL;
+
+ /* Reject if the APIC ID was not registered during enumeration. */
+ if (!test_bit(apic_id, apic_maps[TOPO_SMT_DOMAIN].map))
+ return -ENODEV;
+
+ cpu = topo_lookup_cpuid(apic_id);
+ if (cpu < 0)
+ return -ENOSPC;
+
+ set_bit(apic_id, phys_cpu_present_map);
+ topo_set_cpuids(cpu, apic_id, acpi_id);
+ cpu_mark_primary_thread(cpu, apic_id);
+ return cpu;
+}
+
+/**
+ * topology_hotunplug_apic - Remove a physical hotplugged APIC after boot
+ * @cpu: The CPU number for which the APIC ID is removed
+ */
+void topology_hotunplug_apic(unsigned int cpu)
+{
+ u32 apic_id = cpuid_to_apicid[cpu];
+
+ if (apic_id == BAD_APICID)
+ return;
+
+ per_cpu(x86_cpu_to_apicid, cpu) = BAD_APICID;
+ clear_bit(apic_id, phys_cpu_present_map);
+ set_cpu_present(cpu, false);
}
#endif
-int detect_extended_topology_early(struct cpuinfo_x86 *c)
+#ifdef CONFIG_X86_LOCAL_APIC
+static unsigned int max_possible_cpus __initdata = NR_CPUS;
+
+/**
+ * topology_apply_cmdline_limits_early - Apply topology command line limits early
+ *
+ * Ensure that command line limits are in effect before firmware parsing
+ * takes place.
+ */
+void __init topology_apply_cmdline_limits_early(void)
{
-#ifdef CONFIG_SMP
- unsigned int eax, ebx, ecx, edx;
- int leaf;
+ unsigned int possible = nr_cpu_ids;
+
+ /* 'maxcpus=0' 'nosmp' 'nolapic' 'disableapic' 'noapic' */
+ if (!setup_max_cpus || ioapic_is_disabled || apic_is_disabled)
+ possible = 1;
- leaf = detect_extended_topology_leaf(c);
- if (leaf < 0)
- return -1;
+ /* 'possible_cpus=N' */
+ possible = min_t(unsigned int, max_possible_cpus, possible);
- set_cpu_cap(c, X86_FEATURE_XTOPOLOGY);
+ if (possible < nr_cpu_ids) {
+ pr_info("Limiting to %u possible CPUs\n", possible);
+ set_nr_cpu_ids(possible);
+ }
+}
- cpuid_count(leaf, SMT_LEVEL, &eax, &ebx, &ecx, &edx);
+static __init bool restrict_to_up(void)
+{
+ if (!smp_found_config || ioapic_is_disabled)
+ return true;
/*
- * initial apic id, which also represents 32-bit extended x2apic id.
+ * XEN PV is special as it does not advertise the local APIC
+ * properly, but provides a fake topology for it so that the
+ * infrastructure works. So don't apply the restrictions vs. APIC
+ * here.
*/
- c->topo.initial_apicid = edx;
- smp_num_siblings = max_t(int, smp_num_siblings, LEVEL_MAX_SIBLINGS(ebx));
-#endif
- return 0;
+ if (xen_pv_domain())
+ return false;
+
+ return apic_is_disabled;
}
-/*
- * Check for extended topology enumeration cpuid leaf, and if it
- * exists, use it for populating initial_apicid and cpu topology
- * detection.
- */
-int detect_extended_topology(struct cpuinfo_x86 *c)
+void __init topology_init_possible_cpus(void)
{
-#ifdef CONFIG_SMP
- unsigned int eax, ebx, ecx, edx, sub_index;
- unsigned int ht_mask_width, core_plus_mask_width, die_plus_mask_width;
- unsigned int core_select_mask, core_level_siblings;
- unsigned int die_select_mask, die_level_siblings;
- unsigned int pkg_mask_width;
- bool die_level_present = false;
- int leaf;
-
- leaf = detect_extended_topology_leaf(c);
- if (leaf < 0)
- return -1;
+ unsigned int assigned = topo_info.nr_assigned_cpus;
+ unsigned int disabled = topo_info.nr_disabled_cpus;
+ unsigned int cnta, cntb, cpu, allowed = 1;
+ unsigned int total = assigned + disabled;
+ u32 apicid, firstid;
/*
- * Populate HT related information from sub-leaf level 0.
+ * If there was no APIC registered, then fake one so that the
+ * topology bitmap is populated. That ensures that the code below
+ * is valid and the various query interfaces can be used
+ * unconditionally. This does not affect the actual APIC code in
+ * any way because either the local APIC address has not been
+ * registered or the local APIC was disabled on the command line.
*/
- cpuid_count(leaf, SMT_LEVEL, &eax, &ebx, &ecx, &edx);
- c->topo.initial_apicid = edx;
- core_level_siblings = LEVEL_MAX_SIBLINGS(ebx);
- smp_num_siblings = max_t(int, smp_num_siblings, LEVEL_MAX_SIBLINGS(ebx));
- core_plus_mask_width = ht_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
- die_level_siblings = LEVEL_MAX_SIBLINGS(ebx);
- pkg_mask_width = die_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
-
- sub_index = 1;
- while (true) {
- cpuid_count(leaf, sub_index, &eax, &ebx, &ecx, &edx);
+ if (topo_info.boot_cpu_apic_id == BAD_APICID)
+ topology_register_boot_apic(0);
- /*
- * Check for the Core type in the implemented sub leaves.
- */
- if (LEAFB_SUBTYPE(ecx) == CORE_TYPE) {
- core_level_siblings = LEVEL_MAX_SIBLINGS(ebx);
- core_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
- die_level_siblings = core_level_siblings;
- die_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
- }
- if (LEAFB_SUBTYPE(ecx) == DIE_TYPE) {
- die_level_present = true;
- die_level_siblings = LEVEL_MAX_SIBLINGS(ebx);
- die_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
+ if (!restrict_to_up()) {
+ if (WARN_ON_ONCE(assigned > nr_cpu_ids)) {
+ disabled += assigned - nr_cpu_ids;
+ assigned = nr_cpu_ids;
}
+ allowed = min_t(unsigned int, total, nr_cpu_ids);
+ }
- if (LEAFB_SUBTYPE(ecx) != INVALID_TYPE)
- pkg_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
- else
- break;
+ if (total > allowed)
+ pr_warn("%u possible CPUs exceed the limit of %u\n", total, allowed);
- sub_index++;
- }
+ assigned = min_t(unsigned int, allowed, assigned);
+ disabled = allowed - assigned;
- core_select_mask = (~(-1 << pkg_mask_width)) >> ht_mask_width;
- die_select_mask = (~(-1 << die_plus_mask_width)) >>
- core_plus_mask_width;
+ topo_info.nr_assigned_cpus = assigned;
+ topo_info.nr_disabled_cpus = disabled;
- c->topo.core_id = apic->phys_pkg_id(c->topo.initial_apicid,
- ht_mask_width) & core_select_mask;
+ total_cpus = allowed;
+ set_nr_cpu_ids(allowed);
- if (die_level_present) {
- c->topo.die_id = apic->phys_pkg_id(c->topo.initial_apicid,
- core_plus_mask_width) & die_select_mask;
- }
+ cnta = domain_weight(TOPO_PKG_DOMAIN);
+ cntb = domain_weight(TOPO_DIE_DOMAIN);
+ __max_logical_packages = cnta;
+ __max_dies_per_package = 1U << (get_count_order(cntb) - get_count_order(cnta));
- c->topo.pkg_id = apic->phys_pkg_id(c->topo.initial_apicid, pkg_mask_width);
+ pr_info("Max. logical packages: %3u\n", cnta);
+ pr_info("Max. logical dies: %3u\n", cntb);
+ pr_info("Max. dies per package: %3u\n", __max_dies_per_package);
+
+ cnta = domain_weight(TOPO_CORE_DOMAIN);
+ cntb = domain_weight(TOPO_SMT_DOMAIN);
/*
- * Reinit the apicid, now that we have extended initial_apicid.
+ * Can't use order delta here as order(cnta) can be equal
+ * order(cntb) even if cnta != cntb.
*/
- c->topo.apicid = apic->phys_pkg_id(c->topo.initial_apicid, 0);
+ __max_threads_per_core = DIV_ROUND_UP(cntb, cnta);
+ pr_info("Max. threads per core: %3u\n", __max_threads_per_core);
- c->x86_max_cores = (core_level_siblings / smp_num_siblings);
- __max_die_per_package = (die_level_siblings / core_level_siblings);
-#endif
+ firstid = find_first_bit(apic_maps[TOPO_SMT_DOMAIN].map, MAX_LOCAL_APIC);
+ __num_cores_per_package = topology_unit_count(firstid, TOPO_CORE_DOMAIN, TOPO_PKG_DOMAIN);
+ pr_info("Num. cores per package: %3u\n", __num_cores_per_package);
+ __num_threads_per_package = topology_unit_count(firstid, TOPO_SMT_DOMAIN, TOPO_PKG_DOMAIN);
+ pr_info("Num. threads per package: %3u\n", __num_threads_per_package);
+
+ pr_info("Allowing %u present CPUs plus %u hotplug CPUs\n", assigned, disabled);
+ if (topo_info.nr_rejected_cpus)
+ pr_info("Rejected CPUs %u\n", topo_info.nr_rejected_cpus);
+
+ init_cpu_present(cpumask_of(0));
+ init_cpu_possible(cpumask_of(0));
+
+ /* Assign CPU numbers to non-present CPUs */
+ for (apicid = 0; disabled; disabled--, apicid++) {
+ apicid = find_next_andnot_bit(apic_maps[TOPO_SMT_DOMAIN].map, phys_cpu_present_map,
+ MAX_LOCAL_APIC, apicid);
+ if (apicid >= MAX_LOCAL_APIC)
+ break;
+ cpuid_to_apicid[topo_info.nr_assigned_cpus++] = apicid;
+ }
+
+ for (cpu = 0; cpu < allowed; cpu++) {
+ apicid = cpuid_to_apicid[cpu];
+
+ set_cpu_possible(cpu, true);
+
+ if (apicid == BAD_APICID)
+ continue;
+
+ cpu_mark_primary_thread(cpu, apicid);
+ set_cpu_present(cpu, test_bit(apicid, phys_cpu_present_map));
+ }
+}
+
+/*
+ * Late SMP disable after sizing CPU masks when APIC/IOAPIC setup failed.
+ */
+void __init topology_reset_possible_cpus_up(void)
+{
+ init_cpu_present(cpumask_of(0));
+ init_cpu_possible(cpumask_of(0));
+
+ bitmap_zero(phys_cpu_present_map, MAX_LOCAL_APIC);
+ if (topo_info.boot_cpu_apic_id != BAD_APICID)
+ set_bit(topo_info.boot_cpu_apic_id, phys_cpu_present_map);
+}
+
+static int __init setup_possible_cpus(char *str)
+{
+ get_option(&str, &max_possible_cpus);
return 0;
}
+early_param("possible_cpus", setup_possible_cpus);
+#endif
diff --git a/arch/x86/kernel/cpu/topology.h b/arch/x86/kernel/cpu/topology.h
new file mode 100644
index 000000000000..37326297f80c
--- /dev/null
+++ b/arch/x86/kernel/cpu/topology.h
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef ARCH_X86_TOPOLOGY_H
+#define ARCH_X86_TOPOLOGY_H
+
+struct topo_scan {
+ struct cpuinfo_x86 *c;
+ unsigned int dom_shifts[TOPO_MAX_DOMAIN];
+ unsigned int dom_ncpus[TOPO_MAX_DOMAIN];
+
+ /* Legacy CPUID[1]:EBX[23:16] number of logical processors */
+ unsigned int ebx1_nproc_shift;
+
+ /* AMD specific node ID which cannot be mapped into APIC space. */
+ u16 amd_nodes_per_pkg;
+ u16 amd_node_id;
+};
+
+void cpu_init_topology(struct cpuinfo_x86 *c);
+void cpu_parse_topology(struct cpuinfo_x86 *c);
+void topology_set_dom(struct topo_scan *tscan, enum x86_topology_domains dom,
+ unsigned int shift, unsigned int ncpus);
+bool cpu_parse_topology_ext(struct topo_scan *tscan);
+void cpu_parse_topology_amd(struct topo_scan *tscan);
+void cpu_topology_fixup_amd(struct topo_scan *tscan);
+
+static inline u32 topo_shift_apicid(u32 apicid, enum x86_topology_domains dom)
+{
+ if (dom == TOPO_SMT_DOMAIN)
+ return apicid;
+ return apicid >> x86_topo_system.dom_shifts[dom - 1];
+}
+
+static inline u32 topo_relative_domain_id(u32 apicid, enum x86_topology_domains dom)
+{
+ if (dom != TOPO_SMT_DOMAIN)
+ apicid >>= x86_topo_system.dom_shifts[dom - 1];
+ return apicid & (x86_topo_system.dom_size[dom] - 1);
+}
+
+static inline u32 topo_domain_mask(enum x86_topology_domains dom)
+{
+ return (1U << x86_topo_system.dom_shifts[dom]) - 1;
+}
+
+/*
+ * Update a domain level after the fact without propagating. Used to fixup
+ * broken CPUID enumerations.
+ */
+static inline void topology_update_dom(struct topo_scan *tscan, enum x86_topology_domains dom,
+ unsigned int shift, unsigned int ncpus)
+{
+ tscan->dom_shifts[dom] = shift;
+ tscan->dom_ncpus[dom] = ncpus;
+}
+
+#ifdef CONFIG_X86_LOCAL_APIC
+unsigned int topology_unit_count(u32 apicid, enum x86_topology_domains which_units,
+ enum x86_topology_domains at_level);
+#else
+static inline unsigned int topology_unit_count(u32 apicid, enum x86_topology_domains which_units,
+ enum x86_topology_domains at_level)
+{
+ return 1;
+}
+#endif
+
+#endif /* ARCH_X86_TOPOLOGY_H */
diff --git a/arch/x86/kernel/cpu/topology_amd.c b/arch/x86/kernel/cpu/topology_amd.c
new file mode 100644
index 000000000000..1a8b3ad493af
--- /dev/null
+++ b/arch/x86/kernel/cpu/topology_amd.c
@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/cpu.h>
+
+#include <asm/apic.h>
+#include <asm/memtype.h>
+#include <asm/processor.h>
+
+#include "cpu.h"
+
+static bool parse_8000_0008(struct topo_scan *tscan)
+{
+ struct {
+ // ecx
+ u32 cpu_nthreads : 8, // Number of physical threads - 1
+ : 4, // Reserved
+ apicid_coreid_len : 4, // Number of thread core ID bits (shift) in APIC ID
+ perf_tsc_len : 2, // Performance time-stamp counter size
+ : 14; // Reserved
+ } ecx;
+ unsigned int sft;
+
+ if (tscan->c->extended_cpuid_level < 0x80000008)
+ return false;
+
+ cpuid_leaf_reg(0x80000008, CPUID_ECX, &ecx);
+
+ /* If the thread bits are 0, then get the shift value from ecx.cpu_nthreads */
+ sft = ecx.apicid_coreid_len;
+ if (!sft)
+ sft = get_count_order(ecx.cpu_nthreads + 1);
+
+ topology_set_dom(tscan, TOPO_SMT_DOMAIN, sft, ecx.cpu_nthreads + 1);
+ return true;
+}
+
+static void store_node(struct topo_scan *tscan, unsigned int nr_nodes, u16 node_id)
+{
+ /*
+ * Starting with Fam 17h the DIE domain could probably be used to
+ * retrieve the node info on AMD/HYGON. Analysis of CPUID dumps
+ * suggests it's the topmost bit(s) of the CPU cores area, but
+ * that's guess work and neither enumerated nor documented.
+ *
+ * Up to Fam 16h this does not work at all and the legacy node ID
+ * has to be used.
+ */
+ tscan->amd_nodes_per_pkg = nr_nodes;
+ tscan->amd_node_id = node_id;
+}
+
+static bool parse_8000_001e(struct topo_scan *tscan, bool has_0xb)
+{
+ struct {
+ // eax
+ u32 ext_apic_id : 32; // Extended APIC ID
+ // ebx
+ u32 core_id : 8, // Unique per-socket logical core unit ID
+ core_nthreads : 8, // #Threads per core (zero-based)
+ : 16; // Reserved
+ // ecx
+ u32 node_id : 8, // Node (die) ID of invoking logical CPU
+ nnodes_per_socket : 3, // #nodes in invoking logical CPU's package/socket
+ : 21; // Reserved
+ // edx
+ u32 : 32; // Reserved
+ } leaf;
+
+ if (!boot_cpu_has(X86_FEATURE_TOPOEXT))
+ return false;
+
+ cpuid_leaf(0x8000001e, &leaf);
+
+ tscan->c->topo.initial_apicid = leaf.ext_apic_id;
+
+ /*
+ * If leaf 0xb is available, then SMT shift is set already. If not
+ * take it from ecx.threads_per_core and use topo_update_dom() -
+ * topology_set_dom() would propagate and overwrite the already
+ * propagated CORE level.
+ */
+ if (!has_0xb) {
+ unsigned int nthreads = leaf.core_nthreads + 1;
+
+ topology_update_dom(tscan, TOPO_SMT_DOMAIN, get_count_order(nthreads), nthreads);
+ }
+
+ store_node(tscan, leaf.nnodes_per_socket + 1, leaf.node_id);
+
+ if (tscan->c->x86_vendor == X86_VENDOR_AMD) {
+ if (tscan->c->x86 == 0x15)
+ tscan->c->topo.cu_id = leaf.core_id;
+
+ cacheinfo_amd_init_llc_id(tscan->c, leaf.node_id);
+ } else {
+ /*
+ * Package ID is ApicId[6..] on certain Hygon CPUs. See
+ * commit e0ceeae708ce for explanation. The topology info
+ * is screwed up: The package shift is always 6 and the
+ * node ID is bit [4:5].
+ */
+ if (!boot_cpu_has(X86_FEATURE_HYPERVISOR) && tscan->c->x86_model <= 0x3) {
+ topology_set_dom(tscan, TOPO_CORE_DOMAIN, 6,
+ tscan->dom_ncpus[TOPO_CORE_DOMAIN]);
+ }
+ cacheinfo_hygon_init_llc_id(tscan->c);
+ }
+ return true;
+}
+
+static bool parse_fam10h_node_id(struct topo_scan *tscan)
+{
+ struct {
+ union {
+ u64 node_id : 3,
+ nodes_per_pkg : 3,
+ unused : 58;
+ u64 msr;
+ };
+ } nid;
+
+ if (!boot_cpu_has(X86_FEATURE_NODEID_MSR))
+ return false;
+
+ 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];
+}
+
+static void parse_topology_amd(struct topo_scan *tscan)
+{
+ bool has_0xb = 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.
+ */
+ if (cpu_feature_enabled(X86_FEATURE_TOPOEXT))
+ has_0xb = cpu_parse_topology_ext(tscan);
+
+ if (!has_0xb && !parse_8000_0008(tscan))
+ return;
+
+ /* Prefer leaf 0x8000001e if available */
+ if (parse_8000_001e(tscan, has_0xb))
+ return;
+
+ /* Try the NODEID MSR */
+ if (parse_fam10h_node_id(tscan))
+ return;
+
+ legacy_set_llc(tscan);
+}
+
+void cpu_parse_topology_amd(struct topo_scan *tscan)
+{
+ tscan->amd_nodes_per_pkg = 1;
+ parse_topology_amd(tscan);
+
+ if (tscan->amd_nodes_per_pkg > 1)
+ set_cpu_cap(tscan->c, X86_FEATURE_AMD_DCM);
+}
+
+void cpu_topology_fixup_amd(struct topo_scan *tscan)
+{
+ struct cpuinfo_x86 *c = tscan->c;
+
+ /*
+ * Adjust the core_id relative to the node when there is more than
+ * one node.
+ */
+ if (tscan->c->x86 < 0x17 && tscan->amd_nodes_per_pkg > 1)
+ c->topo.core_id %= tscan->dom_ncpus[TOPO_CORE_DOMAIN] / tscan->amd_nodes_per_pkg;
+}
diff --git a/arch/x86/kernel/cpu/topology_common.c b/arch/x86/kernel/cpu/topology_common.c
new file mode 100644
index 000000000000..9a6069e7133c
--- /dev/null
+++ b/arch/x86/kernel/cpu/topology_common.c
@@ -0,0 +1,220 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/cpu.h>
+
+#include <xen/xen.h>
+
+#include <asm/apic.h>
+#include <asm/processor.h>
+#include <asm/smp.h>
+
+#include "cpu.h"
+
+struct x86_topology_system x86_topo_system __ro_after_init;
+EXPORT_SYMBOL_GPL(x86_topo_system);
+
+unsigned int __amd_nodes_per_pkg __ro_after_init;
+EXPORT_SYMBOL_GPL(__amd_nodes_per_pkg);
+
+void topology_set_dom(struct topo_scan *tscan, enum x86_topology_domains dom,
+ unsigned int shift, unsigned int ncpus)
+{
+ topology_update_dom(tscan, dom, shift, ncpus);
+
+ /* Propagate to the upper levels */
+ for (dom++; dom < TOPO_MAX_DOMAIN; dom++) {
+ tscan->dom_shifts[dom] = tscan->dom_shifts[dom - 1];
+ tscan->dom_ncpus[dom] = tscan->dom_ncpus[dom - 1];
+ }
+}
+
+static unsigned int __maybe_unused parse_num_cores_legacy(struct cpuinfo_x86 *c)
+{
+ struct {
+ u32 cache_type : 5,
+ unused : 21,
+ ncores : 6;
+ } eax;
+
+ if (c->cpuid_level < 4)
+ return 1;
+
+ cpuid_subleaf_reg(4, 0, CPUID_EAX, &eax);
+ if (!eax.cache_type)
+ return 1;
+
+ return eax.ncores + 1;
+}
+
+static void parse_legacy(struct topo_scan *tscan)
+{
+ unsigned int cores, core_shift, smt_shift = 0;
+ struct cpuinfo_x86 *c = tscan->c;
+
+ cores = parse_num_cores_legacy(c);
+ core_shift = get_count_order(cores);
+
+ if (cpu_has(c, X86_FEATURE_HT)) {
+ if (!WARN_ON_ONCE(tscan->ebx1_nproc_shift < core_shift))
+ smt_shift = tscan->ebx1_nproc_shift - core_shift;
+ /*
+ * The parser expects leaf 0xb/0x1f format, which means
+ * the number of logical processors at core level is
+ * counting threads.
+ */
+ core_shift += smt_shift;
+ cores <<= smt_shift;
+ }
+
+ topology_set_dom(tscan, TOPO_SMT_DOMAIN, smt_shift, 1U << smt_shift);
+ topology_set_dom(tscan, TOPO_CORE_DOMAIN, core_shift, cores);
+}
+
+static bool fake_topology(struct topo_scan *tscan)
+{
+ /*
+ * Preset the CORE level shift for CPUID less systems and XEN_PV,
+ * which has useless CPUID information.
+ */
+ topology_set_dom(tscan, TOPO_SMT_DOMAIN, 0, 1);
+ topology_set_dom(tscan, TOPO_CORE_DOMAIN, 0, 1);
+
+ return tscan->c->cpuid_level < 1;
+}
+
+static void parse_topology(struct topo_scan *tscan, bool early)
+{
+ const struct cpuinfo_topology topo_defaults = {
+ .cu_id = 0xff,
+ .llc_id = BAD_APICID,
+ .l2c_id = BAD_APICID,
+ };
+ struct cpuinfo_x86 *c = tscan->c;
+ struct {
+ u32 unused0 : 16,
+ nproc : 8,
+ apicid : 8;
+ } ebx;
+
+ c->topo = topo_defaults;
+
+ if (fake_topology(tscan))
+ return;
+
+ /* Preset Initial APIC ID from CPUID leaf 1 */
+ cpuid_leaf_reg(1, CPUID_EBX, &ebx);
+ c->topo.initial_apicid = ebx.apicid;
+
+ /*
+ * The initial invocation from early_identify_cpu() happens before
+ * the APIC is mapped or X2APIC enabled. For establishing the
+ * topology, that's not required. Use the initial APIC ID.
+ */
+ if (early)
+ c->topo.apicid = c->topo.initial_apicid;
+ else
+ c->topo.apicid = read_apic_id();
+
+ /* The above is sufficient for UP */
+ if (!IS_ENABLED(CONFIG_SMP))
+ return;
+
+ tscan->ebx1_nproc_shift = get_count_order(ebx.nproc);
+
+ switch (c->x86_vendor) {
+ case X86_VENDOR_AMD:
+ if (IS_ENABLED(CONFIG_CPU_SUP_AMD))
+ cpu_parse_topology_amd(tscan);
+ break;
+ case X86_VENDOR_CENTAUR:
+ case X86_VENDOR_ZHAOXIN:
+ parse_legacy(tscan);
+ break;
+ case X86_VENDOR_INTEL:
+ if (!IS_ENABLED(CONFIG_CPU_SUP_INTEL) || !cpu_parse_topology_ext(tscan))
+ parse_legacy(tscan);
+ break;
+ case X86_VENDOR_HYGON:
+ if (IS_ENABLED(CONFIG_CPU_SUP_HYGON))
+ cpu_parse_topology_amd(tscan);
+ break;
+ }
+}
+
+static void topo_set_ids(struct topo_scan *tscan, bool early)
+{
+ struct cpuinfo_x86 *c = tscan->c;
+ u32 apicid = c->topo.apicid;
+
+ c->topo.pkg_id = topo_shift_apicid(apicid, TOPO_PKG_DOMAIN);
+ c->topo.die_id = topo_shift_apicid(apicid, TOPO_DIE_DOMAIN);
+
+ if (!early) {
+ c->topo.logical_pkg_id = topology_get_logical_id(apicid, TOPO_PKG_DOMAIN);
+ c->topo.logical_die_id = topology_get_logical_id(apicid, TOPO_DIE_DOMAIN);
+ }
+
+ /* Package relative core ID */
+ c->topo.core_id = (apicid & topo_domain_mask(TOPO_PKG_DOMAIN)) >>
+ x86_topo_system.dom_shifts[TOPO_SMT_DOMAIN];
+
+ c->topo.amd_node_id = tscan->amd_node_id;
+
+ if (c->x86_vendor == X86_VENDOR_AMD)
+ cpu_topology_fixup_amd(tscan);
+}
+
+void cpu_parse_topology(struct cpuinfo_x86 *c)
+{
+ unsigned int dom, cpu = smp_processor_id();
+ struct topo_scan tscan = { .c = c, };
+
+ parse_topology(&tscan, false);
+
+ if (IS_ENABLED(CONFIG_X86_LOCAL_APIC)) {
+ if (c->topo.initial_apicid != c->topo.apicid) {
+ pr_err(FW_BUG "CPU%4u: APIC ID mismatch. CPUID: 0x%04x APIC: 0x%04x\n",
+ cpu, c->topo.initial_apicid, c->topo.apicid);
+ }
+
+ if (c->topo.apicid != cpuid_to_apicid[cpu]) {
+ pr_err(FW_BUG "CPU%4u: APIC ID mismatch. Firmware: 0x%04x APIC: 0x%04x\n",
+ cpu, cpuid_to_apicid[cpu], c->topo.apicid);
+ }
+ }
+
+ for (dom = TOPO_SMT_DOMAIN; dom < TOPO_MAX_DOMAIN; dom++) {
+ if (tscan.dom_shifts[dom] == x86_topo_system.dom_shifts[dom])
+ continue;
+ pr_err(FW_BUG "CPU%d: Topology domain %u shift %u != %u\n", cpu, dom,
+ tscan.dom_shifts[dom], x86_topo_system.dom_shifts[dom]);
+ }
+
+ topo_set_ids(&tscan, false);
+}
+
+void __init cpu_init_topology(struct cpuinfo_x86 *c)
+{
+ struct topo_scan tscan = { .c = c, };
+ unsigned int dom, sft;
+
+ parse_topology(&tscan, true);
+
+ /* Copy the shift values and calculate the unit sizes. */
+ memcpy(x86_topo_system.dom_shifts, tscan.dom_shifts, sizeof(x86_topo_system.dom_shifts));
+
+ dom = TOPO_SMT_DOMAIN;
+ x86_topo_system.dom_size[dom] = 1U << x86_topo_system.dom_shifts[dom];
+
+ for (dom++; dom < TOPO_MAX_DOMAIN; dom++) {
+ sft = x86_topo_system.dom_shifts[dom] - x86_topo_system.dom_shifts[dom - 1];
+ x86_topo_system.dom_size[dom] = 1U << sft;
+ }
+
+ topo_set_ids(&tscan, true);
+
+ /*
+ * AMD systems have Nodes per package which cannot be mapped to
+ * APIC ID.
+ */
+ __amd_nodes_per_pkg = tscan.amd_nodes_per_pkg;
+}
diff --git a/arch/x86/kernel/cpu/topology_ext.c b/arch/x86/kernel/cpu/topology_ext.c
new file mode 100644
index 000000000000..e477228cd5b2
--- /dev/null
+++ b/arch/x86/kernel/cpu/topology_ext.c
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/cpu.h>
+
+#include <asm/apic.h>
+#include <asm/memtype.h>
+#include <asm/processor.h>
+
+#include "cpu.h"
+
+enum topo_types {
+ INVALID_TYPE = 0,
+ SMT_TYPE = 1,
+ CORE_TYPE = 2,
+ MAX_TYPE_0B = 3,
+ MODULE_TYPE = 3,
+ TILE_TYPE = 4,
+ DIE_TYPE = 5,
+ DIEGRP_TYPE = 6,
+ MAX_TYPE_1F = 7,
+};
+
+/*
+ * Use a lookup table for the case that there are future types > 6 which
+ * describe an intermediate domain level which does not exist today.
+ */
+static const unsigned int topo_domain_map_0b_1f[MAX_TYPE_1F] = {
+ [SMT_TYPE] = TOPO_SMT_DOMAIN,
+ [CORE_TYPE] = TOPO_CORE_DOMAIN,
+ [MODULE_TYPE] = TOPO_MODULE_DOMAIN,
+ [TILE_TYPE] = TOPO_TILE_DOMAIN,
+ [DIE_TYPE] = TOPO_DIE_DOMAIN,
+ [DIEGRP_TYPE] = TOPO_DIEGRP_DOMAIN,
+};
+
+static inline bool topo_subleaf(struct topo_scan *tscan, u32 leaf, u32 subleaf,
+ unsigned int *last_dom)
+{
+ unsigned int dom, maxtype;
+ const unsigned int *map;
+ struct {
+ // eax
+ u32 x2apic_shift : 5, // Number of bits to shift APIC ID right
+ // for the topology ID at the next level
+ : 27; // Reserved
+ // ebx
+ u32 num_processors : 16, // Number of processors at current level
+ : 16; // Reserved
+ // ecx
+ u32 level : 8, // Current topology level. Same as sub leaf number
+ type : 8, // Level type. If 0, invalid
+ : 16; // Reserved
+ // edx
+ u32 x2apic_id : 32; // X2APIC ID of the current logical processor
+ } sl;
+
+ 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;
+ default: return false;
+ }
+
+ cpuid_subleaf(leaf, subleaf, &sl);
+
+ if (!sl.num_processors || sl.type == INVALID_TYPE)
+ return false;
+
+ if (sl.type >= maxtype) {
+ pr_err_once("Topology: leaf 0x%x:%d Unknown domain type %u\n",
+ leaf, subleaf, sl.type);
+ /*
+ * It really would have been too obvious to make the domain
+ * type space sparse and leave a few reserved types between
+ * the points which might change instead of following the
+ * usual "this can be fixed in software" principle.
+ */
+ dom = *last_dom + 1;
+ } else {
+ dom = map[sl.type];
+ *last_dom = dom;
+ }
+
+ if (!dom) {
+ tscan->c->topo.initial_apicid = sl.x2apic_id;
+ } else if (tscan->c->topo.initial_apicid != sl.x2apic_id) {
+ pr_warn_once(FW_BUG "CPUID leaf 0x%x subleaf %d APIC ID mismatch %x != %x\n",
+ leaf, subleaf, tscan->c->topo.initial_apicid, sl.x2apic_id);
+ }
+
+ topology_set_dom(tscan, dom, sl.x2apic_shift, sl.num_processors);
+ return true;
+}
+
+static bool parse_topology_leaf(struct topo_scan *tscan, u32 leaf)
+{
+ unsigned int last_dom;
+ u32 subleaf;
+
+ /* Read all available subleafs and populate the levels */
+ for (subleaf = 0, last_dom = 0; topo_subleaf(tscan, leaf, subleaf, &last_dom); subleaf++);
+
+ /* If subleaf 0 failed to parse, give up */
+ if (!subleaf)
+ return false;
+
+ /*
+ * There are machines in the wild which have shift 0 in the subleaf
+ * 0, but advertise 2 logical processors at that level. They are
+ * truly SMT.
+ */
+ if (!tscan->dom_shifts[TOPO_SMT_DOMAIN] && tscan->dom_ncpus[TOPO_SMT_DOMAIN] > 1) {
+ unsigned int sft = get_count_order(tscan->dom_ncpus[TOPO_SMT_DOMAIN]);
+
+ pr_warn_once(FW_BUG "CPUID leaf 0x%x subleaf 0 has shift level 0 but %u CPUs. Fixing it up.\n",
+ leaf, tscan->dom_ncpus[TOPO_SMT_DOMAIN]);
+ topology_update_dom(tscan, TOPO_SMT_DOMAIN, sft, tscan->dom_ncpus[TOPO_SMT_DOMAIN]);
+ }
+
+ set_cpu_cap(tscan->c, X86_FEATURE_XTOPOLOGY);
+ return true;
+}
+
+bool cpu_parse_topology_ext(struct topo_scan *tscan)
+{
+ /* Intel: Try leaf 0x1F first. */
+ if (tscan->c->cpuid_level >= 0x1f && parse_topology_leaf(tscan, 0x1f))
+ 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/zhaoxin.c b/arch/x86/kernel/cpu/zhaoxin.c
index 415564a6523b..90eba7eb5335 100644
--- a/arch/x86/kernel/cpu/zhaoxin.c
+++ b/arch/x86/kernel/cpu/zhaoxin.c
@@ -71,10 +71,6 @@ static void init_zhaoxin(struct cpuinfo_x86 *c)
{
early_init_zhaoxin(c);
init_intel_cacheinfo(c);
- detect_num_cpu_cores(c);
-#ifdef CONFIG_X86_32
- detect_ht(c);
-#endif
if (c->cpuid_level > 9) {
unsigned int eax = cpuid_eax(10);
diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
index b6b044356f1b..e74d0c4286c1 100644
--- a/arch/x86/kernel/crash.c
+++ b/arch/x86/kernel/crash.c
@@ -26,6 +26,7 @@
#include <linux/vmalloc.h>
#include <linux/memblock.h>
+#include <asm/bootparam.h>
#include <asm/processor.h>
#include <asm/hardirq.h>
#include <asm/nmi.h>
@@ -40,6 +41,7 @@
#include <asm/intel_pt.h>
#include <asm/crash.h>
#include <asm/cmdline.h>
+#include <asm/sev.h>
/* Used while preparing memory map entries for second kernel */
struct crash_memmap_data {
@@ -59,6 +61,8 @@ static void kdump_nmi_callback(int cpu, struct pt_regs *regs)
*/
cpu_emergency_stop_pt();
+ kdump_sev_callback();
+
disable_local_APIC();
}
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
index afd09924094e..003e0298f46a 100644
--- a/arch/x86/kernel/devicetree.c
+++ b/arch/x86/kernel/devicetree.c
@@ -136,7 +136,7 @@ static void __init dtb_cpu_setup(void)
pr_warn("%pOF: missing local APIC ID\n", dn);
continue;
}
- generic_processor_info(apic_id);
+ topology_register_apic(apic_id, CPU_ACPIID_INVALID, true);
}
}
@@ -283,26 +283,28 @@ void __init x86_flattree_get_config(void)
u32 size, map_len;
void *dt;
- if (!initial_dtb)
- return;
+ if (initial_dtb) {
+ map_len = max(PAGE_SIZE - (initial_dtb & ~PAGE_MASK), (u64)128);
- map_len = max(PAGE_SIZE - (initial_dtb & ~PAGE_MASK), (u64)128);
+ dt = early_memremap(initial_dtb, map_len);
+ size = fdt_totalsize(dt);
+ if (map_len < size) {
+ early_memunmap(dt, map_len);
+ dt = early_memremap(initial_dtb, size);
+ map_len = size;
+ }
- dt = early_memremap(initial_dtb, map_len);
- size = fdt_totalsize(dt);
- if (map_len < size) {
- early_memunmap(dt, map_len);
- dt = early_memremap(initial_dtb, size);
- map_len = size;
+ early_init_dt_verify(dt);
}
- early_init_dt_verify(dt);
unflatten_and_copy_device_tree();
- early_memunmap(dt, map_len);
+
+ if (initial_dtb)
+ early_memunmap(dt, map_len);
}
#endif
-void __init x86_dtb_init(void)
+void __init x86_dtb_parse_smp_config(void)
{
if (!of_have_populated_dt())
return;
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c
index f18ca44c904b..44a91ef5a23b 100644
--- a/arch/x86/kernel/dumpstack.c
+++ b/arch/x86/kernel/dumpstack.c
@@ -410,7 +410,7 @@ static void __die_header(const char *str, struct pt_regs *regs, long err)
IS_ENABLED(CONFIG_SMP) ? " SMP" : "",
debug_pagealloc_enabled() ? " DEBUG_PAGEALLOC" : "",
IS_ENABLED(CONFIG_KASAN) ? " KASAN" : "",
- IS_ENABLED(CONFIG_PAGE_TABLE_ISOLATION) ?
+ IS_ENABLED(CONFIG_MITIGATION_PAGE_TABLE_ISOLATION) ?
(boot_cpu_has(X86_FEATURE_PTI) ? " PTI" : " NOPTI") : "");
}
NOKPROBE_SYMBOL(__die_header);
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index b66f540de054..6f1b379e3b38 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -1016,17 +1016,6 @@ void __init e820__reserve_setup_data(void)
e820__range_update(pa_data, sizeof(*data)+data->len, E820_TYPE_RAM, E820_TYPE_RESERVED_KERN);
- /*
- * SETUP_EFI, SETUP_IMA and SETUP_RNG_SEED are supplied by
- * kexec and do not need to be reserved.
- */
- if (data->type != SETUP_EFI &&
- data->type != SETUP_IMA &&
- data->type != SETUP_RNG_SEED)
- e820__range_update_kexec(pa_data,
- sizeof(*data) + data->len,
- E820_TYPE_RAM, E820_TYPE_RESERVED_KERN);
-
if (data->type == SETUP_INDIRECT) {
len += data->len;
early_memunmap(data, sizeof(*data));
@@ -1038,12 +1027,9 @@ void __init e820__reserve_setup_data(void)
indirect = (struct setup_indirect *)data->data;
- if (indirect->type != SETUP_INDIRECT) {
+ if (indirect->type != SETUP_INDIRECT)
e820__range_update(indirect->addr, indirect->len,
E820_TYPE_RAM, E820_TYPE_RESERVED_KERN);
- e820__range_update_kexec(indirect->addr, indirect->len,
- E820_TYPE_RAM, E820_TYPE_RESERVED_KERN);
- }
}
pa_data = pa_next;
@@ -1051,7 +1037,6 @@ void __init e820__reserve_setup_data(void)
}
e820__update_table(e820_table);
- e820__update_table(e820_table_kexec);
pr_info("extended physical RAM map:\n");
e820__print_table("reserve setup_data");
diff --git a/arch/x86/kernel/eisa.c b/arch/x86/kernel/eisa.c
index e963344b0449..53935b4d62e3 100644
--- a/arch/x86/kernel/eisa.c
+++ b/arch/x86/kernel/eisa.c
@@ -2,6 +2,7 @@
/*
* EISA specific code
*/
+#include <linux/cc_platform.h>
#include <linux/ioport.h>
#include <linux/eisa.h>
#include <linux/io.h>
@@ -12,7 +13,7 @@ static __init int eisa_bus_probe(void)
{
void __iomem *p;
- if (xen_pv_domain() && !xen_initial_domain())
+ if ((xen_pv_domain() && !xen_initial_domain()) || cc_platform_has(CC_ATTR_GUEST_SEV_SNP))
return 0;
p = ioremap(0x0FFFD9, 4);
diff --git a/arch/x86/kernel/espfix_64.c b/arch/x86/kernel/espfix_64.c
index 16f9814c9be0..6726e0473d0b 100644
--- a/arch/x86/kernel/espfix_64.c
+++ b/arch/x86/kernel/espfix_64.c
@@ -106,6 +106,10 @@ void __init init_espfix_bsp(void)
pgd_t *pgd;
p4d_t *p4d;
+ /* FRED systems always restore the full value of %rsp */
+ if (cpu_feature_enabled(X86_FEATURE_FRED))
+ return;
+
/* Install the espfix pud into the kernel page directory */
pgd = &init_top_pgt[pgd_index(ESPFIX_BASE_ADDR)];
p4d = p4d_alloc(&init_mm, pgd, ESPFIX_BASE_ADDR);
@@ -129,6 +133,10 @@ void init_espfix_ap(int cpu)
void *stack_page;
pteval_t ptemask;
+ /* FRED systems always restore the full value of %rsp */
+ if (cpu_feature_enabled(X86_FEATURE_FRED))
+ return;
+
/* We only have to do this once... */
if (likely(per_cpu(espfix_stack, cpu)))
return; /* Already initialized */
diff --git a/arch/x86/kernel/fpu/bugs.c b/arch/x86/kernel/fpu/bugs.c
index a06b876bbf2d..edbafc5940e3 100644
--- a/arch/x86/kernel/fpu/bugs.c
+++ b/arch/x86/kernel/fpu/bugs.c
@@ -2,6 +2,8 @@
/*
* x86 FPU bug checks:
*/
+#include <linux/printk.h>
+
#include <asm/cpufeature.h>
#include <asm/fpu/api.h>
diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index 117e74c44e75..33a214b1a4ce 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -178,10 +178,11 @@ void fpu__init_cpu_xstate(void)
* Must happen after CR4 setup and before xsetbv() to allow KVM
* lazy passthrough. Write independent of the dynamic state static
* key as that does not work on the boot CPU. This also ensures
- * that any stale state is wiped out from XFD.
+ * that any stale state is wiped out from XFD. Reset the per CPU
+ * xfd cache too.
*/
if (cpu_feature_enabled(X86_FEATURE_XFD))
- wrmsrl(MSR_IA32_XFD, init_fpstate.xfd);
+ xfd_set_state(init_fpstate.xfd);
/*
* XCR_XFEATURE_ENABLED_MASK (aka. XCR0) sets user features
diff --git a/arch/x86/kernel/fpu/xstate.h b/arch/x86/kernel/fpu/xstate.h
index 3518fb26d06b..19ca623ffa2a 100644
--- a/arch/x86/kernel/fpu/xstate.h
+++ b/arch/x86/kernel/fpu/xstate.h
@@ -148,20 +148,26 @@ static inline void xfd_validate_state(struct fpstate *fpstate, u64 mask, bool rs
#endif
#ifdef CONFIG_X86_64
+static inline void xfd_set_state(u64 xfd)
+{
+ wrmsrl(MSR_IA32_XFD, xfd);
+ __this_cpu_write(xfd_state, xfd);
+}
+
static inline void xfd_update_state(struct fpstate *fpstate)
{
if (fpu_state_size_dynamic()) {
u64 xfd = fpstate->xfd;
- if (__this_cpu_read(xfd_state) != xfd) {
- wrmsrl(MSR_IA32_XFD, xfd);
- __this_cpu_write(xfd_state, xfd);
- }
+ if (__this_cpu_read(xfd_state) != xfd)
+ xfd_set_state(xfd);
}
}
extern int __xfd_enable_feature(u64 which, struct fpu_guest *guest_fpu);
#else
+static inline void xfd_set_state(u64 xfd) { }
+
static inline void xfd_update_state(struct fpstate *fpstate) { }
static inline int __xfd_enable_feature(u64 which, struct fpu_guest *guest_fpu) {
diff --git a/arch/x86/kernel/fred.c b/arch/x86/kernel/fred.c
new file mode 100644
index 000000000000..4bcd8791ad96
--- /dev/null
+++ b/arch/x86/kernel/fred.c
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <linux/kernel.h>
+
+#include <asm/desc.h>
+#include <asm/fred.h>
+#include <asm/tlbflush.h>
+#include <asm/traps.h>
+
+/* #DB in the kernel would imply the use of a kernel debugger. */
+#define FRED_DB_STACK_LEVEL 1UL
+#define FRED_NMI_STACK_LEVEL 2UL
+#define FRED_MC_STACK_LEVEL 2UL
+/*
+ * #DF is the highest level because a #DF means "something went wrong
+ * *while delivering an exception*." The number of cases for which that
+ * can happen with FRED is drastically reduced and basically amounts to
+ * "the stack you pointed me to is broken." Thus, always change stacks
+ * on #DF, which means it should be at the highest level.
+ */
+#define FRED_DF_STACK_LEVEL 3UL
+
+#define FRED_STKLVL(vector, lvl) ((lvl) << (2 * (vector)))
+
+void cpu_init_fred_exceptions(void)
+{
+ /* When FRED is enabled by default, remove this log message */
+ pr_info("Initialize FRED on CPU%d\n", smp_processor_id());
+
+ wrmsrl(MSR_IA32_FRED_CONFIG,
+ /* Reserve for CALL emulation */
+ FRED_CONFIG_REDZONE |
+ FRED_CONFIG_INT_STKLVL(0) |
+ FRED_CONFIG_ENTRYPOINT(asm_fred_entrypoint_user));
+
+ /*
+ * The purpose of separate stacks for NMI, #DB and #MC *in the kernel*
+ * (remember that user space faults are always taken on stack level 0)
+ * is to avoid overflowing the kernel stack.
+ */
+ wrmsrl(MSR_IA32_FRED_STKLVLS,
+ FRED_STKLVL(X86_TRAP_DB, FRED_DB_STACK_LEVEL) |
+ FRED_STKLVL(X86_TRAP_NMI, FRED_NMI_STACK_LEVEL) |
+ FRED_STKLVL(X86_TRAP_MC, FRED_MC_STACK_LEVEL) |
+ FRED_STKLVL(X86_TRAP_DF, FRED_DF_STACK_LEVEL));
+
+ /* The FRED equivalents to IST stacks... */
+ wrmsrl(MSR_IA32_FRED_RSP1, __this_cpu_ist_top_va(DB));
+ wrmsrl(MSR_IA32_FRED_RSP2, __this_cpu_ist_top_va(NMI));
+ wrmsrl(MSR_IA32_FRED_RSP3, __this_cpu_ist_top_va(DF));
+
+ /* Enable FRED */
+ cr4_set_bits(X86_CR4_FRED);
+ /* Any further IDT use is a bug */
+ idt_invalidate();
+
+ /* Use int $0x80 for 32-bit system calls in FRED mode */
+ setup_clear_cpu_cap(X86_FEATURE_SYSENTER32);
+ setup_clear_cpu_cap(X86_FEATURE_SYSCALL32);
+}
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c
index 12df54ff0e81..70139d9d2e01 100644
--- a/arch/x86/kernel/ftrace.c
+++ b/arch/x86/kernel/ftrace.c
@@ -307,7 +307,8 @@ union ftrace_op_code_union {
} __attribute__((packed));
};
-#define RET_SIZE (IS_ENABLED(CONFIG_RETPOLINE) ? 5 : 1 + IS_ENABLED(CONFIG_SLS))
+#define RET_SIZE \
+ (IS_ENABLED(CONFIG_MITIGATION_RETPOLINE) ? 5 : 1 + IS_ENABLED(CONFIG_MITIGATION_SLS))
static unsigned long
create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size)
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index dc0956067944..a817ed0724d1 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -22,6 +22,8 @@
#include <linux/cc_platform.h>
#include <linux/pgtable.h>
+#include <asm/asm.h>
+#include <asm/page_64.h>
#include <asm/processor.h>
#include <asm/proto.h>
#include <asm/smp.h>
@@ -67,42 +69,11 @@ unsigned long vmemmap_base __ro_after_init = __VMEMMAP_BASE_L4;
EXPORT_SYMBOL(vmemmap_base);
#endif
-/*
- * GDT used on the boot CPU before switching to virtual addresses.
- */
-static struct desc_struct startup_gdt[GDT_ENTRIES] __initdata = {
- [GDT_ENTRY_KERNEL32_CS] = GDT_ENTRY_INIT(DESC_CODE32, 0, 0xfffff),
- [GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(DESC_CODE64, 0, 0xfffff),
- [GDT_ENTRY_KERNEL_DS] = GDT_ENTRY_INIT(DESC_DATA64, 0, 0xfffff),
-};
-
-/*
- * Address needs to be set at runtime because it references the startup_gdt
- * while the kernel still uses a direct mapping.
- */
-static struct desc_ptr startup_gdt_descr __initdata = {
- .size = sizeof(startup_gdt)-1,
- .address = 0,
-};
-
-static void __head *fixup_pointer(void *ptr, unsigned long physaddr)
-{
- return ptr - (void *)_text + (void *)physaddr;
-}
-
-static unsigned long __head *fixup_long(void *ptr, unsigned long physaddr)
+static inline bool check_la57_support(void)
{
- return fixup_pointer(ptr, physaddr);
-}
-
-#ifdef CONFIG_X86_5LEVEL
-static unsigned int __head *fixup_int(void *ptr, unsigned long physaddr)
-{
- return fixup_pointer(ptr, physaddr);
-}
+ if (!IS_ENABLED(CONFIG_X86_5LEVEL))
+ return false;
-static bool __head check_la57_support(unsigned long physaddr)
-{
/*
* 5-level paging is detected and enabled at kernel decompression
* stage. Only check if it has been enabled there.
@@ -110,21 +81,15 @@ static bool __head check_la57_support(unsigned long physaddr)
if (!(native_read_cr4() & X86_CR4_LA57))
return false;
- *fixup_int(&__pgtable_l5_enabled, physaddr) = 1;
- *fixup_int(&pgdir_shift, physaddr) = 48;
- *fixup_int(&ptrs_per_p4d, physaddr) = 512;
- *fixup_long(&page_offset_base, physaddr) = __PAGE_OFFSET_BASE_L5;
- *fixup_long(&vmalloc_base, physaddr) = __VMALLOC_BASE_L5;
- *fixup_long(&vmemmap_base, physaddr) = __VMEMMAP_BASE_L5;
+ RIP_REL_REF(__pgtable_l5_enabled) = 1;
+ RIP_REL_REF(pgdir_shift) = 48;
+ RIP_REL_REF(ptrs_per_p4d) = 512;
+ RIP_REL_REF(page_offset_base) = __PAGE_OFFSET_BASE_L5;
+ RIP_REL_REF(vmalloc_base) = __VMALLOC_BASE_L5;
+ RIP_REL_REF(vmemmap_base) = __VMEMMAP_BASE_L5;
return true;
}
-#else
-static bool __head check_la57_support(unsigned long physaddr)
-{
- return false;
-}
-#endif
static unsigned long __head sme_postprocess_startup(struct boot_params *bp, pmdval_t *pmd)
{
@@ -173,23 +138,22 @@ static unsigned long __head sme_postprocess_startup(struct boot_params *bp, pmdv
* doesn't have to generate PC-relative relocations when accessing globals from
* that function. Clang actually does not generate them, which leads to
* boot-time crashes. To work around this problem, every global pointer must
- * be adjusted using fixup_pointer().
+ * be accessed using RIP_REL_REF().
*/
unsigned long __head __startup_64(unsigned long physaddr,
struct boot_params *bp)
{
- unsigned long load_delta, *p;
+ pmd_t (*early_pgts)[PTRS_PER_PMD] = RIP_REL_REF(early_dynamic_pgts);
unsigned long pgtable_flags;
+ unsigned long load_delta;
pgdval_t *pgd;
p4dval_t *p4d;
pudval_t *pud;
pmdval_t *pmd, pmd_entry;
- pteval_t *mask_ptr;
bool la57;
int i;
- unsigned int *next_pgt_ptr;
- la57 = check_la57_support(physaddr);
+ la57 = check_la57_support();
/* Is the address too large? */
if (physaddr >> MAX_PHYSMEM_BITS)
@@ -200,6 +164,7 @@ unsigned long __head __startup_64(unsigned long physaddr,
* and the address I am actually running at.
*/
load_delta = physaddr - (unsigned long)(_text - __START_KERNEL_map);
+ RIP_REL_REF(phys_base) = load_delta;
/* Is the address not 2M aligned? */
if (load_delta & ~PMD_MASK)
@@ -210,26 +175,21 @@ unsigned long __head __startup_64(unsigned long physaddr,
/* Fixup the physical addresses in the page table */
- pgd = fixup_pointer(early_top_pgt, physaddr);
- p = pgd + pgd_index(__START_KERNEL_map);
- if (la57)
- *p = (unsigned long)level4_kernel_pgt;
- else
- *p = (unsigned long)level3_kernel_pgt;
- *p += _PAGE_TABLE_NOENC - __START_KERNEL_map + load_delta;
+ pgd = &RIP_REL_REF(early_top_pgt)->pgd;
+ pgd[pgd_index(__START_KERNEL_map)] += load_delta;
if (la57) {
- p4d = fixup_pointer(level4_kernel_pgt, physaddr);
- p4d[511] += load_delta;
+ p4d = (p4dval_t *)&RIP_REL_REF(level4_kernel_pgt);
+ p4d[MAX_PTRS_PER_P4D - 1] += load_delta;
+
+ pgd[pgd_index(__START_KERNEL_map)] = (pgdval_t)p4d | _PAGE_TABLE;
}
- pud = fixup_pointer(level3_kernel_pgt, physaddr);
- pud[510] += load_delta;
- pud[511] += load_delta;
+ RIP_REL_REF(level3_kernel_pgt)[PTRS_PER_PUD - 2].pud += load_delta;
+ RIP_REL_REF(level3_kernel_pgt)[PTRS_PER_PUD - 1].pud += load_delta;
- pmd = fixup_pointer(level2_fixmap_pgt, physaddr);
for (i = FIXMAP_PMD_TOP; i > FIXMAP_PMD_TOP - FIXMAP_PMD_NUM; i--)
- pmd[i] += load_delta;
+ RIP_REL_REF(level2_fixmap_pgt)[i].pmd += load_delta;
/*
* Set up the identity mapping for the switchover. These
@@ -238,15 +198,14 @@ unsigned long __head __startup_64(unsigned long physaddr,
* it avoids problems around wraparound.
*/
- next_pgt_ptr = fixup_pointer(&next_early_pgt, physaddr);
- pud = fixup_pointer(early_dynamic_pgts[(*next_pgt_ptr)++], physaddr);
- pmd = fixup_pointer(early_dynamic_pgts[(*next_pgt_ptr)++], physaddr);
+ pud = &early_pgts[0]->pmd;
+ pmd = &early_pgts[1]->pmd;
+ RIP_REL_REF(next_early_pgt) = 2;
pgtable_flags = _KERNPG_TABLE_NOENC + sme_get_me_mask();
if (la57) {
- p4d = fixup_pointer(early_dynamic_pgts[(*next_pgt_ptr)++],
- physaddr);
+ p4d = &early_pgts[RIP_REL_REF(next_early_pgt)++]->pmd;
i = (physaddr >> PGDIR_SHIFT) % PTRS_PER_PGD;
pgd[i + 0] = (pgdval_t)p4d + pgtable_flags;
@@ -267,8 +226,7 @@ unsigned long __head __startup_64(unsigned long physaddr,
pmd_entry = __PAGE_KERNEL_LARGE_EXEC & ~_PAGE_GLOBAL;
/* Filter out unsupported __PAGE_KERNEL_* bits: */
- mask_ptr = fixup_pointer(&__supported_pte_mask, physaddr);
- pmd_entry &= *mask_ptr;
+ pmd_entry &= RIP_REL_REF(__supported_pte_mask);
pmd_entry += sme_get_me_mask();
pmd_entry += physaddr;
@@ -294,7 +252,7 @@ unsigned long __head __startup_64(unsigned long physaddr,
* error, causing the BIOS to halt the system.
*/
- pmd = fixup_pointer(level2_kernel_pgt, physaddr);
+ pmd = &RIP_REL_REF(level2_kernel_pgt)->pmd;
/* invalidate pages before the kernel image */
for (i = 0; i < pmd_index((unsigned long)_text); i++)
@@ -309,12 +267,6 @@ unsigned long __head __startup_64(unsigned long physaddr,
for (; i < PTRS_PER_PMD; i++)
pmd[i] &= ~_PAGE_PRESENT;
- /*
- * Fixup phys_base - remove the memory encryption mask to obtain
- * the true physical address.
- */
- *fixup_long(&phys_base, physaddr) += load_delta - sme_get_me_mask();
-
return sme_postprocess_startup(bp, pmd);
}
@@ -569,62 +521,52 @@ void __init __noreturn x86_64_start_reservations(char *real_mode_data)
*/
static gate_desc bringup_idt_table[NUM_EXCEPTION_VECTORS] __page_aligned_data;
-static struct desc_ptr bringup_idt_descr = {
- .size = (NUM_EXCEPTION_VECTORS * sizeof(gate_desc)) - 1,
- .address = 0, /* Set at runtime */
-};
-
-static void set_bringup_idt_handler(gate_desc *idt, int n, void *handler)
+/* This may run while still in the direct mapping */
+static void __head startup_64_load_idt(void *vc_handler)
{
-#ifdef CONFIG_AMD_MEM_ENCRYPT
+ struct desc_ptr desc = {
+ .address = (unsigned long)&RIP_REL_REF(bringup_idt_table),
+ .size = sizeof(bringup_idt_table) - 1,
+ };
struct idt_data data;
- gate_desc desc;
-
- init_idt_data(&data, n, handler);
- idt_init_desc(&desc, &data);
- native_write_idt_entry(idt, n, &desc);
-#endif
-}
+ gate_desc idt_desc;
-/* This runs while still in the direct mapping */
-static void __head startup_64_load_idt(unsigned long physbase)
-{
- struct desc_ptr *desc = fixup_pointer(&bringup_idt_descr, physbase);
- gate_desc *idt = fixup_pointer(bringup_idt_table, physbase);
-
-
- if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT)) {
- void *handler;
-
- /* VMM Communication Exception */
- handler = fixup_pointer(vc_no_ghcb, physbase);
- set_bringup_idt_handler(idt, X86_TRAP_VC, handler);
+ /* @vc_handler is set only for a VMM Communication Exception */
+ if (vc_handler) {
+ init_idt_data(&data, X86_TRAP_VC, vc_handler);
+ idt_init_desc(&idt_desc, &data);
+ native_write_idt_entry((gate_desc *)desc.address, X86_TRAP_VC, &idt_desc);
}
- desc->address = (unsigned long)idt;
- native_load_idt(desc);
+ native_load_idt(&desc);
}
/* This is used when running on kernel addresses */
void early_setup_idt(void)
{
- /* VMM Communication Exception */
+ void *handler = NULL;
+
if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT)) {
setup_ghcb();
- set_bringup_idt_handler(bringup_idt_table, X86_TRAP_VC, vc_boot_ghcb);
+ handler = vc_boot_ghcb;
}
- bringup_idt_descr.address = (unsigned long)bringup_idt_table;
- native_load_idt(&bringup_idt_descr);
+ startup_64_load_idt(handler);
}
/*
* Setup boot CPU state needed before kernel switches to virtual addresses.
*/
-void __head startup_64_setup_env(unsigned long physbase)
+void __head startup_64_setup_gdt_idt(void)
{
+ void *handler = NULL;
+
+ struct desc_ptr startup_gdt_descr = {
+ .address = (unsigned long)&RIP_REL_REF(init_per_cpu_var(gdt_page.gdt)),
+ .size = GDT_SIZE - 1,
+ };
+
/* Load GDT */
- startup_gdt_descr.address = (unsigned long)fixup_pointer(startup_gdt, physbase);
native_load_gdt(&startup_gdt_descr);
/* New GDT is live - reload data segment registers */
@@ -632,5 +574,8 @@ void __head startup_64_setup_env(unsigned long physbase)
"movl %%eax, %%ss\n"
"movl %%eax, %%es\n" : : "a"(__KERNEL_DS) : "memory");
- startup_64_load_idt(physbase);
+ if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT))
+ handler = &RIP_REL_REF(vc_no_ghcb);
+
+ startup_64_load_idt(handler);
}
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
index 487ac57e2c81..b50f3641c4d6 100644
--- a/arch/x86/kernel/head_32.S
+++ b/arch/x86/kernel/head_32.S
@@ -414,7 +414,7 @@ __REFDATA
.align 4
SYM_DATA(initial_code, .long i386_start_kernel)
-#ifdef CONFIG_PAGE_TABLE_ISOLATION
+#ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
#define PGD_ALIGN (2 * PAGE_SIZE)
#define PTI_USER_PGD_FILL 1024
#else
@@ -474,7 +474,7 @@ SYM_DATA_START(initial_page_table)
# endif
.align PAGE_SIZE /* needs to be page-sized too */
-#ifdef CONFIG_PAGE_TABLE_ISOLATION
+#ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
/*
* PTI needs another page so sync_initial_pagetable() works correctly
* and does not scribble over the data which is placed behind the
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
index d4918d03efb4..d8198fbd70e5 100644
--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -26,6 +26,7 @@
#include <asm/apicdef.h>
#include <asm/fixmap.h>
#include <asm/smp.h>
+#include <asm/thread_info.h>
/*
* We are not able to switch in one step to the final KERNEL ADDRESS SPACE
@@ -39,7 +40,6 @@ L4_START_KERNEL = l4_index(__START_KERNEL_map)
L3_START_KERNEL = pud_index(__START_KERNEL_map)
- .text
__HEAD
.code64
SYM_CODE_START_NOALIGN(startup_64)
@@ -66,9 +66,7 @@ SYM_CODE_START_NOALIGN(startup_64)
mov %rsi, %r15
/* Set up the stack for verify_cpu() */
- leaq (__end_init_task - PTREGS_SIZE)(%rip), %rsp
-
- leaq _text(%rip), %rdi
+ leaq (__end_init_task - TOP_OF_KERNEL_STACK_PADDING - PTREGS_SIZE)(%rip), %rsp
/* Setup GSBASE to allow stack canary access for C code */
movl $MSR_GS_BASE, %ecx
@@ -77,7 +75,7 @@ SYM_CODE_START_NOALIGN(startup_64)
shrq $32, %rdx
wrmsr
- call startup_64_setup_env
+ call startup_64_setup_gdt_idt
/* Now switch to __KERNEL_CS so IRET works reliably */
pushq $__KERNEL_CS
@@ -113,13 +111,11 @@ SYM_CODE_START_NOALIGN(startup_64)
call __startup_64
/* Form the CR3 value being sure to include the CR3 modifier */
- addq $(early_top_pgt - __START_KERNEL_map), %rax
+ leaq early_top_pgt(%rip), %rcx
+ addq %rcx, %rax
#ifdef CONFIG_AMD_MEM_ENCRYPT
mov %rax, %rdi
- mov %rax, %r14
-
- addq phys_base(%rip), %rdi
/*
* For SEV guests: Verify that the C-bit is correct. A malicious
@@ -128,17 +124,23 @@ SYM_CODE_START_NOALIGN(startup_64)
* the next RET instruction.
*/
call sev_verify_cbit
+#endif
/*
- * Restore CR3 value without the phys_base which will be added
- * below, before writing %cr3.
+ * Switch to early_top_pgt which still has the identity mappings
+ * present.
*/
- mov %r14, %rax
-#endif
+ movq %rax, %cr3
- jmp 1f
+ /* Branch to the common startup code at its kernel virtual address */
+ ANNOTATE_RETPOLINE_SAFE
+ jmp *0f(%rip)
SYM_CODE_END(startup_64)
+ __INITRODATA
+0: .quad common_startup_64
+
+ .text
SYM_CODE_START(secondary_startup_64)
UNWIND_HINT_END_OF_STACK
ANNOTATE_NOENDBR
@@ -171,22 +173,39 @@ SYM_INNER_LABEL(secondary_startup_64_no_verify, SYM_L_GLOBAL)
ANNOTATE_NOENDBR
/* Clear %R15 which holds the boot_params pointer on the boot CPU */
- xorq %r15, %r15
+ xorl %r15d, %r15d
+
+ /* Derive the runtime physical address of init_top_pgt[] */
+ movq phys_base(%rip), %rax
+ addq $(init_top_pgt - __START_KERNEL_map), %rax
/*
* Retrieve the modifier (SME encryption mask if SME is active) to be
* added to the initial pgdir entry that will be programmed into CR3.
*/
#ifdef CONFIG_AMD_MEM_ENCRYPT
- movq sme_me_mask, %rax
-#else
- xorq %rax, %rax
+ addq sme_me_mask(%rip), %rax
#endif
+ /*
+ * Switch to the init_top_pgt here, away from the trampoline_pgd and
+ * unmap the identity mapped ranges.
+ */
+ movq %rax, %cr3
- /* Form the CR3 value being sure to include the CR3 modifier */
- addq $(init_top_pgt - __START_KERNEL_map), %rax
-1:
+SYM_INNER_LABEL(common_startup_64, SYM_L_LOCAL)
+ UNWIND_HINT_END_OF_STACK
+ ANNOTATE_NOENDBR
+ /*
+ * Create a mask of CR4 bits to preserve. Omit PGE in order to flush
+ * global 1:1 translations from the TLBs.
+ *
+ * From the SDM:
+ * "If CR4.PGE is changing from 0 to 1, there were no global TLB
+ * entries before the execution; if CR4.PGE is changing from 1 to 0,
+ * there will be no global TLB entries after the execution."
+ */
+ movl $(X86_CR4_PAE | X86_CR4_LA57), %edx
#ifdef CONFIG_X86_MCE
/*
* Preserve CR4.MCE if the kernel will enable #MC support.
@@ -195,52 +214,20 @@ SYM_INNER_LABEL(secondary_startup_64_no_verify, SYM_L_GLOBAL)
* configured will crash the system regardless of the CR4.MCE value set
* here.
*/
- movq %cr4, %rcx
- andl $X86_CR4_MCE, %ecx
-#else
- movl $0, %ecx
+ orl $X86_CR4_MCE, %edx
#endif
+ movq %cr4, %rcx
+ andl %edx, %ecx
- /* Enable PAE mode, PSE, PGE and LA57 */
- orl $(X86_CR4_PAE | X86_CR4_PSE | X86_CR4_PGE), %ecx
-#ifdef CONFIG_X86_5LEVEL
- testb $1, __pgtable_l5_enabled(%rip)
- jz 1f
- orl $X86_CR4_LA57, %ecx
-1:
-#endif
+ /* Even if ignored in long mode, set PSE uniformly on all logical CPUs. */
+ btsl $X86_CR4_PSE_BIT, %ecx
movq %rcx, %cr4
- /* Setup early boot stage 4-/5-level pagetables. */
- addq phys_base(%rip), %rax
-
/*
- * Switch to new page-table
- *
- * For the boot CPU this switches to early_top_pgt which still has the
- * identity mappings present. The secondary CPUs will switch to the
- * init_top_pgt here, away from the trampoline_pgd and unmap the
- * identity mapped ranges.
+ * Set CR4.PGE to re-enable global translations.
*/
- movq %rax, %cr3
-
- /*
- * Do a global TLB flush after the CR3 switch to make sure the TLB
- * entries from the identity mapping are flushed.
- */
- movq %cr4, %rcx
- movq %rcx, %rax
- xorq $X86_CR4_PGE, %rcx
+ btsl $X86_CR4_PGE_BIT, %ecx
movq %rcx, %cr4
- movq %rax, %cr4
-
- /* Ensure I am executing from virtual addresses */
- movq $1f, %rax
- ANNOTATE_RETPOLINE_SAFE
- jmp *%rax
-1:
- UNWIND_HINT_END_OF_STACK
- ANNOTATE_NOENDBR // above
#ifdef CONFIG_SMP
/*
@@ -297,7 +284,7 @@ SYM_INNER_LABEL(secondary_startup_64_no_verify, SYM_L_GLOBAL)
.Llookup_AP:
/* EAX contains the APIC ID of the current CPU */
- xorq %rcx, %rcx
+ xorl %ecx, %ecx
leaq cpuid_to_apicid(%rip), %rbx
.Lfind_cpunr:
@@ -428,39 +415,10 @@ SYM_INNER_LABEL(secondary_startup_64_no_verify, SYM_L_GLOBAL)
movq %r15, %rdi
.Ljump_to_C_code:
- /*
- * Jump to run C code and to be on a real kernel address.
- * Since we are running on identity-mapped space we have to jump
- * to the full 64bit address, this is only possible as indirect
- * jump. In addition we need to ensure %cs is set so we make this
- * a far return.
- *
- * Note: do not change to far jump indirect with 64bit offset.
- *
- * AMD does not support far jump indirect with 64bit offset.
- * AMD64 Architecture Programmer's Manual, Volume 3: states only
- * JMP FAR mem16:16 FF /5 Far jump indirect,
- * with the target specified by a far pointer in memory.
- * JMP FAR mem16:32 FF /5 Far jump indirect,
- * with the target specified by a far pointer in memory.
- *
- * Intel64 does support 64bit offset.
- * Software Developer Manual Vol 2: states:
- * FF /5 JMP m16:16 Jump far, absolute indirect,
- * address given in m16:16
- * FF /5 JMP m16:32 Jump far, absolute indirect,
- * address given in m16:32.
- * REX.W + FF /5 JMP m16:64 Jump far, absolute indirect,
- * address given in m16:64.
- */
- pushq $.Lafter_lret # put return address on stack for unwinder
xorl %ebp, %ebp # clear frame pointer
- movq initial_code(%rip), %rax
- pushq $__KERNEL_CS # set correct cs
- pushq %rax # target address in negative space
- lretq
-.Lafter_lret:
- ANNOTATE_NOENDBR
+ ANNOTATE_RETPOLINE_SAFE
+ callq *initial_code(%rip)
+ ud2
SYM_CODE_END(secondary_startup_64)
#include "verify_cpu.S"
@@ -477,7 +435,7 @@ SYM_CODE_START(soft_restart_cpu)
UNWIND_HINT_END_OF_STACK
/* Find the idle task stack */
- movq PER_CPU_VAR(pcpu_hot) + X86_current_task, %rcx
+ movq PER_CPU_VAR(pcpu_hot + X86_current_task), %rcx
movq TASK_threadsp(%rcx), %rsp
jmp .Ljump_to_C_code
@@ -622,7 +580,7 @@ SYM_CODE_END(vc_no_ghcb)
#define SYM_DATA_START_PAGE_ALIGNED(name) \
SYM_START(name, SYM_L_GLOBAL, .balign PAGE_SIZE)
-#ifdef CONFIG_PAGE_TABLE_ISOLATION
+#ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
/*
* Each PGD needs to be 8k long and 8k aligned. We do not
* ever go out to userspace with these, so we do not
@@ -655,7 +613,8 @@ SYM_CODE_END(vc_no_ghcb)
.balign 4
SYM_DATA_START_PTI_ALIGNED(early_top_pgt)
- .fill 512,8,0
+ .fill 511,8,0
+ .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE_NOENC
.fill PTI_USER_PGD_FILL,8,0
SYM_DATA_END(early_top_pgt)
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index a38d0c93a66e..c96ae8fee95e 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -568,7 +568,7 @@ static struct irq_domain *hpet_create_irq_domain(int hpet_id)
fwspec.param_count = 1;
fwspec.param[0] = hpet_id;
- parent = irq_find_matching_fwspec(&fwspec, DOMAIN_BUS_ANY);
+ parent = irq_find_matching_fwspec(&fwspec, DOMAIN_BUS_GENERIC_MSI);
if (!parent) {
irq_domain_free_fwnode(fn);
kfree(domain_info);
diff --git a/arch/x86/kernel/idt.c b/arch/x86/kernel/idt.c
index 660b601f1d6c..fc37c8d83daf 100644
--- a/arch/x86/kernel/idt.c
+++ b/arch/x86/kernel/idt.c
@@ -153,7 +153,7 @@ static const __initconst struct idt_data apic_idts[] = {
#ifdef CONFIG_X86_LOCAL_APIC
INTG(LOCAL_TIMER_VECTOR, asm_sysvec_apic_timer_interrupt),
INTG(X86_PLATFORM_IPI_VECTOR, asm_sysvec_x86_platform_ipi),
-# ifdef CONFIG_HAVE_KVM
+# if IS_ENABLED(CONFIG_KVM)
INTG(POSTED_INTR_VECTOR, asm_sysvec_kvm_posted_intr_ipi),
INTG(POSTED_INTR_WAKEUP_VECTOR, asm_sysvec_kvm_posted_intr_wakeup_ipi),
INTG(POSTED_INTR_NESTED_VECTOR, asm_sysvec_kvm_posted_intr_nested_ipi),
@@ -337,7 +337,7 @@ void idt_invalidate(void)
load_idt(&idt);
}
-void __init alloc_intr_gate(unsigned int n, const void *addr)
+void __init idt_install_sysvec(unsigned int n, const void *function)
{
if (WARN_ON(n < FIRST_SYSTEM_VECTOR))
return;
@@ -346,5 +346,5 @@ void __init alloc_intr_gate(unsigned int n, const void *addr)
return;
if (!WARN_ON(test_and_set_bit(n, system_vectors)))
- set_intr_gate(n, addr);
+ set_intr_gate(n, function);
}
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 11761c124545..35fde0107901 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -164,7 +164,7 @@ int arch_show_interrupts(struct seq_file *p, int prec)
#if defined(CONFIG_X86_IO_APIC)
seq_printf(p, "%*s: %10u\n", prec, "MIS", atomic_read(&irq_mis_count));
#endif
-#ifdef CONFIG_HAVE_KVM
+#if IS_ENABLED(CONFIG_KVM)
seq_printf(p, "%*s: ", prec, "PIN");
for_each_online_cpu(j)
seq_printf(p, "%10u ", irq_stats(j)->kvm_posted_intr_ipis);
@@ -290,7 +290,7 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_x86_platform_ipi)
}
#endif
-#ifdef CONFIG_HAVE_KVM
+#if IS_ENABLED(CONFIG_KVM)
static void dummy_handler(void) {}
static void (*kvm_posted_intr_wakeup_handler)(void) = dummy_handler;
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
index c683666876f1..f79c5edc0b89 100644
--- a/arch/x86/kernel/irqinit.c
+++ b/arch/x86/kernel/irqinit.c
@@ -28,6 +28,7 @@
#include <asm/setup.h>
#include <asm/i8259.h>
#include <asm/traps.h>
+#include <asm/fred.h>
#include <asm/prom.h>
/*
@@ -96,7 +97,11 @@ void __init native_init_IRQ(void)
/* Execute any quirks before the call gates are initialised: */
x86_init.irqs.pre_vector_init();
- idt_setup_apic_and_irq_gates();
+ if (cpu_feature_enabled(X86_FEATURE_FRED))
+ fred_complete_exception_setup();
+ else
+ idt_setup_apic_and_irq_gates();
+
lapic_assign_system_vectors();
if (!acpi_ioapic && !of_ioapic && nr_legacy_irqs()) {
diff --git a/arch/x86/kernel/jailhouse.c b/arch/x86/kernel/jailhouse.c
index 578d16fc040f..df337860612d 100644
--- a/arch/x86/kernel/jailhouse.c
+++ b/arch/x86/kernel/jailhouse.c
@@ -89,7 +89,7 @@ static void __init jailhouse_x2apic_init(void)
#endif
}
-static void __init jailhouse_get_smp_config(unsigned int early)
+static void __init jailhouse_parse_smp_config(void)
{
struct ioapic_domain_cfg ioapic_cfg = {
.type = IOAPIC_DOMAIN_STRICT,
@@ -102,7 +102,7 @@ static void __init jailhouse_get_smp_config(unsigned int early)
register_lapic_address(0xfee00000);
for (cpu = 0; cpu < setup_data.v1.num_cpus; cpu++)
- generic_processor_info(setup_data.v1.cpu_ids[cpu]);
+ topology_register_apic(setup_data.v1.cpu_ids[cpu], CPU_ACPIID_INVALID, true);
smp_found_config = 1;
@@ -201,21 +201,23 @@ static void __init jailhouse_init_platform(void)
struct setup_data header;
void *mapping;
- x86_init.irqs.pre_vector_init = x86_init_noop;
- x86_init.timers.timer_init = jailhouse_timer_init;
- x86_init.mpparse.get_smp_config = jailhouse_get_smp_config;
- x86_init.pci.arch_init = jailhouse_pci_arch_init;
+ x86_init.irqs.pre_vector_init = x86_init_noop;
+ x86_init.timers.timer_init = jailhouse_timer_init;
+ x86_init.mpparse.find_mptable = x86_init_noop;
+ x86_init.mpparse.early_parse_smp_cfg = x86_init_noop;
+ x86_init.mpparse.parse_smp_cfg = jailhouse_parse_smp_config;
+ x86_init.pci.arch_init = jailhouse_pci_arch_init;
- x86_platform.calibrate_cpu = jailhouse_get_tsc;
- x86_platform.calibrate_tsc = jailhouse_get_tsc;
- x86_platform.get_wallclock = jailhouse_get_wallclock;
- x86_platform.legacy.rtc = 0;
- x86_platform.legacy.warm_reset = 0;
- x86_platform.legacy.i8042 = X86_LEGACY_I8042_PLATFORM_ABSENT;
+ x86_platform.calibrate_cpu = jailhouse_get_tsc;
+ x86_platform.calibrate_tsc = jailhouse_get_tsc;
+ x86_platform.get_wallclock = jailhouse_get_wallclock;
+ x86_platform.legacy.rtc = 0;
+ x86_platform.legacy.warm_reset = 0;
+ x86_platform.legacy.i8042 = X86_LEGACY_I8042_PLATFORM_ABSENT;
- legacy_pic = &null_legacy_pic;
+ legacy_pic = &null_legacy_pic;
- machine_ops.emergency_restart = jailhouse_no_restart;
+ machine_ops.emergency_restart = jailhouse_no_restart;
while (pa_data) {
mapping = early_memremap(pa_data, sizeof(header));
diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c
index 2a422e00ed4b..68530fad05f7 100644
--- a/arch/x86/kernel/kexec-bzimage64.c
+++ b/arch/x86/kernel/kexec-bzimage64.c
@@ -263,11 +263,13 @@ setup_boot_parameters(struct kimage *image, struct boot_params *params,
memset(&params->hd0_info, 0, sizeof(params->hd0_info));
memset(&params->hd1_info, 0, sizeof(params->hd1_info));
+#ifdef CONFIG_CRASH_DUMP
if (image->type == KEXEC_TYPE_CRASH) {
ret = crash_setup_memmap_entries(image, params);
if (ret)
return ret;
} else
+#endif
setup_e820_entries(params);
nr_e820_entries = params->e820_entries;
@@ -433,12 +435,14 @@ static void *bzImage64_load(struct kimage *image, char *kernel,
return ERR_PTR(-EINVAL);
}
+#ifdef CONFIG_CRASH_DUMP
/* Allocate and load backup region */
if (image->type == KEXEC_TYPE_CRASH) {
ret = crash_load_segments(image);
if (ret)
return ERR_PTR(ret);
}
+#endif
/*
* Load purgatory. For 64bit entry point, purgatory code can be
@@ -503,7 +507,10 @@ static void *bzImage64_load(struct kimage *image, char *kernel,
kbuf.bufsz = kernel_len - kern16_size;
kbuf.memsz = PAGE_ALIGN(header->init_size);
kbuf.buf_align = header->kernel_alignment;
- kbuf.buf_min = MIN_KERNEL_LOAD_ADDR;
+ if (header->pref_address < MIN_KERNEL_LOAD_ADDR)
+ kbuf.buf_min = MIN_KERNEL_LOAD_ADDR;
+ else
+ kbuf.buf_min = header->pref_address;
kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
ret = kexec_add_buffer(&kbuf);
if (ret)
diff --git a/arch/x86/kernel/kprobes/common.h b/arch/x86/kernel/kprobes/common.h
index c993521d4933..e772276f5aa9 100644
--- a/arch/x86/kernel/kprobes/common.h
+++ b/arch/x86/kernel/kprobes/common.h
@@ -78,7 +78,7 @@
#endif
/* Ensure if the instruction can be boostable */
-extern int can_boost(struct insn *insn, void *orig_addr);
+extern bool can_boost(struct insn *insn, void *orig_addr);
/* Recover instruction if given address is probed */
extern unsigned long recover_probed_instruction(kprobe_opcode_t *buf,
unsigned long addr);
diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c
index a0ce46c0a2d8..d0e49bd7c6f3 100644
--- a/arch/x86/kernel/kprobes/core.c
+++ b/arch/x86/kernel/kprobes/core.c
@@ -137,14 +137,14 @@ NOKPROBE_SYMBOL(synthesize_relcall);
* Returns non-zero if INSN is boostable.
* RIP relative instructions are adjusted at copying time in 64 bits mode
*/
-int can_boost(struct insn *insn, void *addr)
+bool can_boost(struct insn *insn, void *addr)
{
kprobe_opcode_t opcode;
insn_byte_t prefix;
int i;
if (search_exception_tables((unsigned long)addr))
- return 0; /* Page fault may occur on this address. */
+ return false; /* Page fault may occur on this address. */
/* 2nd-byte opcode */
if (insn->opcode.nbytes == 2)
@@ -152,7 +152,7 @@ int can_boost(struct insn *insn, void *addr)
(unsigned long *)twobyte_is_boostable);
if (insn->opcode.nbytes != 1)
- return 0;
+ return false;
for_each_insn_prefix(insn, i, prefix) {
insn_attr_t attr;
@@ -160,7 +160,7 @@ int can_boost(struct insn *insn, void *addr)
attr = inat_get_opcode_attribute(prefix);
/* Can't boost Address-size override prefix and CS override prefix */
if (prefix == 0x2e || inat_is_address_size_prefix(attr))
- return 0;
+ return false;
}
opcode = insn->opcode.bytes[0];
@@ -169,24 +169,35 @@ int can_boost(struct insn *insn, void *addr)
case 0x62: /* bound */
case 0x70 ... 0x7f: /* Conditional jumps */
case 0x9a: /* Call far */
- case 0xc0 ... 0xc1: /* Grp2 */
case 0xcc ... 0xce: /* software exceptions */
- case 0xd0 ... 0xd3: /* Grp2 */
case 0xd6: /* (UD) */
case 0xd8 ... 0xdf: /* ESC */
case 0xe0 ... 0xe3: /* LOOP*, JCXZ */
case 0xe8 ... 0xe9: /* near Call, JMP */
case 0xeb: /* Short JMP */
case 0xf0 ... 0xf4: /* LOCK/REP, HLT */
+ /* ... are not boostable */
+ return false;
+ case 0xc0 ... 0xc1: /* Grp2 */
+ case 0xd0 ... 0xd3: /* Grp2 */
+ /*
+ * AMD uses nnn == 110 as SHL/SAL, but Intel makes it reserved.
+ */
+ return X86_MODRM_REG(insn->modrm.bytes[0]) != 0b110;
case 0xf6 ... 0xf7: /* Grp3 */
+ /* AMD uses nnn == 001 as TEST, but Intel makes it reserved. */
+ return X86_MODRM_REG(insn->modrm.bytes[0]) != 0b001;
case 0xfe: /* Grp4 */
- /* ... are not boostable */
- return 0;
+ /* Only INC and DEC are boostable */
+ return X86_MODRM_REG(insn->modrm.bytes[0]) == 0b000 ||
+ X86_MODRM_REG(insn->modrm.bytes[0]) == 0b001;
case 0xff: /* Grp5 */
- /* Only indirect jmp is boostable */
- return X86_MODRM_REG(insn->modrm.bytes[0]) == 4;
+ /* Only INC, DEC, and indirect JMP are boostable */
+ return X86_MODRM_REG(insn->modrm.bytes[0]) == 0b000 ||
+ X86_MODRM_REG(insn->modrm.bytes[0]) == 0b001 ||
+ X86_MODRM_REG(insn->modrm.bytes[0]) == 0b100;
default:
- return 1;
+ return true;
}
}
@@ -252,21 +263,40 @@ unsigned long recover_probed_instruction(kprobe_opcode_t *buf, unsigned long add
return __recover_probed_insn(buf, addr);
}
-/* Check if paddr is at an instruction boundary */
-static int can_probe(unsigned long paddr)
+/* Check if insn is INT or UD */
+static inline bool is_exception_insn(struct insn *insn)
+{
+ /* UD uses 0f escape */
+ if (insn->opcode.bytes[0] == 0x0f) {
+ /* UD0 / UD1 / UD2 */
+ return insn->opcode.bytes[1] == 0xff ||
+ insn->opcode.bytes[1] == 0xb9 ||
+ insn->opcode.bytes[1] == 0x0b;
+ }
+
+ /* INT3 / INT n / INTO / INT1 */
+ return insn->opcode.bytes[0] == 0xcc ||
+ insn->opcode.bytes[0] == 0xcd ||
+ insn->opcode.bytes[0] == 0xce ||
+ insn->opcode.bytes[0] == 0xf1;
+}
+
+/*
+ * Check if paddr is at an instruction boundary and that instruction can
+ * be probed
+ */
+static bool can_probe(unsigned long paddr)
{
unsigned long addr, __addr, offset = 0;
struct insn insn;
kprobe_opcode_t buf[MAX_INSN_SIZE];
if (!kallsyms_lookup_size_offset(paddr, NULL, &offset))
- return 0;
+ return false;
/* Decode instructions */
addr = paddr - offset;
while (addr < paddr) {
- int ret;
-
/*
* Check if the instruction has been modified by another
* kprobe, in which case we replace the breakpoint by the
@@ -277,11 +307,10 @@ static int can_probe(unsigned long paddr)
*/
__addr = recover_probed_instruction(buf, addr);
if (!__addr)
- return 0;
+ return false;
- ret = insn_decode_kernel(&insn, (void *)__addr);
- if (ret < 0)
- return 0;
+ if (insn_decode_kernel(&insn, (void *)__addr) < 0)
+ return false;
#ifdef CONFIG_KGDB
/*
@@ -290,10 +319,26 @@ static int can_probe(unsigned long paddr)
*/
if (insn.opcode.bytes[0] == INT3_INSN_OPCODE &&
kgdb_has_hit_break(addr))
- return 0;
+ return false;
#endif
addr += insn.length;
}
+
+ /* Check if paddr is at an instruction boundary */
+ if (addr != paddr)
+ return false;
+
+ __addr = recover_probed_instruction(buf, addr);
+ if (!__addr)
+ return false;
+
+ if (insn_decode_kernel(&insn, (void *)__addr) < 0)
+ return false;
+
+ /* INT and UD are special and should not be kprobed */
+ if (is_exception_insn(&insn))
+ return false;
+
if (IS_ENABLED(CONFIG_CFI_CLANG)) {
/*
* The compiler generates the following instruction sequence
@@ -308,13 +353,6 @@ static int can_probe(unsigned long paddr)
* Also, these movl and addl are used for showing expected
* type. So those must not be touched.
*/
- __addr = recover_probed_instruction(buf, addr);
- if (!__addr)
- return 0;
-
- if (insn_decode_kernel(&insn, (void *)__addr) < 0)
- return 0;
-
if (insn.opcode.value == 0xBA)
offset = 12;
else if (insn.opcode.value == 0x3)
@@ -324,18 +362,27 @@ static int can_probe(unsigned long paddr)
/* This movl/addl is used for decoding CFI. */
if (is_cfi_trap(addr + offset))
- return 0;
+ return false;
}
out:
- return (addr == paddr);
+ return true;
}
/* If x86 supports IBT (ENDBR) it must be skipped. */
kprobe_opcode_t *arch_adjust_kprobe_addr(unsigned long addr, unsigned long offset,
bool *on_func_entry)
{
- if (is_endbr(*(u32 *)addr)) {
+ u32 insn;
+
+ /*
+ * Since 'addr' is not guaranteed to be safe to access, use
+ * copy_from_kernel_nofault() to read the instruction:
+ */
+ if (copy_from_kernel_nofault(&insn, (void *)addr, sizeof(u32)))
+ return NULL;
+
+ if (is_endbr(insn)) {
*on_func_entry = !offset || offset == 4;
if (*on_func_entry)
offset = 4;
diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c
index 517821b48391..36d6809c6c9e 100644
--- a/arch/x86/kernel/kprobes/opt.c
+++ b/arch/x86/kernel/kprobes/opt.c
@@ -324,7 +324,7 @@ static int can_optimize(unsigned long paddr)
* However, the kernel built with retpolines or IBT has jump
* tables disabled so the check can be skipped altogether.
*/
- if (!IS_ENABLED(CONFIG_RETPOLINE) &&
+ if (!IS_ENABLED(CONFIG_MITIGATION_RETPOLINE) &&
!IS_ENABLED(CONFIG_X86_KERNEL_IBT) &&
insn_is_indirect_jump(&insn))
return 0;
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index 428ee74002e1..7f0732bc0ccd 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -65,6 +65,7 @@ static int __init parse_no_stealacc(char *arg)
early_param("no-steal-acc", parse_no_stealacc);
+static DEFINE_PER_CPU_READ_MOSTLY(bool, async_pf_enabled);
static DEFINE_PER_CPU_DECRYPTED(struct kvm_vcpu_pv_apf_data, apf_reason) __aligned(64);
DEFINE_PER_CPU_DECRYPTED(struct kvm_steal_time, steal_time) __aligned(64) __visible;
static int has_steal_clock = 0;
@@ -244,7 +245,7 @@ noinstr u32 kvm_read_and_reset_apf_flags(void)
{
u32 flags = 0;
- if (__this_cpu_read(apf_reason.enabled)) {
+ if (__this_cpu_read(async_pf_enabled)) {
flags = __this_cpu_read(apf_reason.flags);
__this_cpu_write(apf_reason.flags, 0);
}
@@ -295,7 +296,7 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_kvm_asyncpf_interrupt)
inc_irq_stat(irq_hv_callback_count);
- if (__this_cpu_read(apf_reason.enabled)) {
+ if (__this_cpu_read(async_pf_enabled)) {
token = __this_cpu_read(apf_reason.token);
kvm_async_pf_task_wake(token);
__this_cpu_write(apf_reason.token, 0);
@@ -362,7 +363,7 @@ static void kvm_guest_cpu_init(void)
wrmsrl(MSR_KVM_ASYNC_PF_INT, HYPERVISOR_CALLBACK_VECTOR);
wrmsrl(MSR_KVM_ASYNC_PF_EN, pa);
- __this_cpu_write(apf_reason.enabled, 1);
+ __this_cpu_write(async_pf_enabled, true);
pr_debug("setup async PF for cpu %d\n", smp_processor_id());
}
@@ -383,11 +384,11 @@ static void kvm_guest_cpu_init(void)
static void kvm_pv_disable_apf(void)
{
- if (!__this_cpu_read(apf_reason.enabled))
+ if (!__this_cpu_read(async_pf_enabled))
return;
wrmsrl(MSR_KVM_ASYNC_PF_EN, 0);
- __this_cpu_write(apf_reason.enabled, 0);
+ __this_cpu_write(async_pf_enabled, false);
pr_debug("disable async PF for cpu %d\n", smp_processor_id());
}
@@ -770,7 +771,7 @@ static struct notifier_block kvm_pv_reboot_nb = {
* won't be valid. In cases like kexec, in which you install a new kernel, this
* means a random memory location will be kept being written.
*/
-#ifdef CONFIG_KEXEC_CORE
+#ifdef CONFIG_CRASH_DUMP
static void kvm_crash_shutdown(struct pt_regs *regs)
{
kvm_guest_cpu_offline(true);
@@ -830,7 +831,7 @@ static void __init kvm_guest_init(void)
if (kvm_para_has_feature(KVM_FEATURE_ASYNC_PF_INT) && kvmapf) {
static_branch_enable(&kvm_async_pf_enabled);
- alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, asm_sysvec_kvm_asyncpf_interrupt);
+ sysvec_install(HYPERVISOR_CALLBACK_VECTOR, sysvec_kvm_asyncpf_interrupt);
}
#ifdef CONFIG_SMP
@@ -853,7 +854,7 @@ static void __init kvm_guest_init(void)
kvm_guest_cpu_init();
#endif
-#ifdef CONFIG_KEXEC_CORE
+#ifdef CONFIG_CRASH_DUMP
machine_ops.crash_shutdown = kvm_crash_shutdown;
#endif
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c
index 5bb395551c44..5b2c15214a6b 100644
--- a/arch/x86/kernel/kvmclock.c
+++ b/arch/x86/kernel/kvmclock.c
@@ -154,15 +154,15 @@ static int kvm_cs_enable(struct clocksource *cs)
return 0;
}
-struct clocksource kvm_clock = {
+static struct clocksource kvm_clock = {
.name = "kvm-clock",
.read = kvm_clock_get_cycles,
.rating = 400,
.mask = CLOCKSOURCE_MASK(64),
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
+ .id = CSID_X86_KVM_CLK,
.enable = kvm_cs_enable,
};
-EXPORT_SYMBOL_GPL(kvm_clock);
static void kvm_register_clock(char *txt)
{
diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c
index 7a814b41402d..0f19ef355f5f 100644
--- a/arch/x86/kernel/ldt.c
+++ b/arch/x86/kernel/ldt.c
@@ -184,7 +184,7 @@ static struct ldt_struct *alloc_ldt_struct(unsigned int num_entries)
return new_ldt;
}
-#ifdef CONFIG_PAGE_TABLE_ISOLATION
+#ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
static void do_sanity_check(struct mm_struct *mm,
bool had_kernel_mapping,
@@ -377,7 +377,7 @@ static void unmap_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt)
flush_tlb_mm_range(mm, va, va + nr_pages * PAGE_SIZE, PAGE_SHIFT, false);
}
-#else /* !CONFIG_PAGE_TABLE_ISOLATION */
+#else /* !CONFIG_MITIGATION_PAGE_TABLE_ISOLATION */
static int
map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot)
@@ -388,11 +388,11 @@ map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot)
static void unmap_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt)
{
}
-#endif /* CONFIG_PAGE_TABLE_ISOLATION */
+#endif /* CONFIG_MITIGATION_PAGE_TABLE_ISOLATION */
static void free_ldt_pgtables(struct mm_struct *mm)
{
-#ifdef CONFIG_PAGE_TABLE_ISOLATION
+#ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
struct mmu_gather tlb;
unsigned long start = LDT_BASE_ADDR;
unsigned long end = LDT_END_ADDR;
diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
index bc0a5348b4a6..b180d8e497c3 100644
--- a/arch/x86/kernel/machine_kexec_64.c
+++ b/arch/x86/kernel/machine_kexec_64.c
@@ -508,6 +508,8 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image)
}
#endif /* CONFIG_KEXEC_FILE */
+#ifdef CONFIG_CRASH_DUMP
+
static int
kexec_mark_range(unsigned long start, unsigned long end, bool protect)
{
@@ -552,6 +554,7 @@ void arch_kexec_unprotect_crashkres(void)
{
kexec_mark_crashkres(false);
}
+#endif
/*
* During a traditional boot under SME, SME will encrypt the kernel,
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c
index b223922248e9..e89171b0347a 100644
--- a/arch/x86/kernel/mpparse.c
+++ b/arch/x86/kernel/mpparse.c
@@ -36,6 +36,8 @@
* Checksum an MP configuration block.
*/
+static unsigned int num_procs __initdata;
+
static int __init mpf_checksum(unsigned char *mp, int len)
{
int sum = 0;
@@ -50,16 +52,15 @@ static void __init MP_processor_info(struct mpc_cpu *m)
{
char *bootup_cpu = "";
- if (!(m->cpuflag & CPU_ENABLED)) {
- disabled_cpus++;
+ topology_register_apic(m->apicid, CPU_ACPIID_INVALID, m->cpuflag & CPU_ENABLED);
+ if (!(m->cpuflag & CPU_ENABLED))
return;
- }
if (m->cpuflag & CPU_BOOTPROCESSOR)
bootup_cpu = " (Bootup-CPU)";
pr_info("Processor #%d%s\n", m->apicid, bootup_cpu);
- generic_processor_info(m->apicid);
+ num_procs++;
}
#ifdef CONFIG_X86_IO_APIC
@@ -196,12 +197,12 @@ static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
if (!smp_check_mpc(mpc, oem, str))
return 0;
- /* Initialize the lapic mapping */
- if (!acpi_lapic)
- register_lapic_address(mpc->lapic);
-
- if (early)
+ if (early) {
+ /* Initialize the lapic mapping */
+ if (!acpi_lapic)
+ register_lapic_address(mpc->lapic);
return 1;
+ }
/* Now process the configuration blocks. */
while (count < mpc->length) {
@@ -236,9 +237,9 @@ static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
}
}
- if (!num_processors)
+ if (!num_procs && !acpi_lapic)
pr_err("MPTABLE: no processors registered!\n");
- return num_processors;
+ return num_procs || acpi_lapic;
}
#ifdef CONFIG_X86_IO_APIC
@@ -473,7 +474,7 @@ static int __init check_physptr(struct mpf_intel *mpf, unsigned int early)
/*
* Scan the memory blocks for an SMP configuration block.
*/
-void __init default_get_smp_config(unsigned int early)
+static __init void mpparse_get_smp_config(unsigned int early)
{
struct mpf_intel *mpf;
@@ -529,8 +530,8 @@ void __init default_get_smp_config(unsigned int early)
} else
BUG();
- if (!early)
- pr_info("Processors: %d\n", num_processors);
+ if (!early && !acpi_lapic)
+ pr_info("Processors: %d\n", num_procs);
/*
* Only use the first configuration found.
*/
@@ -538,6 +539,16 @@ out:
early_memunmap(mpf, sizeof(*mpf));
}
+void __init mpparse_parse_early_smp_config(void)
+{
+ mpparse_get_smp_config(true);
+}
+
+void __init mpparse_parse_smp_config(void)
+{
+ mpparse_get_smp_config(false);
+}
+
static void __init smp_reserve_memory(struct mpf_intel *mpf)
{
memblock_reserve(mpf->physptr, get_mpc_size(mpf->physptr));
@@ -587,7 +598,7 @@ static int __init smp_scan_config(unsigned long base, unsigned long length)
return ret;
}
-void __init default_find_smp_config(void)
+void __init mpparse_find_mptable(void)
{
unsigned int address;
diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c
index 3082cf24b69e..ed163c8c8604 100644
--- a/arch/x86/kernel/nmi.c
+++ b/arch/x86/kernel/nmi.c
@@ -35,6 +35,7 @@
#include <asm/nospec-branch.h>
#include <asm/microcode.h>
#include <asm/sev.h>
+#include <asm/fred.h>
#define CREATE_TRACE_POINTS
#include <trace/events/nmi.h>
@@ -303,13 +304,13 @@ unknown_nmi_error(unsigned char reason, struct pt_regs *regs)
__this_cpu_add(nmi_stats.unknown, 1);
- pr_emerg("Uhhuh. NMI received for unknown reason %02x on CPU %d.\n",
- reason, smp_processor_id());
+ pr_emerg_ratelimited("Uhhuh. NMI received for unknown reason %02x on CPU %d.\n",
+ reason, smp_processor_id());
if (unknown_nmi_panic || panic_on_unrecovered_nmi)
nmi_panic(regs, "NMI: Not continuing");
- pr_emerg("Dazed and confused, but trying to continue\n");
+ pr_emerg_ratelimited("Dazed and confused, but trying to continue\n");
}
NOKPROBE_SYMBOL(unknown_nmi_error);
@@ -502,7 +503,7 @@ DEFINE_IDTENTRY_RAW(exc_nmi)
if (IS_ENABLED(CONFIG_NMI_CHECK_CPU))
raw_atomic_long_inc(&nsp->idt_calls);
- if (IS_ENABLED(CONFIG_SMP) && arch_cpu_is_offline(smp_processor_id())) {
+ if (arch_cpu_is_offline(smp_processor_id())) {
if (microcode_nmi_handler_enabled())
microcode_offline_nmi_handler();
return;
@@ -579,7 +580,7 @@ EXPORT_SYMBOL_GPL(asm_exc_nmi_kvm_vmx);
static char *nmi_check_stall_msg[] = {
/* */
-/* +--------- nsp->idt_seq_snap & 0x1: CPU is in NMI handler. */
+/* +--------- nmi_seq & 0x1: CPU is currently in NMI handler. */
/* | +------ cpu_is_offline(cpu) */
/* | | +--- nsp->idt_calls_snap != atomic_long_read(&nsp->idt_calls): */
/* | | | NMI handler has been invoked. */
@@ -627,27 +628,72 @@ void nmi_backtrace_stall_check(const struct cpumask *btp)
nmi_seq = READ_ONCE(nsp->idt_nmi_seq);
if (nsp->idt_nmi_seq_snap + 1 == nmi_seq && (nmi_seq & 0x1)) {
msgp = "CPU entered NMI handler function, but has not exited";
- } else if ((nsp->idt_nmi_seq_snap & 0x1) != (nmi_seq & 0x1)) {
- msgp = "CPU is handling NMIs";
- } else {
- idx = ((nsp->idt_seq_snap & 0x1) << 2) |
+ } else if (nsp->idt_nmi_seq_snap == nmi_seq ||
+ nsp->idt_nmi_seq_snap + 1 == nmi_seq) {
+ idx = ((nmi_seq & 0x1) << 2) |
(cpu_is_offline(cpu) << 1) |
(nsp->idt_calls_snap != atomic_long_read(&nsp->idt_calls));
msgp = nmi_check_stall_msg[idx];
if (nsp->idt_ignored_snap != READ_ONCE(nsp->idt_ignored) && (idx & 0x1))
modp = ", but OK because ignore_nmis was set";
- if (nmi_seq & ~0x1)
- msghp = " (CPU currently in NMI handler function)";
- else if (nsp->idt_nmi_seq_snap + 1 == nmi_seq)
+ if (nsp->idt_nmi_seq_snap + 1 == nmi_seq)
msghp = " (CPU exited one NMI handler function)";
+ else if (nmi_seq & 0x1)
+ msghp = " (CPU currently in NMI handler function)";
+ else
+ msghp = " (CPU was never in an NMI handler function)";
+ } else {
+ msgp = "CPU is handling NMIs";
}
- pr_alert("%s: CPU %d: %s%s%s, last activity: %lu jiffies ago.\n",
- __func__, cpu, msgp, modp, msghp, j - READ_ONCE(nsp->recv_jiffies));
+ pr_alert("%s: CPU %d: %s%s%s\n", __func__, cpu, msgp, modp, msghp);
+ pr_alert("%s: last activity: %lu jiffies ago.\n",
+ __func__, j - READ_ONCE(nsp->recv_jiffies));
}
}
#endif
+#ifdef CONFIG_X86_FRED
+/*
+ * With FRED, CR2/DR6 is pushed to #PF/#DB stack frame during FRED
+ * event delivery, i.e., there is no problem of transient states.
+ * And NMI unblocking only happens when the stack frame indicates
+ * that so should happen.
+ *
+ * Thus, the NMI entry stub for FRED is really straightforward and
+ * as simple as most exception handlers. As such, #DB is allowed
+ * during NMI handling.
+ */
+DEFINE_FREDENTRY_NMI(exc_nmi)
+{
+ irqentry_state_t irq_state;
+
+ if (arch_cpu_is_offline(smp_processor_id())) {
+ if (microcode_nmi_handler_enabled())
+ microcode_offline_nmi_handler();
+ return;
+ }
+
+ /*
+ * Save CR2 for eventual restore to cover the case where the NMI
+ * hits the VMENTER/VMEXIT region where guest CR2 is life. This
+ * prevents guest state corruption in case that the NMI handler
+ * takes a page fault.
+ */
+ this_cpu_write(nmi_cr2, read_cr2());
+
+ irq_state = irqentry_nmi_enter(regs);
+
+ inc_irq_stat(__nmi_count);
+ default_do_nmi(regs);
+
+ irqentry_nmi_exit(regs, irq_state);
+
+ if (unlikely(this_cpu_read(nmi_cr2) != read_cr2()))
+ write_cr2(this_cpu_read(nmi_cr2));
+}
+#endif
+
void stop_nmi(void)
{
ignore_nmis++;
diff --git a/arch/x86/kernel/probe_roms.c b/arch/x86/kernel/probe_roms.c
index 319fef37d9dc..cc2c34ba7228 100644
--- a/arch/x86/kernel/probe_roms.c
+++ b/arch/x86/kernel/probe_roms.c
@@ -203,16 +203,6 @@ void __init probe_roms(void)
unsigned char c;
int i;
- /*
- * The ROM memory range is not part of the e820 table and is therefore not
- * pre-validated by BIOS. The kernel page table maps the ROM region as encrypted
- * memory, and SNP requires encrypted memory to be validated before access.
- * Do that here.
- */
- snp_prep_memory(video_rom_resource.start,
- ((system_rom_resource.end + 1) - video_rom_resource.start),
- SNP_PAGE_STATE_PRIVATE);
-
/* video rom */
upper = adapter_rom_resources[0].start;
for (start = video_rom_resource.start; start < upper; start += 2048) {
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index ab49ade31b0d..b8441147eb5e 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -846,31 +846,6 @@ void __noreturn stop_this_cpu(void *dummy)
}
/*
- * AMD Erratum 400 aware idle routine. We handle it the same way as C3 power
- * states (local apic timer and TSC stop).
- *
- * XXX this function is completely buggered vs RCU and tracing.
- */
-static void amd_e400_idle(void)
-{
- /*
- * We cannot use static_cpu_has_bug() here because X86_BUG_AMD_APIC_C1E
- * gets set after static_cpu_has() places have been converted via
- * alternatives.
- */
- if (!boot_cpu_has_bug(X86_BUG_AMD_APIC_C1E)) {
- default_idle();
- return;
- }
-
- tick_broadcast_enter();
-
- default_idle();
-
- tick_broadcast_exit();
-}
-
-/*
* Prefer MWAIT over HALT if MWAIT is supported, MWAIT_CPUID leaf
* exists and whenever MONITOR/MWAIT extensions are present there is at
* least one C1 substate.
@@ -878,21 +853,22 @@ static void amd_e400_idle(void)
* Do not prefer MWAIT if MONITOR instruction has a bug or idle=nomwait
* is passed to kernel commandline parameter.
*/
-static int prefer_mwait_c1_over_halt(const struct cpuinfo_x86 *c)
+static __init bool prefer_mwait_c1_over_halt(void)
{
+ const struct cpuinfo_x86 *c = &boot_cpu_data;
u32 eax, ebx, ecx, edx;
- /* User has disallowed the use of MWAIT. Fallback to HALT */
- if (boot_option_idle_override == IDLE_NOMWAIT)
- return 0;
+ /* If override is enforced on the command line, fall back to HALT. */
+ if (boot_option_idle_override != IDLE_NO_OVERRIDE)
+ return false;
/* MWAIT is not supported on this platform. Fallback to HALT */
if (!cpu_has(c, X86_FEATURE_MWAIT))
- return 0;
+ return false;
- /* Monitor has a bug. Fallback to HALT */
- if (boot_cpu_has_bug(X86_BUG_MONITOR))
- return 0;
+ /* Monitor has a bug or APIC stops in C1E. Fallback to HALT */
+ if (boot_cpu_has_bug(X86_BUG_MONITOR) || boot_cpu_has_bug(X86_BUG_AMD_APIC_C1E))
+ return false;
cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &edx);
@@ -901,13 +877,13 @@ static int prefer_mwait_c1_over_halt(const struct cpuinfo_x86 *c)
* with EAX=0, ECX=0.
*/
if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED))
- return 1;
+ return true;
/*
* If MWAIT extensions are available, there should be at least one
* MWAIT C1 substate present.
*/
- return (edx & MWAIT_C1_SUBSTATE_MASK);
+ return !!(edx & MWAIT_C1_SUBSTATE_MASK);
}
/*
@@ -933,26 +909,27 @@ static __cpuidle void mwait_idle(void)
__current_clr_polling();
}
-void select_idle_routine(const struct cpuinfo_x86 *c)
+void __init select_idle_routine(void)
{
-#ifdef CONFIG_SMP
- if (boot_option_idle_override == IDLE_POLL && smp_num_siblings > 1)
- pr_warn_once("WARNING: polling idle and HT enabled, performance may degrade\n");
-#endif
- if (x86_idle_set() || boot_option_idle_override == IDLE_POLL)
+ if (boot_option_idle_override == IDLE_POLL) {
+ if (IS_ENABLED(CONFIG_SMP) && __max_threads_per_core > 1)
+ pr_warn_once("WARNING: polling idle and HT enabled, performance may degrade\n");
+ return;
+ }
+
+ /* Required to guard against xen_set_default_idle() */
+ if (x86_idle_set())
return;
- if (boot_cpu_has_bug(X86_BUG_AMD_E400)) {
- pr_info("using AMD E400 aware idle routine\n");
- static_call_update(x86_idle, amd_e400_idle);
- } else if (prefer_mwait_c1_over_halt(c)) {
+ if (prefer_mwait_c1_over_halt()) {
pr_info("using mwait in idle threads\n");
static_call_update(x86_idle, mwait_idle);
} else if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) {
pr_info("using TDX aware idle routine\n");
static_call_update(x86_idle, tdx_safe_halt);
- } else
+ } else {
static_call_update(x86_idle, default_idle);
+ }
}
void amd_e400_c1e_apic_setup(void)
@@ -985,7 +962,10 @@ void __init arch_post_acpi_subsys_init(void)
if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
mark_tsc_unstable("TSC halt in AMD C1E");
- pr_info("System has AMD C1E enabled\n");
+
+ if (IS_ENABLED(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST_IDLE))
+ static_branch_enable(&arch_needs_tick_broadcast);
+ pr_info("System has AMD C1E erratum E400. Workaround enabled.\n");
}
static int __init idle_setup(char *str)
@@ -998,24 +978,14 @@ static int __init idle_setup(char *str)
boot_option_idle_override = IDLE_POLL;
cpu_idle_poll_ctrl(true);
} else if (!strcmp(str, "halt")) {
- /*
- * When the boot option of idle=halt is added, halt is
- * forced to be used for CPU idle. In such case CPU C2/C3
- * won't be used again.
- * To continue to load the CPU idle driver, don't touch
- * the boot_option_idle_override.
- */
- static_call_update(x86_idle, default_idle);
+ /* 'idle=halt' HALT for idle. C-states are disabled. */
boot_option_idle_override = IDLE_HALT;
} else if (!strcmp(str, "nomwait")) {
- /*
- * If the boot option of "idle=nomwait" is added,
- * it means that mwait will be disabled for CPU C1/C2/C3
- * states.
- */
+ /* 'idle=nomwait' disables MWAIT for idle */
boot_option_idle_override = IDLE_NOMWAIT;
- } else
- return -1;
+ } else {
+ return -EINVAL;
+ }
return 0;
}
@@ -1030,7 +1000,10 @@ unsigned long arch_align_stack(unsigned long sp)
unsigned long arch_randomize_brk(struct mm_struct *mm)
{
- return randomize_page(mm->brk, 0x02000000);
+ if (mmap_is_ia32())
+ return randomize_page(mm->brk, SZ_32M);
+
+ return randomize_page(mm->brk, SZ_1G);
}
/*
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 708c87b88cc1..0917c7f25720 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -156,13 +156,12 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
{
struct thread_struct *prev = &prev_p->thread,
*next = &next_p->thread;
- struct fpu *prev_fpu = &prev->fpu;
int cpu = smp_processor_id();
/* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
- if (!test_thread_flag(TIF_NEED_FPU_LOAD))
- switch_fpu_prepare(prev_fpu, cpu);
+ if (!test_tsk_thread_flag(prev_p, TIF_NEED_FPU_LOAD))
+ switch_fpu_prepare(prev_p, cpu);
/*
* Save away %gs. No need to save %fs, as it was saved on the
@@ -209,7 +208,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
raw_cpu_write(pcpu_hot.current_task, next_p);
- switch_fpu_finish();
+ switch_fpu_finish(next_p);
/* Load the Intel cache allocation PQR MSR. */
resctrl_sched_in(next_p);
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 33b268747bb7..7062b84dd467 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -56,6 +56,7 @@
#include <asm/resctrl.h>
#include <asm/unistd.h>
#include <asm/fsgsbase.h>
+#include <asm/fred.h>
#ifdef CONFIG_IA32_EMULATION
/* Not included via unistd.h */
#include <asm/unistd_32_ia32.h>
@@ -117,7 +118,7 @@ void __show_regs(struct pt_regs *regs, enum show_regs_mode mode,
printk("%sFS: %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n",
log_lvl, fs, fsindex, gs, gsindex, shadowgs);
- printk("%sCS: %04lx DS: %04x ES: %04x CR0: %016lx\n",
+ printk("%sCS: %04x DS: %04x ES: %04x CR0: %016lx\n",
log_lvl, regs->cs, ds, es, cr0);
printk("%sCR2: %016lx CR3: %016lx CR4: %016lx\n",
log_lvl, cr2, cr3, cr4);
@@ -166,7 +167,29 @@ static noinstr unsigned long __rdgsbase_inactive(void)
lockdep_assert_irqs_disabled();
- if (!cpu_feature_enabled(X86_FEATURE_XENPV)) {
+ /*
+ * SWAPGS is no longer needed thus NOT allowed with FRED because
+ * FRED transitions ensure that an operating system can _always_
+ * operate with its own GS base address:
+ * - For events that occur in ring 3, FRED event delivery swaps
+ * the GS base address with the IA32_KERNEL_GS_BASE MSR.
+ * - ERETU (the FRED transition that returns to ring 3) also swaps
+ * the GS base address with the IA32_KERNEL_GS_BASE MSR.
+ *
+ * And the operating system can still setup the GS segment for a
+ * user thread without the need of loading a user thread GS with:
+ * - Using LKGS, available with FRED, to modify other attributes
+ * of the GS segment without compromising its ability always to
+ * operate with its own GS base address.
+ * - Accessing the GS segment base address for a user thread as
+ * before using RDMSR or WRMSR on the IA32_KERNEL_GS_BASE MSR.
+ *
+ * Note, LKGS loads the GS base address into the IA32_KERNEL_GS_BASE
+ * MSR instead of the GS segment’s descriptor cache. As such, the
+ * operating system never changes its runtime GS base address.
+ */
+ if (!cpu_feature_enabled(X86_FEATURE_FRED) &&
+ !cpu_feature_enabled(X86_FEATURE_XENPV)) {
native_swapgs();
gsbase = rdgsbase();
native_swapgs();
@@ -191,7 +214,8 @@ static noinstr void __wrgsbase_inactive(unsigned long gsbase)
{
lockdep_assert_irqs_disabled();
- if (!cpu_feature_enabled(X86_FEATURE_XENPV)) {
+ if (!cpu_feature_enabled(X86_FEATURE_FRED) &&
+ !cpu_feature_enabled(X86_FEATURE_XENPV)) {
native_swapgs();
wrgsbase(gsbase);
native_swapgs();
@@ -505,7 +529,7 @@ void x86_gsbase_write_task(struct task_struct *task, unsigned long gsbase)
static void
start_thread_common(struct pt_regs *regs, unsigned long new_ip,
unsigned long new_sp,
- unsigned int _cs, unsigned int _ss, unsigned int _ds)
+ u16 _cs, u16 _ss, u16 _ds)
{
WARN_ON_ONCE(regs != current_pt_regs());
@@ -522,11 +546,36 @@ start_thread_common(struct pt_regs *regs, unsigned long new_ip,
loadsegment(ds, _ds);
load_gs_index(0);
- regs->ip = new_ip;
- regs->sp = new_sp;
- regs->cs = _cs;
- regs->ss = _ss;
- regs->flags = X86_EFLAGS_IF;
+ regs->ip = new_ip;
+ regs->sp = new_sp;
+ regs->csx = _cs;
+ regs->ssx = _ss;
+ /*
+ * Allow single-step trap and NMI when starting a new task, thus
+ * once the new task enters user space, single-step trap and NMI
+ * are both enabled immediately.
+ *
+ * Entering a new task is logically speaking a return from a
+ * system call (exec, fork, clone, etc.). As such, if ptrace
+ * enables single stepping a single step exception should be
+ * allowed to trigger immediately upon entering user space.
+ * This is not optional.
+ *
+ * NMI should *never* be disabled in user space. As such, this
+ * is an optional, opportunistic way to catch errors.
+ *
+ * Paranoia: High-order 48 bits above the lowest 16 bit SS are
+ * discarded by the legacy IRET instruction on all Intel, AMD,
+ * and Cyrix/Centaur/VIA CPUs, thus can be set unconditionally,
+ * even when FRED is not enabled. But we choose the safer side
+ * to use these bits only when FRED is enabled.
+ */
+ if (cpu_feature_enabled(X86_FEATURE_FRED)) {
+ regs->fred_ss.swevent = true;
+ regs->fred_ss.nmi = true;
+ }
+
+ regs->flags = X86_EFLAGS_IF | X86_EFLAGS_FIXED;
}
void
@@ -562,14 +611,13 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
{
struct thread_struct *prev = &prev_p->thread;
struct thread_struct *next = &next_p->thread;
- struct fpu *prev_fpu = &prev->fpu;
int cpu = smp_processor_id();
WARN_ON_ONCE(IS_ENABLED(CONFIG_DEBUG_ENTRY) &&
this_cpu_read(pcpu_hot.hardirq_stack_inuse));
- if (!test_thread_flag(TIF_NEED_FPU_LOAD))
- switch_fpu_prepare(prev_fpu, cpu);
+ if (!test_tsk_thread_flag(prev_p, TIF_NEED_FPU_LOAD))
+ switch_fpu_prepare(prev_p, cpu);
/* We must save %fs and %gs before load_TLS() because
* %fs and %gs may be cleared by load_TLS().
@@ -623,7 +671,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
raw_cpu_write(pcpu_hot.current_task, next_p);
raw_cpu_write(pcpu_hot.top_of_stack, task_top_of_stack(next_p));
- switch_fpu_finish();
+ switch_fpu_finish(next_p);
/* Reload sp0. */
update_task_stack(next_p);
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index 830425e6d38e..f3130f762784 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -796,7 +796,7 @@ struct machine_ops machine_ops __ro_after_init = {
.emergency_restart = native_machine_emergency_restart,
.restart = native_machine_restart,
.halt = native_machine_halt,
-#ifdef CONFIG_KEXEC_CORE
+#ifdef CONFIG_CRASH_DUMP
.crash_shutdown = native_machine_crash_shutdown,
#endif
};
@@ -826,7 +826,7 @@ void machine_halt(void)
machine_ops.halt();
}
-#ifdef CONFIG_KEXEC_CORE
+#ifdef CONFIG_CRASH_DUMP
void machine_crash_shutdown(struct pt_regs *regs)
{
machine_ops.crash_shutdown(regs);
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 84201071dfac..e125e059e2c4 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -9,7 +9,6 @@
#include <linux/console.h>
#include <linux/crash_dump.h>
#include <linux/dma-map-ops.h>
-#include <linux/dmi.h>
#include <linux/efi.h>
#include <linux/ima.h>
#include <linux/init_ohci1394_dma.h>
@@ -36,6 +35,7 @@
#include <asm/bios_ebda.h>
#include <asm/bugs.h>
#include <asm/cacheinfo.h>
+#include <asm/coco.h>
#include <asm/cpu.h>
#include <asm/efi.h>
#include <asm/gart.h>
@@ -471,7 +471,7 @@ static void __init arch_reserve_crashkernel(void)
bool high = false;
int ret;
- if (!IS_ENABLED(CONFIG_KEXEC_CORE))
+ if (!IS_ENABLED(CONFIG_CRASH_RESERVE))
return;
ret = parse_crashkernel(cmdline, memblock_phys_mem_size(),
@@ -902,7 +902,7 @@ void __init setup_arch(char **cmdline_p)
efi_init();
reserve_ibft_region();
- dmi_setup();
+ x86_init.resources.dmi_setup();
/*
* VMware detection requires dmi to be available, so this
@@ -970,10 +970,8 @@ void __init setup_arch(char **cmdline_p)
high_memory = (void *)__va(max_pfn * PAGE_SIZE - 1) + 1;
#endif
- /*
- * Find and reserve possible boot-time SMP configuration:
- */
- find_smp_config();
+ /* Find and reserve MPTABLE area */
+ x86_init.mpparse.find_mptable();
early_alloc_pgt_buf();
@@ -994,6 +992,7 @@ void __init setup_arch(char **cmdline_p)
* memory size.
*/
mem_encrypt_setup_arch();
+ cc_random_init();
efi_fake_memmap();
efi_find_mirror();
@@ -1090,7 +1089,9 @@ void __init setup_arch(char **cmdline_p)
early_platform_quirks();
+ /* Some platforms need the APIC registered for NUMA configuration */
early_acpi_boot_init();
+ x86_init.mpparse.early_parse_smp_cfg();
x86_flattree_get_config();
@@ -1131,24 +1132,19 @@ void __init setup_arch(char **cmdline_p)
early_quirks();
- /*
- * Read APIC and some other early information from ACPI tables.
- */
- acpi_boot_init();
- x86_dtb_init();
+ topology_apply_cmdline_limits_early();
/*
- * get boot-time SMP configuration:
+ * Parse SMP configuration. Try ACPI first and then the platform
+ * specific parser.
*/
- get_smp_config();
+ acpi_boot_init();
+ x86_init.mpparse.parse_smp_cfg();
- /*
- * Systems w/o ACPI and mptables might not have it mapped the local
- * APIC yet, but prefill_possible_map() might need to access it.
- */
+ /* Last opportunity to detect and map the local APIC */
init_apic_mappings();
- prefill_possible_map();
+ topology_init_possible_cpus();
init_cpu_to_node();
init_gi_nodes();
diff --git a/arch/x86/kernel/sev-shared.c b/arch/x86/kernel/sev-shared.c
index 1d24ec679915..8b04958da5e7 100644
--- a/arch/x86/kernel/sev-shared.c
+++ b/arch/x86/kernel/sev-shared.c
@@ -9,12 +9,18 @@
* and is included directly into both code-bases.
*/
+#include <asm/setup_data.h>
+
#ifndef __BOOT_COMPRESSED
-#define error(v) pr_err(v)
-#define has_cpuflag(f) boot_cpu_has(f)
+#define error(v) pr_err(v)
+#define has_cpuflag(f) boot_cpu_has(f)
+#define sev_printk(fmt, ...) printk(fmt, ##__VA_ARGS__)
+#define sev_printk_rtl(fmt, ...) printk_ratelimited(fmt, ##__VA_ARGS__)
#else
#undef WARN
#define WARN(condition, format...) (!!(condition))
+#define sev_printk(fmt, ...)
+#define sev_printk_rtl(fmt, ...)
#endif
/* I/O parameters for CPUID-related helpers */
@@ -89,7 +95,8 @@ static bool __init sev_es_check_cpu_features(void)
return true;
}
-static void __noreturn sev_es_terminate(unsigned int set, unsigned int reason)
+static void __head __noreturn
+sev_es_terminate(unsigned int set, unsigned int reason)
{
u64 val = GHCB_MSR_TERM_REQ;
@@ -326,13 +333,7 @@ static int sev_cpuid_hv(struct ghcb *ghcb, struct es_em_ctxt *ctxt, struct cpuid
*/
static const struct snp_cpuid_table *snp_cpuid_get_table(void)
{
- void *ptr;
-
- asm ("lea cpuid_table_copy(%%rip), %0"
- : "=r" (ptr)
- : "p" (&cpuid_table_copy));
-
- return ptr;
+ return &RIP_REL_REF(cpuid_table_copy);
}
/*
@@ -391,7 +392,7 @@ static u32 snp_cpuid_calc_xsave_size(u64 xfeatures_en, bool compacted)
return xsave_size;
}
-static bool
+static bool __head
snp_cpuid_get_validated_func(struct cpuid_leaf *leaf)
{
const struct snp_cpuid_table *cpuid_table = snp_cpuid_get_table();
@@ -528,7 +529,8 @@ static int snp_cpuid_postprocess(struct ghcb *ghcb, struct es_em_ctxt *ctxt,
* Returns -EOPNOTSUPP if feature not enabled. Any other non-zero return value
* should be treated as fatal by caller.
*/
-static int snp_cpuid(struct ghcb *ghcb, struct es_em_ctxt *ctxt, struct cpuid_leaf *leaf)
+static int __head
+snp_cpuid(struct ghcb *ghcb, struct es_em_ctxt *ctxt, struct cpuid_leaf *leaf)
{
const struct snp_cpuid_table *cpuid_table = snp_cpuid_get_table();
@@ -556,9 +558,9 @@ static int snp_cpuid(struct ghcb *ghcb, struct es_em_ctxt *ctxt, struct cpuid_le
leaf->eax = leaf->ebx = leaf->ecx = leaf->edx = 0;
/* Skip post-processing for out-of-range zero leafs. */
- if (!(leaf->fn <= cpuid_std_range_max ||
- (leaf->fn >= 0x40000000 && leaf->fn <= cpuid_hyp_range_max) ||
- (leaf->fn >= 0x80000000 && leaf->fn <= cpuid_ext_range_max)))
+ if (!(leaf->fn <= RIP_REL_REF(cpuid_std_range_max) ||
+ (leaf->fn >= 0x40000000 && leaf->fn <= RIP_REL_REF(cpuid_hyp_range_max)) ||
+ (leaf->fn >= 0x80000000 && leaf->fn <= RIP_REL_REF(cpuid_ext_range_max))))
return 0;
}
@@ -570,10 +572,11 @@ static int snp_cpuid(struct ghcb *ghcb, struct es_em_ctxt *ctxt, struct cpuid_le
* page yet, so it only supports the MSR based communication with the
* hypervisor and only the CPUID exit-code.
*/
-void __init do_vc_no_ghcb(struct pt_regs *regs, unsigned long exit_code)
+void __head do_vc_no_ghcb(struct pt_regs *regs, unsigned long exit_code)
{
unsigned int subfn = lower_bits(regs->cx, 32);
unsigned int fn = lower_bits(regs->ax, 32);
+ u16 opcode = *(unsigned short *)regs->ip;
struct cpuid_leaf leaf;
int ret;
@@ -581,6 +584,10 @@ void __init do_vc_no_ghcb(struct pt_regs *regs, unsigned long exit_code)
if (exit_code != SVM_EXIT_CPUID)
goto fail;
+ /* Is it really a CPUID insn? */
+ if (opcode != 0xa20f)
+ goto fail;
+
leaf.fn = fn;
leaf.subfn = subfn;
@@ -1016,7 +1023,8 @@ struct cc_setup_data {
* Search for a Confidential Computing blob passed in as a setup_data entry
* via the Linux Boot Protocol.
*/
-static struct cc_blob_sev_info *find_cc_blob_setup_data(struct boot_params *bp)
+static __head
+struct cc_blob_sev_info *find_cc_blob_setup_data(struct boot_params *bp)
{
struct cc_setup_data *sd = NULL;
struct setup_data *hdr;
@@ -1043,7 +1051,7 @@ static struct cc_blob_sev_info *find_cc_blob_setup_data(struct boot_params *bp)
* mapping needs to be updated in sync with all the changes to virtual memory
* layout and related mapping facilities throughout the boot process.
*/
-static void __init setup_cpuid_table(const struct cc_blob_sev_info *cc_info)
+static void __head setup_cpuid_table(const struct cc_blob_sev_info *cc_info)
{
const struct snp_cpuid_table *cpuid_table_fw, *cpuid_table;
int i;
@@ -1063,11 +1071,11 @@ static void __init setup_cpuid_table(const struct cc_blob_sev_info *cc_info)
const struct snp_cpuid_fn *fn = &cpuid_table->fn[i];
if (fn->eax_in == 0x0)
- cpuid_std_range_max = fn->eax;
+ RIP_REL_REF(cpuid_std_range_max) = fn->eax;
else if (fn->eax_in == 0x40000000)
- cpuid_hyp_range_max = fn->eax;
+ RIP_REL_REF(cpuid_hyp_range_max) = fn->eax;
else if (fn->eax_in == 0x80000000)
- cpuid_ext_range_max = fn->eax;
+ RIP_REL_REF(cpuid_ext_range_max) = fn->eax;
}
}
@@ -1170,3 +1178,92 @@ static int vmgexit_psc(struct ghcb *ghcb, struct snp_psc_desc *desc)
out:
return ret;
}
+
+static enum es_result vc_check_opcode_bytes(struct es_em_ctxt *ctxt,
+ unsigned long exit_code)
+{
+ unsigned int opcode = (unsigned int)ctxt->insn.opcode.value;
+ u8 modrm = ctxt->insn.modrm.value;
+
+ switch (exit_code) {
+
+ case SVM_EXIT_IOIO:
+ case SVM_EXIT_NPF:
+ /* handled separately */
+ return ES_OK;
+
+ case SVM_EXIT_CPUID:
+ if (opcode == 0xa20f)
+ return ES_OK;
+ break;
+
+ case SVM_EXIT_INVD:
+ if (opcode == 0x080f)
+ return ES_OK;
+ break;
+
+ case SVM_EXIT_MONITOR:
+ if (opcode == 0x010f && modrm == 0xc8)
+ return ES_OK;
+ break;
+
+ case SVM_EXIT_MWAIT:
+ if (opcode == 0x010f && modrm == 0xc9)
+ return ES_OK;
+ break;
+
+ case SVM_EXIT_MSR:
+ /* RDMSR */
+ if (opcode == 0x320f ||
+ /* WRMSR */
+ opcode == 0x300f)
+ return ES_OK;
+ break;
+
+ case SVM_EXIT_RDPMC:
+ if (opcode == 0x330f)
+ return ES_OK;
+ break;
+
+ case SVM_EXIT_RDTSC:
+ if (opcode == 0x310f)
+ return ES_OK;
+ break;
+
+ case SVM_EXIT_RDTSCP:
+ if (opcode == 0x010f && modrm == 0xf9)
+ return ES_OK;
+ break;
+
+ case SVM_EXIT_READ_DR7:
+ if (opcode == 0x210f &&
+ X86_MODRM_REG(ctxt->insn.modrm.value) == 7)
+ return ES_OK;
+ break;
+
+ case SVM_EXIT_VMMCALL:
+ if (opcode == 0x010f && modrm == 0xd9)
+ return ES_OK;
+
+ break;
+
+ case SVM_EXIT_WRITE_DR7:
+ if (opcode == 0x230f &&
+ X86_MODRM_REG(ctxt->insn.modrm.value) == 7)
+ return ES_OK;
+ break;
+
+ case SVM_EXIT_WBINVD:
+ if (opcode == 0x90f)
+ return ES_OK;
+ break;
+
+ default:
+ break;
+ }
+
+ sev_printk(KERN_ERR "Wrong/unhandled opcode bytes: 0x%x, exit_code: 0x%lx, rIP: 0x%lx\n",
+ opcode, exit_code, ctxt->regs->ip);
+
+ return ES_UNSUPPORTED;
+}
diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c
index c67285824e82..38ad066179d8 100644
--- a/arch/x86/kernel/sev.c
+++ b/arch/x86/kernel/sev.c
@@ -23,8 +23,10 @@
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/psp-sev.h>
+#include <linux/dmi.h>
#include <uapi/linux/sev-guest.h>
+#include <asm/init.h>
#include <asm/cpu_entry_area.h>
#include <asm/stacktrace.h>
#include <asm/sev.h>
@@ -59,6 +61,25 @@
#define AP_INIT_CR0_DEFAULT 0x60000010
#define AP_INIT_MXCSR_DEFAULT 0x1f80
+static const char * const sev_status_feat_names[] = {
+ [MSR_AMD64_SEV_ENABLED_BIT] = "SEV",
+ [MSR_AMD64_SEV_ES_ENABLED_BIT] = "SEV-ES",
+ [MSR_AMD64_SEV_SNP_ENABLED_BIT] = "SEV-SNP",
+ [MSR_AMD64_SNP_VTOM_BIT] = "vTom",
+ [MSR_AMD64_SNP_REFLECT_VC_BIT] = "ReflectVC",
+ [MSR_AMD64_SNP_RESTRICTED_INJ_BIT] = "RI",
+ [MSR_AMD64_SNP_ALT_INJ_BIT] = "AI",
+ [MSR_AMD64_SNP_DEBUG_SWAP_BIT] = "DebugSwap",
+ [MSR_AMD64_SNP_PREVENT_HOST_IBS_BIT] = "NoHostIBS",
+ [MSR_AMD64_SNP_BTB_ISOLATION_BIT] = "BTBIsol",
+ [MSR_AMD64_SNP_VMPL_SSS_BIT] = "VmplSSS",
+ [MSR_AMD64_SNP_SECURE_TSC_BIT] = "SecureTSC",
+ [MSR_AMD64_SNP_VMGEXIT_PARAM_BIT] = "VMGExitParam",
+ [MSR_AMD64_SNP_IBS_VIRT_BIT] = "IBSVirt",
+ [MSR_AMD64_SNP_VMSA_REG_PROT_BIT] = "VMSARegProt",
+ [MSR_AMD64_SNP_SMT_PROT_BIT] = "SMTProt",
+};
+
/* For early boot hypervisor communication in SEV-ES enabled guests */
static struct ghcb boot_ghcb_page __bss_decrypted __aligned(PAGE_SIZE);
@@ -682,8 +703,9 @@ static u64 __init get_jump_table_addr(void)
return ret;
}
-static void early_set_pages_state(unsigned long vaddr, unsigned long paddr,
- unsigned long npages, enum psc_op op)
+static void __head
+early_set_pages_state(unsigned long vaddr, unsigned long paddr,
+ unsigned long npages, enum psc_op op)
{
unsigned long paddr_end;
u64 val;
@@ -739,7 +761,7 @@ e_term:
sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PSC);
}
-void __init early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr,
+void __head early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr,
unsigned long npages)
{
/*
@@ -748,7 +770,7 @@ void __init early_snp_set_memory_private(unsigned long vaddr, unsigned long padd
* This eliminates worries about jump tables or checking boot_cpu_data
* in the cc_platform_has() function.
*/
- if (!(sev_status & MSR_AMD64_SEV_SNP_ENABLED))
+ if (!(RIP_REL_REF(sev_status) & MSR_AMD64_SEV_SNP_ENABLED))
return;
/*
@@ -767,28 +789,13 @@ void __init early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr
* This eliminates worries about jump tables or checking boot_cpu_data
* in the cc_platform_has() function.
*/
- if (!(sev_status & MSR_AMD64_SEV_SNP_ENABLED))
+ if (!(RIP_REL_REF(sev_status) & MSR_AMD64_SEV_SNP_ENABLED))
return;
/* Ask hypervisor to mark the memory pages shared in the RMP table. */
early_set_pages_state(vaddr, paddr, npages, SNP_PAGE_STATE_SHARED);
}
-void __init snp_prep_memory(unsigned long paddr, unsigned int sz, enum psc_op op)
-{
- unsigned long vaddr, npages;
-
- vaddr = (unsigned long)__va(paddr);
- npages = PAGE_ALIGN(sz) >> PAGE_SHIFT;
-
- if (op == SNP_PAGE_STATE_PRIVATE)
- early_snp_set_memory_private(vaddr, paddr, npages);
- else if (op == SNP_PAGE_STATE_SHARED)
- early_snp_set_memory_shared(vaddr, paddr, npages);
- else
- WARN(1, "invalid memory op %d\n", op);
-}
-
static unsigned long __set_pages_state(struct snp_psc_desc *data, unsigned long vaddr,
unsigned long vaddr_end, int op)
{
@@ -1752,7 +1759,10 @@ static enum es_result vc_handle_exitcode(struct es_em_ctxt *ctxt,
struct ghcb *ghcb,
unsigned long exit_code)
{
- enum es_result result;
+ enum es_result result = vc_check_opcode_bytes(ctxt, exit_code);
+
+ if (result != ES_OK)
+ return result;
switch (exit_code) {
case SVM_EXIT_READ_DR7:
@@ -2059,7 +2069,7 @@ fail:
*
* Scan for the blob in that order.
*/
-static __init struct cc_blob_sev_info *find_cc_blob(struct boot_params *bp)
+static __head struct cc_blob_sev_info *find_cc_blob(struct boot_params *bp)
{
struct cc_blob_sev_info *cc_info;
@@ -2085,7 +2095,7 @@ found_cc_info:
return cc_info;
}
-bool __init snp_init(struct boot_params *bp)
+bool __head snp_init(struct boot_params *bp)
{
struct cc_blob_sev_info *cc_info;
@@ -2107,11 +2117,22 @@ bool __init snp_init(struct boot_params *bp)
return true;
}
-void __init __noreturn snp_abort(void)
+void __head __noreturn snp_abort(void)
{
sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED);
}
+/*
+ * SEV-SNP guests should only execute dmi_setup() if EFI_CONFIG_TABLES are
+ * enabled, as the alternative (fallback) logic for DMI probing in the legacy
+ * ROM region can cause a crash since this region is not pre-validated.
+ */
+void __init snp_dmi_setup(void)
+{
+ if (efi_enabled(EFI_CONFIG_TABLES))
+ dmi_setup();
+}
+
static void dump_cpuid_table(void)
{
const struct snp_cpuid_table *cpuid_table = snp_cpuid_get_table();
@@ -2262,3 +2283,19 @@ static int __init snp_init_platform_device(void)
return 0;
}
device_initcall(snp_init_platform_device);
+
+void sev_show_status(void)
+{
+ int i;
+
+ pr_info("Status: ");
+ for (i = 0; i < MSR_AMD64_SNP_RESV_BIT; i++) {
+ if (sev_status & BIT_ULL(i)) {
+ if (!sev_status_feat_names[i])
+ continue;
+
+ pr_cont("%s ", sev_status_feat_names[i]);
+ }
+ }
+ pr_cont("\n");
+}
diff --git a/arch/x86/kernel/sev_verify_cbit.S b/arch/x86/kernel/sev_verify_cbit.S
index 3355e27c69eb..1ab65f6c6ae7 100644
--- a/arch/x86/kernel/sev_verify_cbit.S
+++ b/arch/x86/kernel/sev_verify_cbit.S
@@ -77,7 +77,7 @@ SYM_FUNC_START(sev_verify_cbit)
* The check failed, prevent any forward progress to prevent ROP
* attacks, invalidate the stack and go into a hlt loop.
*/
- xorq %rsp, %rsp
+ xorl %esp, %esp
subq $0x1000, %rsp
2: hlt
jmp 2b
diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c
index 96a771f9f930..18266cc3d98c 100644
--- a/arch/x86/kernel/smp.c
+++ b/arch/x86/kernel/smp.c
@@ -148,14 +148,16 @@ static int register_stop_handler(void)
static void native_stop_other_cpus(int wait)
{
- unsigned int cpu = smp_processor_id();
+ unsigned int old_cpu, this_cpu;
unsigned long flags, timeout;
if (reboot_force)
return;
/* Only proceed if this is the first CPU to reach this code */
- if (atomic_cmpxchg(&stopping_cpu, -1, cpu) != -1)
+ old_cpu = -1;
+ this_cpu = smp_processor_id();
+ if (!atomic_try_cmpxchg(&stopping_cpu, &old_cpu, this_cpu))
return;
/* For kexec, ensure that offline CPUs are out of MWAIT and in HLT */
@@ -186,7 +188,7 @@ static void native_stop_other_cpus(int wait)
* NMIs.
*/
cpumask_copy(&cpus_stop_mask, cpu_online_mask);
- cpumask_clear_cpu(cpu, &cpus_stop_mask);
+ cpumask_clear_cpu(this_cpu, &cpus_stop_mask);
if (!cpumask_empty(&cpus_stop_mask)) {
apic_send_IPI_allbutself(REBOOT_VECTOR);
@@ -210,6 +212,8 @@ static void native_stop_other_cpus(int wait)
* CPUs to stop.
*/
if (!smp_no_nmi_ipi && !register_stop_handler()) {
+ unsigned int cpu;
+
pr_emerg("Shutting down cpus with NMI\n");
for_each_cpu(cpu, &cpus_stop_mask)
@@ -282,7 +286,7 @@ struct smp_ops smp_ops = {
.smp_cpus_done = native_smp_cpus_done,
.stop_other_cpus = native_stop_other_cpus,
-#if defined(CONFIG_KEXEC_CORE)
+#if defined(CONFIG_CRASH_DUMP)
.crash_stop_other_cpus = kdump_nmi_shootdown_cpus,
#endif
.smp_send_reschedule = native_smp_send_reschedule,
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 3f57ce68a3f1..76bb65045c64 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -101,10 +101,6 @@ EXPORT_PER_CPU_SYMBOL(cpu_core_map);
DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_die_map);
EXPORT_PER_CPU_SYMBOL(cpu_die_map);
-/* Per CPU bogomips and other parameters */
-DEFINE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info);
-EXPORT_PER_CPU_SYMBOL(cpu_info);
-
/* CPUs which are the primary SMT threads */
struct cpumask __cpu_primary_thread_mask __read_mostly;
@@ -125,25 +121,6 @@ struct mwait_cpu_dead {
*/
static DEFINE_PER_CPU_ALIGNED(struct mwait_cpu_dead, mwait_cpu_dead);
-/* Logical package management. */
-struct logical_maps {
- u32 phys_pkg_id;
- u32 phys_die_id;
- u32 logical_pkg_id;
- u32 logical_die_id;
-};
-
-/* Temporary workaround until the full topology mechanics is in place */
-static DEFINE_PER_CPU_READ_MOSTLY(struct logical_maps, logical_maps) = {
- .phys_pkg_id = U32_MAX,
- .phys_die_id = U32_MAX,
-};
-
-unsigned int __max_logical_packages __read_mostly;
-EXPORT_SYMBOL(__max_logical_packages);
-static unsigned int logical_packages __read_mostly;
-static unsigned int logical_die __read_mostly;
-
/* Maximum number of SMT threads on any online core */
int __read_mostly __max_smt_threads = 1;
@@ -336,106 +313,6 @@ static void notrace start_secondary(void *unused)
cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
}
-/**
- * topology_phys_to_logical_pkg - Map a physical package id to a logical
- * @phys_pkg: The physical package id to map
- *
- * Returns logical package id or -1 if not found
- */
-int topology_phys_to_logical_pkg(unsigned int phys_pkg)
-{
- int cpu;
-
- for_each_possible_cpu(cpu) {
- if (per_cpu(logical_maps.phys_pkg_id, cpu) == phys_pkg)
- return per_cpu(logical_maps.logical_pkg_id, cpu);
- }
- return -1;
-}
-EXPORT_SYMBOL(topology_phys_to_logical_pkg);
-
-/**
- * topology_phys_to_logical_die - Map a physical die id to logical
- * @die_id: The physical die id to map
- * @cur_cpu: The CPU for which the mapping is done
- *
- * Returns logical die id or -1 if not found
- */
-static int topology_phys_to_logical_die(unsigned int die_id, unsigned int cur_cpu)
-{
- int cpu, proc_id = cpu_data(cur_cpu).topo.pkg_id;
-
- for_each_possible_cpu(cpu) {
- if (per_cpu(logical_maps.phys_pkg_id, cpu) == proc_id &&
- per_cpu(logical_maps.phys_die_id, cpu) == die_id)
- return per_cpu(logical_maps.logical_die_id, cpu);
- }
- return -1;
-}
-
-/**
- * topology_update_package_map - Update the physical to logical package map
- * @pkg: The physical package id as retrieved via CPUID
- * @cpu: The cpu for which this is updated
- */
-int topology_update_package_map(unsigned int pkg, unsigned int cpu)
-{
- int new;
-
- /* Already available somewhere? */
- new = topology_phys_to_logical_pkg(pkg);
- if (new >= 0)
- goto found;
-
- new = logical_packages++;
- if (new != pkg) {
- pr_info("CPU %u Converting physical %u to logical package %u\n",
- cpu, pkg, new);
- }
-found:
- per_cpu(logical_maps.phys_pkg_id, cpu) = pkg;
- per_cpu(logical_maps.logical_pkg_id, cpu) = new;
- cpu_data(cpu).topo.logical_pkg_id = new;
- return 0;
-}
-/**
- * topology_update_die_map - Update the physical to logical die map
- * @die: The die id as retrieved via CPUID
- * @cpu: The cpu for which this is updated
- */
-int topology_update_die_map(unsigned int die, unsigned int cpu)
-{
- int new;
-
- /* Already available somewhere? */
- new = topology_phys_to_logical_die(die, cpu);
- if (new >= 0)
- goto found;
-
- new = logical_die++;
- if (new != die) {
- pr_info("CPU %u Converting physical %u to logical die %u\n",
- cpu, die, new);
- }
-found:
- per_cpu(logical_maps.phys_die_id, cpu) = die;
- per_cpu(logical_maps.logical_die_id, cpu) = new;
- cpu_data(cpu).topo.logical_die_id = new;
- return 0;
-}
-
-static void __init smp_store_boot_cpu_info(void)
-{
- int id = 0; /* CPU 0 */
- struct cpuinfo_x86 *c = &cpu_data(id);
-
- *c = boot_cpu_data;
- c->cpu_index = id;
- topology_update_package_map(c->topo.pkg_id, id);
- topology_update_die_map(c->topo.die_id, id);
- c->initialized = true;
-}
-
/*
* The bootstrap kernel entry code has set these up. Save them for
* a given CPU
@@ -488,6 +365,7 @@ static bool match_smt(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
if (c->topo.pkg_id == o->topo.pkg_id &&
c->topo.die_id == o->topo.die_id &&
+ c->topo.amd_node_id == o->topo.amd_node_id &&
per_cpu_llc_id(cpu1) == per_cpu_llc_id(cpu2)) {
if (c->topo.core_id == o->topo.core_id)
return topology_sane(c, o, "smt");
@@ -509,10 +387,13 @@ static bool match_smt(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
static bool match_die(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
{
- if (c->topo.pkg_id == o->topo.pkg_id &&
- c->topo.die_id == o->topo.die_id)
- return true;
- return false;
+ if (c->topo.pkg_id != o->topo.pkg_id || c->topo.die_id != o->topo.die_id)
+ return false;
+
+ if (cpu_feature_enabled(X86_FEATURE_TOPOEXT) && topology_amd_nodes_per_pkg() > 1)
+ return c->topo.amd_node_id == o->topo.amd_node_id;
+
+ return true;
}
static bool match_l2c(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
@@ -670,8 +551,8 @@ static void __init build_sched_topology(void)
void set_cpu_sibling_map(int cpu)
{
- bool has_smt = smp_num_siblings > 1;
- bool has_mp = has_smt || boot_cpu_data.x86_max_cores > 1;
+ bool has_smt = __max_threads_per_core > 1;
+ bool has_mp = has_smt || topology_num_cores_per_package() > 1;
struct cpuinfo_x86 *c = &cpu_data(cpu);
struct cpuinfo_x86 *o;
int i, threads;
@@ -1068,9 +949,13 @@ int native_kick_ap(unsigned int cpu, struct task_struct *tidle)
pr_debug("++++++++++++++++++++=_---CPU UP %u\n", cpu);
- if (apicid == BAD_APICID || !physid_isset(apicid, phys_cpu_present_map) ||
- !apic_id_valid(apicid)) {
- pr_err("%s: bad cpu %d\n", __func__, cpu);
+ if (apicid == BAD_APICID || !apic_id_valid(apicid)) {
+ pr_err("CPU %u has invalid APIC ID %x. Aborting bringup\n", cpu, apicid);
+ return -EINVAL;
+ }
+
+ if (!test_bit(apicid, phys_cpu_present_map)) {
+ pr_err("CPU %u APIC ID %x is not present. Aborting bringup\n", cpu, apicid);
return -EINVAL;
}
@@ -1139,42 +1024,22 @@ static __init void disable_smp(void)
pr_info("SMP disabled\n");
disable_ioapic_support();
+ topology_reset_possible_cpus_up();
- init_cpu_present(cpumask_of(0));
- init_cpu_possible(cpumask_of(0));
-
- if (smp_found_config)
- physid_set_mask_of_physid(boot_cpu_physical_apicid, &phys_cpu_present_map);
- else
- physid_set_mask_of_physid(0, &phys_cpu_present_map);
cpumask_set_cpu(0, topology_sibling_cpumask(0));
cpumask_set_cpu(0, topology_core_cpumask(0));
cpumask_set_cpu(0, topology_die_cpumask(0));
}
-static void __init smp_cpu_index_default(void)
-{
- int i;
- struct cpuinfo_x86 *c;
-
- for_each_possible_cpu(i) {
- c = &cpu_data(i);
- /* mark all to hotplug */
- c->cpu_index = nr_cpu_ids;
- }
-}
-
void __init smp_prepare_cpus_common(void)
{
unsigned int i;
- smp_cpu_index_default();
-
- /*
- * Setup boot CPU information
- */
- smp_store_boot_cpu_info(); /* Final full version of the data */
- mb();
+ /* 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(i) {
zalloc_cpumask_var(&per_cpu(cpu_sibling_map, i), GFP_KERNEL);
@@ -1187,6 +1052,11 @@ void __init smp_prepare_cpus_common(void)
set_cpu_sibling_map(0);
}
+void __init smp_prepare_boot_cpu(void)
+{
+ smp_ops.smp_prepare_boot_cpu();
+}
+
#ifdef CONFIG_X86_64
/* Establish whether parallel bringup can be supported. */
bool __init arch_cpuhp_init_parallel_bringup(void)
@@ -1265,102 +1135,16 @@ void __init native_smp_prepare_boot_cpu(void)
native_pv_lock_init();
}
-void __init calculate_max_logical_packages(void)
-{
- int ncpus;
-
- /*
- * Today neither Intel nor AMD support heterogeneous systems so
- * extrapolate the boot cpu's data to all packages.
- */
- ncpus = cpu_data(0).booted_cores * topology_max_smt_threads();
- __max_logical_packages = DIV_ROUND_UP(total_cpus, ncpus);
- pr_info("Max logical packages: %u\n", __max_logical_packages);
-}
-
void __init native_smp_cpus_done(unsigned int max_cpus)
{
pr_debug("Boot done\n");
- calculate_max_logical_packages();
build_sched_topology();
nmi_selftest();
impress_friends();
cache_aps_init();
}
-static int __initdata setup_possible_cpus = -1;
-static int __init _setup_possible_cpus(char *str)
-{
- get_option(&str, &setup_possible_cpus);
- return 0;
-}
-early_param("possible_cpus", _setup_possible_cpus);
-
-
-/*
- * cpu_possible_mask should be static, it cannot change as cpu's
- * are onlined, or offlined. The reason is per-cpu data-structures
- * are allocated by some modules at init time, and don't expect to
- * do this dynamically on cpu arrival/departure.
- * cpu_present_mask on the other hand can change dynamically.
- * In case when cpu_hotplug is not compiled, then we resort to current
- * behaviour, which is cpu_possible == cpu_present.
- * - Ashok Raj
- *
- * Three ways to find out the number of additional hotplug CPUs:
- * - If the BIOS specified disabled CPUs in ACPI/mptables use that.
- * - The user can overwrite it with possible_cpus=NUM
- * - Otherwise don't reserve additional CPUs.
- * We do this because additional CPUs waste a lot of memory.
- * -AK
- */
-__init void prefill_possible_map(void)
-{
- int i, possible;
-
- i = setup_max_cpus ?: 1;
- if (setup_possible_cpus == -1) {
- possible = num_processors;
-#ifdef CONFIG_HOTPLUG_CPU
- if (setup_max_cpus)
- possible += disabled_cpus;
-#else
- if (possible > i)
- possible = i;
-#endif
- } else
- possible = setup_possible_cpus;
-
- total_cpus = max_t(int, possible, num_processors + disabled_cpus);
-
- /* nr_cpu_ids could be reduced via nr_cpus= */
- if (possible > nr_cpu_ids) {
- pr_warn("%d Processors exceeds NR_CPUS limit of %u\n",
- possible, nr_cpu_ids);
- possible = nr_cpu_ids;
- }
-
-#ifdef CONFIG_HOTPLUG_CPU
- if (!setup_max_cpus)
-#endif
- if (possible > i) {
- pr_warn("%d Processors exceeds max_cpus limit of %u\n",
- possible, setup_max_cpus);
- possible = i;
- }
-
- set_nr_cpu_ids(possible);
-
- pr_info("Allowing %d CPUs, %d hotplug CPUs\n",
- possible, max_t(int, possible - num_processors, 0));
-
- reset_cpu_possible_mask();
-
- for (i = 0; i < possible; i++)
- set_cpu_possible(i, true);
-}
-
/* correctly size the local cpu masks */
void __init setup_cpu_local_masks(void)
{
diff --git a/arch/x86/kernel/static_call.c b/arch/x86/kernel/static_call.c
index 77a9316da435..4eefaac64c6c 100644
--- a/arch/x86/kernel/static_call.c
+++ b/arch/x86/kernel/static_call.c
@@ -172,7 +172,7 @@ void arch_static_call_transform(void *site, void *tramp, void *func, bool tail)
}
EXPORT_SYMBOL_GPL(arch_static_call_transform);
-#ifdef CONFIG_RETHUNK
+#ifdef CONFIG_MITIGATION_RETHUNK
/*
* This is called by apply_returns() to fix up static call trampolines,
* specifically ARCH_DEFINE_STATIC_CALL_NULL_TRAMP which is recorded as
diff --git a/arch/x86/kernel/step.c b/arch/x86/kernel/step.c
index 8e2b2552b5ee..3e2952679b88 100644
--- a/arch/x86/kernel/step.c
+++ b/arch/x86/kernel/step.c
@@ -6,7 +6,9 @@
#include <linux/sched/task_stack.h>
#include <linux/mm.h>
#include <linux/ptrace.h>
+
#include <asm/desc.h>
+#include <asm/debugreg.h>
#include <asm/mmu_context.h>
unsigned long convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs)
diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
index c783aeb37dce..cb9fa1d5c66f 100644
--- a/arch/x86/kernel/sys_x86_64.c
+++ b/arch/x86/kernel/sys_x86_64.c
@@ -52,13 +52,6 @@ static unsigned long get_align_bits(void)
return va_align.bits & get_align_mask();
}
-unsigned long align_vdso_addr(unsigned long addr)
-{
- unsigned long align_mask = get_align_mask();
- addr = (addr + align_mask) & ~align_mask;
- return addr | get_align_bits();
-}
-
static int __init control_va_addr_alignment(char *str)
{
/* guard against enabling this on other CPU families */
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index c3b2f863acf0..4fa0b17e5043 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -51,6 +51,7 @@
#include <asm/ftrace.h>
#include <asm/traps.h>
#include <asm/desc.h>
+#include <asm/fred.h>
#include <asm/fpu/api.h>
#include <asm/cpu.h>
#include <asm/cpu_entry_area.h>
@@ -773,7 +774,7 @@ DEFINE_IDTENTRY_RAW(exc_int3)
*/
asmlinkage __visible noinstr struct pt_regs *sync_regs(struct pt_regs *eregs)
{
- struct pt_regs *regs = (struct pt_regs *)this_cpu_read(pcpu_hot.top_of_stack) - 1;
+ struct pt_regs *regs = (struct pt_regs *)current_top_of_stack() - 1;
if (regs != eregs)
*regs = *eregs;
return regs;
@@ -791,7 +792,7 @@ asmlinkage __visible noinstr struct pt_regs *vc_switch_off_ist(struct pt_regs *r
* trust it and switch to the current kernel stack
*/
if (ip_within_syscall_gap(regs)) {
- sp = this_cpu_read(pcpu_hot.top_of_stack);
+ sp = current_top_of_stack();
goto sync;
}
@@ -935,8 +936,7 @@ static bool notify_debug(struct pt_regs *regs, unsigned long *dr6)
return false;
}
-static __always_inline void exc_debug_kernel(struct pt_regs *regs,
- unsigned long dr6)
+static noinstr void exc_debug_kernel(struct pt_regs *regs, unsigned long dr6)
{
/*
* Disable breakpoints during exception handling; recursive exceptions
@@ -948,6 +948,11 @@ static __always_inline void exc_debug_kernel(struct pt_regs *regs,
*
* Entry text is excluded for HW_BP_X and cpu_entry_area, which
* includes the entry stack is excluded for everything.
+ *
+ * For FRED, nested #DB should just work fine. But when a watchpoint or
+ * breakpoint is set in the code path which is executed by #DB handler,
+ * it results in an endless recursion and stack overflow. Thus we stay
+ * with the IDT approach, i.e., save DR7 and disable #DB.
*/
unsigned long dr7 = local_db_save();
irqentry_state_t irq_state = irqentry_nmi_enter(regs);
@@ -977,7 +982,8 @@ static __always_inline void exc_debug_kernel(struct pt_regs *regs,
* Catch SYSENTER with TF set and clear DR_STEP. If this hit a
* watchpoint at the same time then that will still be handled.
*/
- if ((dr6 & DR_STEP) && is_sysenter_singlestep(regs))
+ if (!cpu_feature_enabled(X86_FEATURE_FRED) &&
+ (dr6 & DR_STEP) && is_sysenter_singlestep(regs))
dr6 &= ~DR_STEP;
/*
@@ -1009,8 +1015,7 @@ out:
local_db_restore(dr7);
}
-static __always_inline void exc_debug_user(struct pt_regs *regs,
- unsigned long dr6)
+static noinstr void exc_debug_user(struct pt_regs *regs, unsigned long dr6)
{
bool icebp;
@@ -1094,6 +1099,34 @@ DEFINE_IDTENTRY_DEBUG_USER(exc_debug)
{
exc_debug_user(regs, debug_read_clear_dr6());
}
+
+#ifdef CONFIG_X86_FRED
+/*
+ * When occurred on different ring level, i.e., from user or kernel
+ * context, #DB needs to be handled on different stack: User #DB on
+ * current task stack, while kernel #DB on a dedicated stack.
+ *
+ * This is exactly how FRED event delivery invokes an exception
+ * handler: ring 3 event on level 0 stack, i.e., current task stack;
+ * ring 0 event on the #DB dedicated stack specified in the
+ * IA32_FRED_STKLVLS MSR. So unlike IDT, the FRED debug exception
+ * entry stub doesn't do stack switch.
+ */
+DEFINE_FREDENTRY_DEBUG(exc_debug)
+{
+ /*
+ * FRED #DB stores DR6 on the stack in the format which
+ * debug_read_clear_dr6() returns for the IDT entry points.
+ */
+ unsigned long dr6 = fred_event_data(regs);
+
+ if (user_mode(regs))
+ exc_debug_user(regs, dr6);
+ else
+ exc_debug_kernel(regs, dr6);
+}
+#endif /* CONFIG_X86_FRED */
+
#else
/* 32 bit does not have separate entry points. */
DEFINE_IDTENTRY_RAW(exc_debug)
@@ -1369,8 +1402,34 @@ DEFINE_IDTENTRY_SW(iret_error)
}
#endif
+/* Do not enable FRED by default yet. */
+static bool enable_fred __ro_after_init = false;
+
+#ifdef CONFIG_X86_FRED
+static int __init fred_setup(char *str)
+{
+ if (!str)
+ return -EINVAL;
+
+ if (!cpu_feature_enabled(X86_FEATURE_FRED))
+ return 0;
+
+ if (!strcmp(str, "on"))
+ enable_fred = true;
+ else if (!strcmp(str, "off"))
+ enable_fred = false;
+ else
+ pr_warn("invalid FRED option: 'fred=%s'\n", str);
+ return 0;
+}
+early_param("fred", fred_setup);
+#endif
+
void __init trap_init(void)
{
+ if (cpu_feature_enabled(X86_FEATURE_FRED) && !enable_fred)
+ setup_clear_cpu_cap(X86_FEATURE_FRED);
+
/* Init cpu_entry_area before IST entries are set up */
setup_cpu_entry_areas();
@@ -1379,7 +1438,10 @@ void __init trap_init(void)
/* Initialize TSS before setting up traps so ISTs work */
cpu_init_exception_handling();
+
/* Setup traps as cpu_init() might #GP */
- idt_setup_traps();
+ if (!cpu_feature_enabled(X86_FEATURE_FRED))
+ idt_setup_traps();
+
cpu_init();
}
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 15f97c0abc9d..5a69a49acc96 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -53,7 +53,7 @@ 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 *art_related_clocksource;
+static bool have_art;
struct cyc2ns {
struct cyc2ns_data data[2]; /* 0 + 2*16 = 32 */
@@ -652,7 +652,7 @@ success:
}
/**
- * native_calibrate_tsc
+ * native_calibrate_tsc - determine TSC frequency
* Determine TSC frequency via CPUID, else return 0.
*/
unsigned long native_calibrate_tsc(void)
@@ -1168,6 +1168,7 @@ static struct clocksource clocksource_tsc_early = {
.mask = CLOCKSOURCE_MASK(64),
.flags = CLOCK_SOURCE_IS_CONTINUOUS |
CLOCK_SOURCE_MUST_VERIFY,
+ .id = CSID_X86_TSC_EARLY,
.vdso_clock_mode = VDSO_CLOCKMODE_TSC,
.enable = tsc_cs_enable,
.resume = tsc_resume,
@@ -1190,6 +1191,7 @@ static struct clocksource clocksource_tsc = {
CLOCK_SOURCE_VALID_FOR_HRES |
CLOCK_SOURCE_MUST_VERIFY |
CLOCK_SOURCE_VERIFY_PERCPU,
+ .id = CSID_X86_TSC,
.vdso_clock_mode = VDSO_CLOCKMODE_TSC,
.enable = tsc_cs_enable,
.resume = tsc_resume,
@@ -1309,8 +1311,10 @@ struct system_counterval_t convert_art_to_tsc(u64 art)
do_div(tmp, art_to_tsc_denominator);
res += tmp + art_to_tsc_offset;
- return (struct system_counterval_t) {.cs = art_related_clocksource,
- .cycles = res};
+ return (struct system_counterval_t) {
+ .cs_id = have_art ? CSID_X86_TSC : CSID_GENERIC,
+ .cycles = res,
+ };
}
EXPORT_SYMBOL(convert_art_to_tsc);
@@ -1327,12 +1331,10 @@ EXPORT_SYMBOL(convert_art_to_tsc);
* that this flag is set before conversion to TSC is attempted.
*
* Return:
- * struct system_counterval_t - system counter value with the pointer to the
- * corresponding clocksource
- * @cycles: System counter value
- * @cs: Clocksource corresponding to system counter value. Used
- * by timekeeping code to verify comparability of two cycle
- * values.
+ * 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)
@@ -1347,8 +1349,10 @@ struct system_counterval_t convert_art_ns_to_tsc(u64 art_ns)
do_div(tmp, USEC_PER_SEC);
res += tmp;
- return (struct system_counterval_t) { .cs = art_related_clocksource,
- .cycles = res};
+ return (struct system_counterval_t) {
+ .cs_id = have_art ? CSID_X86_TSC : CSID_GENERIC,
+ .cycles = res,
+ };
}
EXPORT_SYMBOL(convert_art_ns_to_tsc);
@@ -1357,7 +1361,7 @@ static void tsc_refine_calibration_work(struct work_struct *work);
static DECLARE_DELAYED_WORK(tsc_irqwork, tsc_refine_calibration_work);
/**
* tsc_refine_calibration_work - Further refine tsc freq calibration
- * @work - ignored.
+ * @work: ignored.
*
* This functions uses delayed work over a period of a
* second to further refine the TSC freq value. Since this is
@@ -1455,7 +1459,7 @@ out:
goto unreg;
if (boot_cpu_has(X86_FEATURE_ART))
- art_related_clocksource = &clocksource_tsc;
+ have_art = true;
clocksource_register_khz(&clocksource_tsc, tsc_khz);
unreg:
clocksource_unregister(&clocksource_tsc_early);
@@ -1481,7 +1485,7 @@ static int __init init_tsc_clocksource(void)
*/
if (boot_cpu_has(X86_FEATURE_TSC_KNOWN_FREQ)) {
if (boot_cpu_has(X86_FEATURE_ART))
- art_related_clocksource = &clocksource_tsc;
+ have_art = true;
clocksource_register_khz(&clocksource_tsc, tsc_khz);
clocksource_unregister(&clocksource_tsc_early);
diff --git a/arch/x86/kernel/crash_core_32.c b/arch/x86/kernel/vmcore_info_32.c
index 8a89c109e20a..5995a749288a 100644
--- a/arch/x86/kernel/crash_core_32.c
+++ b/arch/x86/kernel/vmcore_info_32.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
-#include <linux/crash_core.h>
+#include <linux/vmcore_info.h>
#include <linux/pgtable.h>
#include <asm/setup.h>
diff --git a/arch/x86/kernel/crash_core_64.c b/arch/x86/kernel/vmcore_info_64.c
index 7d255f882afe..0dec7d868754 100644
--- a/arch/x86/kernel/crash_core_64.c
+++ b/arch/x86/kernel/vmcore_info_64.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
-#include <linux/crash_core.h>
+#include <linux/vmcore_info.h>
#include <linux/pgtable.h>
#include <asm/setup.h>
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index a349dbfc6d5a..56451fd2099e 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -46,6 +46,7 @@ ENTRY(phys_startup_64)
#endif
jiffies = jiffies_64;
+const_pcpu_hot = pcpu_hot;
#if defined(CONFIG_X86_64)
/*
@@ -132,7 +133,7 @@ SECTIONS
LOCK_TEXT
KPROBES_TEXT
SOFTIRQENTRY_TEXT
-#ifdef CONFIG_RETPOLINE
+#ifdef CONFIG_MITIGATION_RETPOLINE
*(.text..__x86.indirect_thunk)
*(.text..__x86.return_thunk)
#endif
@@ -142,7 +143,7 @@ SECTIONS
*(.text..__x86.rethunk_untrain)
ENTRY_TEXT
-#ifdef CONFIG_CPU_SRSO
+#ifdef CONFIG_MITIGATION_SRSO
/*
* See the comment above srso_alias_untrain_ret()'s
* definition.
@@ -267,7 +268,7 @@ SECTIONS
}
#endif
-#ifdef CONFIG_RETPOLINE
+#ifdef CONFIG_MITIGATION_RETPOLINE
/*
* List of instructions that call/jmp/jcc to retpoline thunks
* __x86_indirect_thunk_*(). These instructions can be patched along
@@ -504,11 +505,11 @@ INIT_PER_CPU(irq_stack_backing_store);
"fixed_percpu_data is not at start of per-cpu area");
#endif
-#ifdef CONFIG_CPU_UNRET_ENTRY
+#ifdef CONFIG_MITIGATION_UNRET_ENTRY
. = ASSERT((retbleed_return_thunk & 0x3f) == 0, "retbleed_return_thunk not cacheline-aligned");
#endif
-#ifdef CONFIG_CPU_SRSO
+#ifdef CONFIG_MITIGATION_SRSO
. = ASSERT((srso_safe_ret & 0x3f) == 0, "srso_safe_ret not cacheline-aligned");
/*
* GNU ld cannot do XOR until 2.41.
diff --git a/arch/x86/kernel/vsmp_64.c b/arch/x86/kernel/vsmp_64.c
index d3fc01770558..73511332bb67 100644
--- a/arch/x86/kernel/vsmp_64.c
+++ b/arch/x86/kernel/vsmp_64.c
@@ -127,25 +127,12 @@ static void __init vsmp_cap_cpus(void)
#endif
}
-static u32 apicid_phys_pkg_id(u32 initial_apic_id, int index_msb)
-{
- return read_apic_id() >> index_msb;
-}
-
-static void vsmp_apic_post_init(void)
-{
- /* need to update phys_pkg_id */
- apic->phys_pkg_id = apicid_phys_pkg_id;
-}
-
void __init vsmp_init(void)
{
detect_vsmp_box();
if (!is_vsmp_box())
return;
- x86_platform.apic_post_init = vsmp_apic_post_init;
-
vsmp_cap_cpus();
set_vsmp_ctl();
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index a37ebd3b4773..d5dc5a92635a 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -3,6 +3,7 @@
*
* For licencing details see kernel-base/COPYING
*/
+#include <linux/dmi.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/export.h>
@@ -66,12 +67,14 @@ struct x86_init_ops x86_init __initdata = {
.probe_roms = probe_roms,
.reserve_resources = reserve_standard_io_resources,
.memory_setup = e820__memory_setup_default,
+ .dmi_setup = dmi_setup,
},
.mpparse = {
.setup_ioapic_ids = x86_init_noop,
- .find_smp_config = default_find_smp_config,
- .get_smp_config = default_get_smp_config,
+ .find_mptable = mpparse_find_mptable,
+ .early_parse_smp_cfg = mpparse_parse_early_smp_config,
+ .parse_smp_cfg = mpparse_parse_smp_config,
},
.irqs = {
diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig
index 65ed14b6540b..0ebdd088f28b 100644
--- a/arch/x86/kvm/Kconfig
+++ b/arch/x86/kvm/Kconfig
@@ -7,7 +7,6 @@ source "virt/kvm/Kconfig"
menuconfig VIRTUALIZATION
bool "Virtualization"
- depends on HAVE_KVM || X86
default y
help
Say Y here to get to see options for using your Linux host to run other
@@ -20,7 +19,6 @@ if VIRTUALIZATION
config KVM
tristate "Kernel-based Virtual Machine (KVM) support"
- depends on HAVE_KVM
depends on HIGH_RES_TIMERS
depends on X86_LOCAL_APIC
select KVM_COMMON
@@ -29,9 +27,9 @@ config KVM
select HAVE_KVM_PFNCACHE
select HAVE_KVM_DIRTY_RING_TSO
select HAVE_KVM_DIRTY_RING_ACQ_REL
- select IRQ_BYPASS_MANAGER
select HAVE_KVM_IRQ_BYPASS
select HAVE_KVM_IRQ_ROUTING
+ select HAVE_KVM_READONLY_MEM
select KVM_ASYNC_PF
select USER_RETURN_NOTIFIER
select KVM_MMIO
@@ -120,10 +118,11 @@ config KVM_AMD
will be called kvm-amd.
config KVM_AMD_SEV
- def_bool y
bool "AMD Secure Encrypted Virtualization (SEV) support"
+ default y
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
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 475b5fa917a6..a88bb14266b6 100644
--- a/arch/x86/kvm/Makefile
+++ b/arch/x86/kvm/Makefile
@@ -4,7 +4,8 @@ ccflags-y += -I $(srctree)/arch/x86/kvm
ccflags-$(CONFIG_KVM_WERROR) += -Werror
ifeq ($(CONFIG_FRAME_POINTER),y)
-OBJECT_FILES_NON_STANDARD_vmenter.o := y
+OBJECT_FILES_NON_STANDARD_vmx/vmenter.o := y
+OBJECT_FILES_NON_STANDARD_svm/vmenter.o := y
endif
include $(srctree)/virt/kvm/Makefile.kvm
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index adba49afb5fe..bfc0bfcb2bc6 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -189,15 +189,15 @@ static int kvm_cpuid_check_equal(struct kvm_vcpu *vcpu, struct kvm_cpuid_entry2
return 0;
}
-static struct kvm_hypervisor_cpuid kvm_get_hypervisor_cpuid(struct kvm_vcpu *vcpu,
- const char *sig)
+static struct kvm_hypervisor_cpuid __kvm_get_hypervisor_cpuid(struct kvm_cpuid_entry2 *entries,
+ int nent, const char *sig)
{
struct kvm_hypervisor_cpuid cpuid = {};
struct kvm_cpuid_entry2 *entry;
u32 base;
for_each_possible_hypervisor_cpuid_base(base) {
- entry = kvm_find_cpuid_entry(vcpu, base);
+ entry = cpuid_entry2_find(entries, nent, base, KVM_CPUID_INDEX_NOT_SIGNIFICANT);
if (entry) {
u32 signature[3];
@@ -217,22 +217,29 @@ static struct kvm_hypervisor_cpuid kvm_get_hypervisor_cpuid(struct kvm_vcpu *vcp
return cpuid;
}
-static struct kvm_cpuid_entry2 *__kvm_find_kvm_cpuid_features(struct kvm_vcpu *vcpu,
- struct kvm_cpuid_entry2 *entries, int nent)
+static struct kvm_hypervisor_cpuid kvm_get_hypervisor_cpuid(struct kvm_vcpu *vcpu,
+ const char *sig)
{
- u32 base = vcpu->arch.kvm_cpuid.base;
-
- if (!base)
- return NULL;
+ return __kvm_get_hypervisor_cpuid(vcpu->arch.cpuid_entries,
+ vcpu->arch.cpuid_nent, sig);
+}
- return cpuid_entry2_find(entries, nent, base | KVM_CPUID_FEATURES,
+static struct kvm_cpuid_entry2 *__kvm_find_kvm_cpuid_features(struct kvm_cpuid_entry2 *entries,
+ int nent, u32 kvm_cpuid_base)
+{
+ return cpuid_entry2_find(entries, nent, kvm_cpuid_base | KVM_CPUID_FEATURES,
KVM_CPUID_INDEX_NOT_SIGNIFICANT);
}
static struct kvm_cpuid_entry2 *kvm_find_kvm_cpuid_features(struct kvm_vcpu *vcpu)
{
- return __kvm_find_kvm_cpuid_features(vcpu, vcpu->arch.cpuid_entries,
- vcpu->arch.cpuid_nent);
+ u32 base = vcpu->arch.kvm_cpuid.base;
+
+ if (!base)
+ return NULL;
+
+ return __kvm_find_kvm_cpuid_features(vcpu->arch.cpuid_entries,
+ vcpu->arch.cpuid_nent, base);
}
void kvm_update_pv_runtime(struct kvm_vcpu *vcpu)
@@ -266,6 +273,7 @@ static void __kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu, struct kvm_cpuid_e
int nent)
{
struct kvm_cpuid_entry2 *best;
+ struct kvm_hypervisor_cpuid kvm_cpuid;
best = cpuid_entry2_find(entries, nent, 1, KVM_CPUID_INDEX_NOT_SIGNIFICANT);
if (best) {
@@ -292,10 +300,12 @@ static void __kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu, struct kvm_cpuid_e
cpuid_entry_has(best, X86_FEATURE_XSAVEC)))
best->ebx = xstate_required_size(vcpu->arch.xcr0, true);
- best = __kvm_find_kvm_cpuid_features(vcpu, entries, nent);
- if (kvm_hlt_in_guest(vcpu->kvm) && best &&
- (best->eax & (1 << KVM_FEATURE_PV_UNHALT)))
- best->eax &= ~(1 << KVM_FEATURE_PV_UNHALT);
+ kvm_cpuid = __kvm_get_hypervisor_cpuid(entries, nent, KVM_SIGNATURE);
+ if (kvm_cpuid.base) {
+ best = __kvm_find_kvm_cpuid_features(entries, nent, kvm_cpuid.base);
+ if (kvm_hlt_in_guest(vcpu->kvm) && best)
+ best->eax &= ~(1 << KVM_FEATURE_PV_UNHALT);
+ }
if (!kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT)) {
best = cpuid_entry2_find(entries, nent, 0x1, KVM_CPUID_INDEX_NOT_SIGNIFICANT);
diff --git a/arch/x86/kvm/debugfs.c b/arch/x86/kvm/debugfs.c
index 95ea1a1f7403..999227fc7c66 100644
--- a/arch/x86/kvm/debugfs.c
+++ b/arch/x86/kvm/debugfs.c
@@ -189,9 +189,8 @@ static const struct file_operations mmu_rmaps_stat_fops = {
.release = kvm_mmu_rmaps_stat_release,
};
-int kvm_arch_create_vm_debugfs(struct kvm *kvm)
+void kvm_arch_create_vm_debugfs(struct kvm *kvm)
{
debugfs_create_file("mmu_rmaps_stat", 0644, kvm->debugfs_dentry, kvm,
&mmu_rmaps_stat_fops);
- return 0;
}
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index e223043ef5b2..5d4c86133453 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -1820,22 +1820,22 @@ static int writeback(struct x86_emulate_ctxt *ctxt, struct operand *op)
return X86EMUL_CONTINUE;
}
-static int push(struct x86_emulate_ctxt *ctxt, void *data, int bytes)
+static int emulate_push(struct x86_emulate_ctxt *ctxt, const void *data, int len)
{
struct segmented_address addr;
- rsp_increment(ctxt, -bytes);
+ rsp_increment(ctxt, -len);
addr.ea = reg_read(ctxt, VCPU_REGS_RSP) & stack_mask(ctxt);
addr.seg = VCPU_SREG_SS;
- return segmented_write(ctxt, addr, data, bytes);
+ return segmented_write(ctxt, addr, data, len);
}
static int em_push(struct x86_emulate_ctxt *ctxt)
{
/* Disable writeback. */
ctxt->dst.type = OP_NONE;
- return push(ctxt, &ctxt->src.val, ctxt->op_bytes);
+ return emulate_push(ctxt, &ctxt->src.val, ctxt->op_bytes);
}
static int emulate_pop(struct x86_emulate_ctxt *ctxt,
@@ -1863,7 +1863,8 @@ static int emulate_popf(struct x86_emulate_ctxt *ctxt,
void *dest, int len)
{
int rc;
- unsigned long val, change_mask;
+ unsigned long val = 0;
+ unsigned long change_mask;
int iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> X86_EFLAGS_IOPL_BIT;
int cpl = ctxt->ops->cpl(ctxt);
@@ -1920,7 +1921,7 @@ static int em_enter(struct x86_emulate_ctxt *ctxt)
return X86EMUL_UNHANDLEABLE;
rbp = reg_read(ctxt, VCPU_REGS_RBP);
- rc = push(ctxt, &rbp, stack_size(ctxt));
+ rc = emulate_push(ctxt, &rbp, stack_size(ctxt));
if (rc != X86EMUL_CONTINUE)
return rc;
assign_masked(reg_rmw(ctxt, VCPU_REGS_RBP), reg_read(ctxt, VCPU_REGS_RSP),
@@ -1954,7 +1955,7 @@ static int em_push_sreg(struct x86_emulate_ctxt *ctxt)
static int em_pop_sreg(struct x86_emulate_ctxt *ctxt)
{
int seg = ctxt->src2.val;
- unsigned long selector;
+ unsigned long selector = 0;
int rc;
rc = emulate_pop(ctxt, &selector, 2);
@@ -2000,7 +2001,7 @@ static int em_popa(struct x86_emulate_ctxt *ctxt)
{
int rc = X86EMUL_CONTINUE;
int reg = VCPU_REGS_RDI;
- u32 val;
+ u32 val = 0;
while (reg >= VCPU_REGS_RAX) {
if (reg == VCPU_REGS_RSP) {
@@ -2229,7 +2230,7 @@ static int em_cmpxchg8b(struct x86_emulate_ctxt *ctxt)
static int em_ret(struct x86_emulate_ctxt *ctxt)
{
int rc;
- unsigned long eip;
+ unsigned long eip = 0;
rc = emulate_pop(ctxt, &eip, ctxt->op_bytes);
if (rc != X86EMUL_CONTINUE)
@@ -2241,7 +2242,8 @@ static int em_ret(struct x86_emulate_ctxt *ctxt)
static int em_ret_far(struct x86_emulate_ctxt *ctxt)
{
int rc;
- unsigned long eip, cs;
+ unsigned long eip = 0;
+ unsigned long cs = 0;
int cpl = ctxt->ops->cpl(ctxt);
struct desc_struct new_desc;
@@ -3011,7 +3013,7 @@ static int emulator_do_task_switch(struct x86_emulate_ctxt *ctxt,
ret = em_push(ctxt);
}
- ops->get_dr(ctxt, 7, &dr7);
+ dr7 = ops->get_dr(ctxt, 7);
ops->set_dr(ctxt, 7, dr7 & ~(DR_LOCAL_ENABLE_MASK | DR_LOCAL_SLOWDOWN));
return ret;
@@ -3184,7 +3186,7 @@ fail:
static int em_ret_near_imm(struct x86_emulate_ctxt *ctxt)
{
int rc;
- unsigned long eip;
+ unsigned long eip = 0;
rc = emulate_pop(ctxt, &eip, ctxt->op_bytes);
if (rc != X86EMUL_CONTINUE)
@@ -3866,15 +3868,6 @@ static int check_cr_access(struct x86_emulate_ctxt *ctxt)
return X86EMUL_CONTINUE;
}
-static int check_dr7_gd(struct x86_emulate_ctxt *ctxt)
-{
- unsigned long dr7;
-
- ctxt->ops->get_dr(ctxt, 7, &dr7);
-
- return dr7 & DR7_GD;
-}
-
static int check_dr_read(struct x86_emulate_ctxt *ctxt)
{
int dr = ctxt->modrm_reg;
@@ -3887,10 +3880,10 @@ static int check_dr_read(struct x86_emulate_ctxt *ctxt)
if ((cr4 & X86_CR4_DE) && (dr == 4 || dr == 5))
return emulate_ud(ctxt);
- if (check_dr7_gd(ctxt)) {
+ if (ctxt->ops->get_dr(ctxt, 7) & DR7_GD) {
ulong dr6;
- ctxt->ops->get_dr(ctxt, 6, &dr6);
+ dr6 = ctxt->ops->get_dr(ctxt, 6);
dr6 &= ~DR_TRAP_BITS;
dr6 |= DR6_BD | DR6_ACTIVE_LOW;
ctxt->ops->set_dr(ctxt, 6, dr6);
@@ -3962,7 +3955,7 @@ static int check_rdpmc(struct x86_emulate_ctxt *ctxt)
* protected mode.
*/
if ((!(cr4 & X86_CR4_PCE) && ctxt->ops->cpl(ctxt)) ||
- ctxt->ops->check_pmc(ctxt, rcx))
+ ctxt->ops->check_rdpmc_early(ctxt, rcx))
return emulate_gp(ctxt, 0);
return X86EMUL_CONTINUE;
@@ -4505,11 +4498,11 @@ static const struct instr_dual instr_dual_0f_38_f1 = {
};
static const struct gprefix three_byte_0f_38_f0 = {
- ID(0, &instr_dual_0f_38_f0), N, N, N
+ ID(0, &instr_dual_0f_38_f0), ID(0, &instr_dual_0f_38_f0), N, N
};
static const struct gprefix three_byte_0f_38_f1 = {
- ID(0, &instr_dual_0f_38_f1), N, N, N
+ ID(0, &instr_dual_0f_38_f1), ID(0, &instr_dual_0f_38_f1), N, N
};
/*
@@ -5449,7 +5442,7 @@ twobyte_insn:
ctxt->dst.val = ops->get_cr(ctxt, ctxt->modrm_reg);
break;
case 0x21: /* mov from dr to reg */
- ops->get_dr(ctxt, ctxt->modrm_reg, &ctxt->dst.val);
+ ctxt->dst.val = ops->get_dr(ctxt, ctxt->modrm_reg);
break;
case 0x40 ... 0x4f: /* cmov */
if (test_cc(ctxt->b, ctxt->eflags))
diff --git a/arch/x86/kvm/kvm_emulate.h b/arch/x86/kvm/kvm_emulate.h
index e6d149825169..5382646162a3 100644
--- a/arch/x86/kvm/kvm_emulate.h
+++ b/arch/x86/kvm/kvm_emulate.h
@@ -203,12 +203,12 @@ struct x86_emulate_ops {
ulong (*get_cr)(struct x86_emulate_ctxt *ctxt, int cr);
int (*set_cr)(struct x86_emulate_ctxt *ctxt, int cr, ulong val);
int (*cpl)(struct x86_emulate_ctxt *ctxt);
- void (*get_dr)(struct x86_emulate_ctxt *ctxt, int dr, ulong *dest);
+ ulong (*get_dr)(struct x86_emulate_ctxt *ctxt, int dr);
int (*set_dr)(struct x86_emulate_ctxt *ctxt, int dr, ulong value);
int (*set_msr_with_filter)(struct x86_emulate_ctxt *ctxt, u32 msr_index, u64 data);
int (*get_msr_with_filter)(struct x86_emulate_ctxt *ctxt, u32 msr_index, u64 *pdata);
int (*get_msr)(struct x86_emulate_ctxt *ctxt, u32 msr_index, u64 *pdata);
- int (*check_pmc)(struct x86_emulate_ctxt *ctxt, u32 pmc);
+ int (*check_rdpmc_early)(struct x86_emulate_ctxt *ctxt, u32 pmc);
int (*read_pmc)(struct x86_emulate_ctxt *ctxt, u32 pmc, u64 *pdata);
void (*halt)(struct x86_emulate_ctxt *ctxt);
void (*wbinvd)(struct x86_emulate_ctxt *ctxt);
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 3242f3da2457..cf37586f0466 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -41,6 +41,7 @@
#include "ioapic.h"
#include "trace.h"
#include "x86.h"
+#include "xen.h"
#include "cpuid.h"
#include "hyperv.h"
#include "smm.h"
@@ -124,6 +125,9 @@ static inline int __apic_test_and_clear_vector(int vec, void *bitmap)
return __test_and_clear_bit(VEC_POS(vec), (bitmap) + REG_POS(vec));
}
+__read_mostly DEFINE_STATIC_KEY_FALSE(kvm_has_noapic_vcpu);
+EXPORT_SYMBOL_GPL(kvm_has_noapic_vcpu);
+
__read_mostly DEFINE_STATIC_KEY_DEFERRED_FALSE(apic_hw_disabled, HZ);
__read_mostly DEFINE_STATIC_KEY_DEFERRED_FALSE(apic_sw_disabled, HZ);
@@ -499,8 +503,10 @@ static inline void apic_set_spiv(struct kvm_lapic *apic, u32 val)
}
/* Check if there are APF page ready requests pending */
- if (enabled)
+ if (enabled) {
kvm_make_request(KVM_REQ_APF_READY, apic->vcpu);
+ kvm_xen_sw_enable_lapic(apic->vcpu);
+ }
}
static inline void kvm_apic_set_xapic_id(struct kvm_lapic *apic, u8 id)
@@ -2466,8 +2472,10 @@ void kvm_free_lapic(struct kvm_vcpu *vcpu)
{
struct kvm_lapic *apic = vcpu->arch.apic;
- if (!vcpu->arch.apic)
+ if (!vcpu->arch.apic) {
+ static_branch_dec(&kvm_has_noapic_vcpu);
return;
+ }
hrtimer_cancel(&apic->lapic_timer.timer);
@@ -2809,13 +2817,21 @@ int kvm_create_lapic(struct kvm_vcpu *vcpu, int timer_advance_ns)
ASSERT(vcpu != NULL);
+ if (!irqchip_in_kernel(vcpu->kvm)) {
+ static_branch_inc(&kvm_has_noapic_vcpu);
+ return 0;
+ }
+
apic = kzalloc(sizeof(*apic), GFP_KERNEL_ACCOUNT);
if (!apic)
goto nomem;
vcpu->arch.apic = apic;
- apic->regs = (void *)get_zeroed_page(GFP_KERNEL_ACCOUNT);
+ if (kvm_x86_ops.alloc_apic_backing_page)
+ apic->regs = static_call(kvm_x86_alloc_apic_backing_page)(vcpu);
+ else
+ apic->regs = (void *)get_zeroed_page(GFP_KERNEL_ACCOUNT);
if (!apic->regs) {
printk(KERN_ERR "malloc apic regs error for vcpu %x\n",
vcpu->vcpu_id);
@@ -2844,6 +2860,21 @@ int kvm_create_lapic(struct kvm_vcpu *vcpu, int timer_advance_ns)
static_branch_inc(&apic_sw_disabled.key); /* sw disabled at reset */
kvm_iodevice_init(&apic->dev, &apic_mmio_ops);
+ /*
+ * Defer evaluating inhibits until the vCPU is first run, as this vCPU
+ * will not get notified of any changes until this vCPU is visible to
+ * other vCPUs (marked online and added to the set of vCPUs).
+ *
+ * Opportunistically mark APICv active as VMX in particularly is highly
+ * unlikely to have inhibits. Ignore the current per-VM APICv state so
+ * that vCPU creation is guaranteed to run with a deterministic value,
+ * the request will ensure the vCPU gets the correct state before VM-Entry.
+ */
+ if (enable_apicv) {
+ apic->apicv_active = true;
+ kvm_make_request(KVM_REQ_APICV_UPDATE, vcpu);
+ }
+
return 0;
nomem_free_apic:
kfree(apic);
diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index 0544700ca50b..992e651540e8 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -47,18 +47,18 @@
#include <linux/kern_levels.h>
#include <linux/kstrtox.h>
#include <linux/kthread.h>
+#include <linux/wordpart.h>
#include <asm/page.h>
#include <asm/memtype.h>
#include <asm/cmpxchg.h>
#include <asm/io.h>
#include <asm/set_memory.h>
+#include <asm/spec-ctrl.h>
#include <asm/vmx.h>
#include "trace.h"
-extern bool itlb_multihit_kvm_mitigation;
-
static bool nx_hugepage_mitigation_hard_disabled;
int __read_mostly nx_huge_pages = -1;
@@ -263,7 +263,7 @@ static unsigned long get_guest_cr3(struct kvm_vcpu *vcpu)
static inline unsigned long kvm_mmu_get_guest_pgd(struct kvm_vcpu *vcpu,
struct kvm_mmu *mmu)
{
- if (IS_ENABLED(CONFIG_RETPOLINE) && mmu->get_guest_pgd == get_guest_cr3)
+ if (IS_ENABLED(CONFIG_MITIGATION_RETPOLINE) && mmu->get_guest_pgd == get_guest_cr3)
return kvm_read_cr3(vcpu);
return mmu->get_guest_pgd(vcpu);
@@ -3110,7 +3110,7 @@ static int host_pfn_mapping_level(struct kvm *kvm, gfn_t gfn,
/*
* Read each entry once. As above, a non-leaf entry can be promoted to
* a huge page _during_ this walk. Re-reading the entry could send the
- * walk into the weeks, e.g. p*d_large() returns false (sees the old
+ * walk into the weeks, e.g. p*d_leaf() returns false (sees the old
* value) and then p*d_offset() walks into the target huge page instead
* of the old page table (sees the new value).
*/
@@ -3126,7 +3126,7 @@ static int host_pfn_mapping_level(struct kvm *kvm, gfn_t gfn,
if (pud_none(pud) || !pud_present(pud))
goto out;
- if (pud_large(pud)) {
+ if (pud_leaf(pud)) {
level = PG_LEVEL_1G;
goto out;
}
@@ -3135,7 +3135,7 @@ static int host_pfn_mapping_level(struct kvm *kvm, gfn_t gfn,
if (pmd_none(pmd) || !pmd_present(pmd))
goto out;
- if (pmd_large(pmd))
+ if (pmd_leaf(pmd))
level = PG_LEVEL_2M;
out:
@@ -3575,10 +3575,14 @@ static void mmu_free_root_page(struct kvm *kvm, hpa_t *root_hpa,
if (WARN_ON_ONCE(!sp))
return;
- if (is_tdp_mmu_page(sp))
+ if (is_tdp_mmu_page(sp)) {
+ lockdep_assert_held_read(&kvm->mmu_lock);
kvm_tdp_mmu_put_root(kvm, sp);
- else if (!--sp->root_count && sp->role.invalid)
- kvm_mmu_prepare_zap_page(kvm, sp, invalid_list);
+ } else {
+ lockdep_assert_held_write(&kvm->mmu_lock);
+ if (!--sp->root_count && sp->role.invalid)
+ kvm_mmu_prepare_zap_page(kvm, sp, invalid_list);
+ }
*root_hpa = INVALID_PAGE;
}
@@ -3587,6 +3591,7 @@ static void mmu_free_root_page(struct kvm *kvm, hpa_t *root_hpa,
void kvm_mmu_free_roots(struct kvm *kvm, struct kvm_mmu *mmu,
ulong roots_to_free)
{
+ bool is_tdp_mmu = tdp_mmu_enabled && mmu->root_role.direct;
int i;
LIST_HEAD(invalid_list);
bool free_active_root;
@@ -3609,7 +3614,10 @@ void kvm_mmu_free_roots(struct kvm *kvm, struct kvm_mmu *mmu,
return;
}
- write_lock(&kvm->mmu_lock);
+ if (is_tdp_mmu)
+ read_lock(&kvm->mmu_lock);
+ else
+ write_lock(&kvm->mmu_lock);
for (i = 0; i < KVM_MMU_NUM_PREV_ROOTS; i++)
if (roots_to_free & KVM_MMU_ROOT_PREVIOUS(i))
@@ -3635,8 +3643,13 @@ void kvm_mmu_free_roots(struct kvm *kvm, struct kvm_mmu *mmu,
mmu->root.pgd = 0;
}
- kvm_mmu_commit_zap_page(kvm, &invalid_list);
- write_unlock(&kvm->mmu_lock);
+ if (is_tdp_mmu) {
+ read_unlock(&kvm->mmu_lock);
+ WARN_ON_ONCE(!list_empty(&invalid_list));
+ } else {
+ kvm_mmu_commit_zap_page(kvm, &invalid_list);
+ write_unlock(&kvm->mmu_lock);
+ }
}
EXPORT_SYMBOL_GPL(kvm_mmu_free_roots);
@@ -3693,15 +3706,15 @@ static int mmu_alloc_direct_roots(struct kvm_vcpu *vcpu)
unsigned i;
int r;
+ if (tdp_mmu_enabled)
+ return kvm_tdp_mmu_alloc_root(vcpu);
+
write_lock(&vcpu->kvm->mmu_lock);
r = make_mmu_pages_available(vcpu);
if (r < 0)
goto out_unlock;
- if (tdp_mmu_enabled) {
- root = kvm_tdp_mmu_get_vcpu_root_hpa(vcpu);
- mmu->root.hpa = root;
- } else if (shadow_root_level >= PT64_ROOT_4LEVEL) {
+ if (shadow_root_level >= PT64_ROOT_4LEVEL) {
root = mmu_alloc_root(vcpu, 0, 0, shadow_root_level);
mmu->root.hpa = root;
} else if (shadow_root_level == PT32E_ROOT_LEVEL) {
@@ -7039,9 +7052,7 @@ int kvm_mmu_vendor_module_init(void)
kvm_mmu_reset_all_pte_masks();
- pte_list_desc_cache = kmem_cache_create("pte_list_desc",
- sizeof(struct pte_list_desc),
- 0, SLAB_ACCOUNT, NULL);
+ pte_list_desc_cache = KMEM_CACHE(pte_list_desc, SLAB_ACCOUNT);
if (!pte_list_desc_cache)
goto out;
diff --git a/arch/x86/kvm/mmu/mmu_internal.h b/arch/x86/kvm/mmu/mmu_internal.h
index 0669a8a668ca..5390a591a571 100644
--- a/arch/x86/kvm/mmu/mmu_internal.h
+++ b/arch/x86/kvm/mmu/mmu_internal.h
@@ -315,7 +315,7 @@ static inline int kvm_mmu_do_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
if (!prefetch)
vcpu->stat.pf_taken++;
- if (IS_ENABLED(CONFIG_RETPOLINE) && fault.is_tdp)
+ 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);
diff --git a/arch/x86/kvm/mmu/page_track.c b/arch/x86/kvm/mmu/page_track.c
index c87da11f3a04..f6448284c18e 100644
--- a/arch/x86/kvm/mmu/page_track.c
+++ b/arch/x86/kvm/mmu/page_track.c
@@ -20,10 +20,23 @@
#include "mmu_internal.h"
#include "page_track.h"
+static bool kvm_external_write_tracking_enabled(struct kvm *kvm)
+{
+#ifdef CONFIG_KVM_EXTERNAL_WRITE_TRACKING
+ /*
+ * Read external_write_tracking_enabled before related pointers. Pairs
+ * with the smp_store_release in kvm_page_track_write_tracking_enable().
+ */
+ return smp_load_acquire(&kvm->arch.external_write_tracking_enabled);
+#else
+ return false;
+#endif
+}
+
bool kvm_page_track_write_tracking_enabled(struct kvm *kvm)
{
- return IS_ENABLED(CONFIG_KVM_EXTERNAL_WRITE_TRACKING) ||
- !tdp_enabled || kvm_shadow_root_allocated(kvm);
+ return kvm_external_write_tracking_enabled(kvm) ||
+ kvm_shadow_root_allocated(kvm) || !tdp_enabled;
}
void kvm_page_track_free_memslot(struct kvm_memory_slot *slot)
@@ -153,6 +166,50 @@ int kvm_page_track_init(struct kvm *kvm)
return init_srcu_struct(&head->track_srcu);
}
+static int kvm_enable_external_write_tracking(struct kvm *kvm)
+{
+ struct kvm_memslots *slots;
+ struct kvm_memory_slot *slot;
+ int r = 0, i, bkt;
+
+ mutex_lock(&kvm->slots_arch_lock);
+
+ /*
+ * Check for *any* write tracking user (not just external users) under
+ * lock. This avoids unnecessary work, e.g. if KVM itself is using
+ * write tracking, or if two external users raced when registering.
+ */
+ if (kvm_page_track_write_tracking_enabled(kvm))
+ goto out_success;
+
+ for (i = 0; i < kvm_arch_nr_memslot_as_ids(kvm); i++) {
+ slots = __kvm_memslots(kvm, i);
+ kvm_for_each_memslot(slot, bkt, slots) {
+ /*
+ * Intentionally do NOT free allocations on failure to
+ * avoid having to track which allocations were made
+ * now versus when the memslot was created. The
+ * metadata is guaranteed to be freed when the slot is
+ * freed, and will be kept/used if userspace retries
+ * the failed ioctl() instead of killing the VM.
+ */
+ r = kvm_page_track_write_tracking_alloc(slot);
+ if (r)
+ goto out_unlock;
+ }
+ }
+
+out_success:
+ /*
+ * Ensure that external_write_tracking_enabled becomes true strictly
+ * after all the related pointers are set.
+ */
+ smp_store_release(&kvm->arch.external_write_tracking_enabled, true);
+out_unlock:
+ mutex_unlock(&kvm->slots_arch_lock);
+ return r;
+}
+
/*
* register the notifier so that event interception for the tracked guest
* pages can be received.
@@ -161,10 +218,17 @@ int kvm_page_track_register_notifier(struct kvm *kvm,
struct kvm_page_track_notifier_node *n)
{
struct kvm_page_track_notifier_head *head;
+ int r;
if (!kvm || kvm->mm != current->mm)
return -ESRCH;
+ if (!kvm_external_write_tracking_enabled(kvm)) {
+ r = kvm_enable_external_write_tracking(kvm);
+ if (r)
+ return r;
+ }
+
kvm_get_kvm(kvm);
head = &kvm->arch.track_notifier_head;
diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c
index 6ae19b4ee5b1..d078157e62aa 100644
--- a/arch/x86/kvm/mmu/tdp_mmu.c
+++ b/arch/x86/kvm/mmu/tdp_mmu.c
@@ -149,11 +149,11 @@ static struct kvm_mmu_page *tdp_mmu_next_root(struct kvm *kvm,
* If shared is set, this function is operating under the MMU lock in read
* mode.
*/
-#define __for_each_tdp_mmu_root_yield_safe(_kvm, _root, _as_id, _only_valid)\
- for (_root = tdp_mmu_next_root(_kvm, NULL, _only_valid); \
- ({ lockdep_assert_held(&(_kvm)->mmu_lock); }), _root; \
- _root = tdp_mmu_next_root(_kvm, _root, _only_valid)) \
- if (kvm_mmu_page_as_id(_root) != _as_id) { \
+#define __for_each_tdp_mmu_root_yield_safe(_kvm, _root, _as_id, _only_valid) \
+ for (_root = tdp_mmu_next_root(_kvm, NULL, _only_valid); \
+ ({ lockdep_assert_held(&(_kvm)->mmu_lock); }), _root; \
+ _root = tdp_mmu_next_root(_kvm, _root, _only_valid)) \
+ if (_as_id >= 0 && kvm_mmu_page_as_id(_root) != _as_id) { \
} else
#define for_each_valid_tdp_mmu_root_yield_safe(_kvm, _root, _as_id) \
@@ -171,12 +171,19 @@ static struct kvm_mmu_page *tdp_mmu_next_root(struct kvm *kvm,
* Holding mmu_lock for write obviates the need for RCU protection as the list
* is guaranteed to be stable.
*/
-#define for_each_tdp_mmu_root(_kvm, _root, _as_id) \
- list_for_each_entry(_root, &_kvm->arch.tdp_mmu_roots, link) \
- if (kvm_lockdep_assert_mmu_lock_held(_kvm, false) && \
- kvm_mmu_page_as_id(_root) != _as_id) { \
+#define __for_each_tdp_mmu_root(_kvm, _root, _as_id, _only_valid) \
+ list_for_each_entry(_root, &_kvm->arch.tdp_mmu_roots, link) \
+ if (kvm_lockdep_assert_mmu_lock_held(_kvm, false) && \
+ ((_as_id >= 0 && kvm_mmu_page_as_id(_root) != _as_id) || \
+ ((_only_valid) && (_root)->role.invalid))) { \
} else
+#define for_each_tdp_mmu_root(_kvm, _root, _as_id) \
+ __for_each_tdp_mmu_root(_kvm, _root, _as_id, false)
+
+#define for_each_valid_tdp_mmu_root(_kvm, _root, _as_id) \
+ __for_each_tdp_mmu_root(_kvm, _root, _as_id, true)
+
static struct kvm_mmu_page *tdp_mmu_alloc_sp(struct kvm_vcpu *vcpu)
{
struct kvm_mmu_page *sp;
@@ -216,22 +223,41 @@ static void tdp_mmu_init_child_sp(struct kvm_mmu_page *child_sp,
tdp_mmu_init_sp(child_sp, iter->sptep, iter->gfn, role);
}
-hpa_t kvm_tdp_mmu_get_vcpu_root_hpa(struct kvm_vcpu *vcpu)
+int kvm_tdp_mmu_alloc_root(struct kvm_vcpu *vcpu)
{
- union kvm_mmu_page_role role = vcpu->arch.mmu->root_role;
+ struct kvm_mmu *mmu = vcpu->arch.mmu;
+ union kvm_mmu_page_role role = mmu->root_role;
+ int as_id = kvm_mmu_role_as_id(role);
struct kvm *kvm = vcpu->kvm;
struct kvm_mmu_page *root;
- lockdep_assert_held_write(&kvm->mmu_lock);
+ /*
+ * Check for an existing root before acquiring the pages lock to avoid
+ * unnecessary serialization if multiple vCPUs are loading a new root.
+ * E.g. when bringing up secondary vCPUs, KVM will already have created
+ * a valid root on behalf of the primary vCPU.
+ */
+ read_lock(&kvm->mmu_lock);
+
+ for_each_valid_tdp_mmu_root_yield_safe(kvm, root, as_id) {
+ if (root->role.word == role.word)
+ goto out_read_unlock;
+ }
+
+ spin_lock(&kvm->arch.tdp_mmu_pages_lock);
/*
- * Check for an existing root before allocating a new one. Note, the
- * role check prevents consuming an invalid root.
+ * Recheck for an existing root after acquiring the pages lock, another
+ * vCPU may have raced ahead and created a new usable root. Manually
+ * walk the list of roots as the standard macros assume that the pages
+ * lock is *not* held. WARN if grabbing a reference to a usable root
+ * fails, as the last reference to a root can only be put *after* the
+ * root has been invalidated, which requires holding mmu_lock for write.
*/
- for_each_tdp_mmu_root(kvm, root, kvm_mmu_role_as_id(role)) {
+ list_for_each_entry(root, &kvm->arch.tdp_mmu_roots, link) {
if (root->role.word == role.word &&
- kvm_tdp_mmu_get_root(root))
- goto out;
+ !WARN_ON_ONCE(!kvm_tdp_mmu_get_root(root)))
+ goto out_spin_unlock;
}
root = tdp_mmu_alloc_sp(vcpu);
@@ -245,13 +271,20 @@ hpa_t kvm_tdp_mmu_get_vcpu_root_hpa(struct kvm_vcpu *vcpu)
* is ultimately put by kvm_tdp_mmu_zap_invalidated_roots().
*/
refcount_set(&root->tdp_mmu_root_count, 2);
-
- spin_lock(&kvm->arch.tdp_mmu_pages_lock);
list_add_rcu(&root->link, &kvm->arch.tdp_mmu_roots);
- spin_unlock(&kvm->arch.tdp_mmu_pages_lock);
-out:
- return __pa(root->spt);
+out_spin_unlock:
+ spin_unlock(&kvm->arch.tdp_mmu_pages_lock);
+out_read_unlock:
+ read_unlock(&kvm->mmu_lock);
+ /*
+ * Note, KVM_REQ_MMU_FREE_OBSOLETE_ROOTS will prevent entering the guest
+ * and actually consuming the root if it's invalidated after dropping
+ * mmu_lock, and the root can't be freed as this vCPU holds a reference.
+ */
+ mmu->root.hpa = __pa(root->spt);
+ mmu->root.pgd = 0;
+ return 0;
}
static void handle_changed_spte(struct kvm *kvm, int as_id, gfn_t gfn,
@@ -734,15 +767,26 @@ static void tdp_mmu_zap_root(struct kvm *kvm, struct kvm_mmu_page *root,
rcu_read_lock();
/*
- * To avoid RCU stalls due to recursively removing huge swaths of SPs,
- * split the zap into two passes. On the first pass, zap at the 1gb
- * level, and then zap top-level SPs on the second pass. "1gb" is not
- * arbitrary, as KVM must be able to zap a 1gb shadow page without
- * inducing a stall to allow in-place replacement with a 1gb hugepage.
+ * Zap roots in multiple passes of decreasing granularity, i.e. zap at
+ * 4KiB=>2MiB=>1GiB=>root, in order to better honor need_resched() (all
+ * preempt models) or mmu_lock contention (full or real-time models).
+ * Zapping at finer granularity marginally increases the total time of
+ * the zap, but in most cases the zap itself isn't latency sensitive.
*
- * Because zapping a SP recurses on its children, stepping down to
- * PG_LEVEL_4K in the iterator itself is unnecessary.
+ * If KVM is configured to prove the MMU, skip the 4KiB and 2MiB zaps
+ * in order to mimic the page fault path, which can replace a 1GiB page
+ * table with an equivalent 1GiB hugepage, i.e. can get saddled with
+ * zapping a 1GiB region that's fully populated with 4KiB SPTEs. This
+ * allows verifying that KVM can safely zap 1GiB regions, e.g. without
+ * inducing RCU stalls, without relying on a relatively rare event
+ * (zapping roots is orders of magnitude more common). Note, because
+ * zapping a SP recurses on its children, stepping down to PG_LEVEL_4K
+ * in the iterator itself is unnecessary.
*/
+ if (!IS_ENABLED(CONFIG_KVM_PROVE_MMU)) {
+ __tdp_mmu_zap_root(kvm, root, shared, PG_LEVEL_4K);
+ __tdp_mmu_zap_root(kvm, root, shared, PG_LEVEL_2M);
+ }
__tdp_mmu_zap_root(kvm, root, shared, PG_LEVEL_1G);
__tdp_mmu_zap_root(kvm, root, shared, root->role.level);
@@ -800,7 +844,13 @@ static bool tdp_mmu_zap_leafs(struct kvm *kvm, struct kvm_mmu_page *root,
continue;
tdp_mmu_iter_set_spte(kvm, &iter, 0);
- flush = true;
+
+ /*
+ * Zappings SPTEs in invalid roots doesn't require a TLB flush,
+ * see kvm_tdp_mmu_zap_invalidated_roots() for details.
+ */
+ if (!root->role.invalid)
+ flush = true;
}
rcu_read_unlock();
@@ -813,16 +863,16 @@ static bool tdp_mmu_zap_leafs(struct kvm *kvm, struct kvm_mmu_page *root,
}
/*
- * Zap leaf SPTEs for the range of gfns, [start, end), for all roots. Returns
- * true if a TLB flush is needed before releasing the MMU lock, i.e. if one or
- * more SPTEs were zapped since the MMU lock was last acquired.
+ * Zap leaf SPTEs for the range of gfns, [start, end), for all *VALID** roots.
+ * Returns true if a TLB flush is needed before releasing the MMU lock, i.e. if
+ * one or more SPTEs were zapped since the MMU lock was last acquired.
*/
bool kvm_tdp_mmu_zap_leafs(struct kvm *kvm, gfn_t start, gfn_t end, bool flush)
{
struct kvm_mmu_page *root;
lockdep_assert_held_write(&kvm->mmu_lock);
- for_each_tdp_mmu_root_yield_safe(kvm, root)
+ for_each_valid_tdp_mmu_root_yield_safe(kvm, root, -1)
flush = tdp_mmu_zap_leafs(kvm, root, start, end, true, flush);
return flush;
@@ -896,7 +946,7 @@ void kvm_tdp_mmu_zap_invalidated_roots(struct kvm *kvm)
* the VM is being destroyed).
*
* Note, kvm_tdp_mmu_zap_invalidated_roots() is gifted the TDP MMU's reference.
- * See kvm_tdp_mmu_get_vcpu_root_hpa().
+ * See kvm_tdp_mmu_alloc_root().
*/
void kvm_tdp_mmu_invalidate_all_roots(struct kvm *kvm)
{
@@ -1622,7 +1672,7 @@ void kvm_tdp_mmu_clear_dirty_pt_masked(struct kvm *kvm,
{
struct kvm_mmu_page *root;
- for_each_tdp_mmu_root(kvm, root, slot->as_id)
+ for_each_valid_tdp_mmu_root(kvm, root, slot->as_id)
clear_dirty_pt_masked(kvm, root, gfn, mask, wrprot);
}
@@ -1740,7 +1790,7 @@ bool kvm_tdp_mmu_write_protect_gfn(struct kvm *kvm,
bool spte_set = false;
lockdep_assert_held_write(&kvm->mmu_lock);
- for_each_tdp_mmu_root(kvm, root, slot->as_id)
+ for_each_valid_tdp_mmu_root(kvm, root, slot->as_id)
spte_set |= write_protect_gfn(kvm, root, gfn, min_level);
return spte_set;
diff --git a/arch/x86/kvm/mmu/tdp_mmu.h b/arch/x86/kvm/mmu/tdp_mmu.h
index 20d97aa46c49..6e1ea04ca885 100644
--- a/arch/x86/kvm/mmu/tdp_mmu.h
+++ b/arch/x86/kvm/mmu/tdp_mmu.h
@@ -10,7 +10,7 @@
void kvm_mmu_init_tdp_mmu(struct kvm *kvm);
void kvm_mmu_uninit_tdp_mmu(struct kvm *kvm);
-hpa_t kvm_tdp_mmu_get_vcpu_root_hpa(struct kvm_vcpu *vcpu);
+int kvm_tdp_mmu_alloc_root(struct kvm_vcpu *vcpu);
__must_check static inline bool kvm_tdp_mmu_get_root(struct kvm_mmu_page *root)
{
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index 87cc6c8809ad..c397b28e3d1b 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -29,6 +29,9 @@
struct x86_pmu_capability __read_mostly kvm_pmu_cap;
EXPORT_SYMBOL_GPL(kvm_pmu_cap);
+struct kvm_pmu_emulated_event_selectors __read_mostly kvm_pmu_eventsel;
+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),
@@ -67,7 +70,7 @@ static const struct x86_cpu_id vmx_pebs_pdist_cpu[] = {
* 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_PMC_IDX_FIXED .. INTEL_PMC_IDX_FIXED + 2] <=> fixed
+ * [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
*/
@@ -411,7 +414,7 @@ static bool is_gp_event_allowed(struct kvm_x86_pmu_event_filter *f,
static bool is_fixed_event_allowed(struct kvm_x86_pmu_event_filter *filter,
int idx)
{
- int fixed_idx = idx - INTEL_PMC_IDX_FIXED;
+ int fixed_idx = idx - KVM_FIXED_PMC_BASE_IDX;
if (filter->action == KVM_PMU_EVENT_DENY &&
test_bit(fixed_idx, (ulong *)&filter->fixed_counter_bitmap))
@@ -441,11 +444,10 @@ static bool check_pmu_event_filter(struct kvm_pmc *pmc)
static bool pmc_event_is_allowed(struct kvm_pmc *pmc)
{
return pmc_is_globally_enabled(pmc) && pmc_speculative_in_use(pmc) &&
- static_call(kvm_x86_pmu_hw_event_available)(pmc) &&
check_pmu_event_filter(pmc);
}
-static void reprogram_counter(struct kvm_pmc *pmc)
+static int reprogram_counter(struct kvm_pmc *pmc)
{
struct kvm_pmu *pmu = pmc_to_pmu(pmc);
u64 eventsel = pmc->eventsel;
@@ -456,7 +458,7 @@ static void reprogram_counter(struct kvm_pmc *pmc)
emulate_overflow = pmc_pause_counter(pmc);
if (!pmc_event_is_allowed(pmc))
- goto reprogram_complete;
+ return 0;
if (emulate_overflow)
__kvm_perf_overflow(pmc, false);
@@ -466,7 +468,7 @@ static void reprogram_counter(struct kvm_pmc *pmc)
if (pmc_is_fixed(pmc)) {
fixed_ctr_ctrl = fixed_ctrl_field(pmu->fixed_ctr_ctrl,
- pmc->idx - INTEL_PMC_IDX_FIXED);
+ pmc->idx - KVM_FIXED_PMC_BASE_IDX);
if (fixed_ctr_ctrl & 0x1)
eventsel |= ARCH_PERFMON_EVENTSEL_OS;
if (fixed_ctr_ctrl & 0x2)
@@ -477,43 +479,45 @@ static void reprogram_counter(struct kvm_pmc *pmc)
}
if (pmc->current_config == new_config && pmc_resume_counter(pmc))
- goto reprogram_complete;
+ return 0;
pmc_release_perf_event(pmc);
pmc->current_config = new_config;
- /*
- * If reprogramming fails, e.g. due to contention, leave the counter's
- * regprogram bit set, i.e. opportunistically try again on the next PMU
- * refresh. Don't make a new request as doing so can stall the guest
- * if reprogramming repeatedly fails.
- */
- if (pmc_reprogram_counter(pmc, PERF_TYPE_RAW,
- (eventsel & pmu->raw_event_mask),
- !(eventsel & ARCH_PERFMON_EVENTSEL_USR),
- !(eventsel & ARCH_PERFMON_EVENTSEL_OS),
- eventsel & ARCH_PERFMON_EVENTSEL_INT))
- return;
-
-reprogram_complete:
- clear_bit(pmc->idx, (unsigned long *)&pmc_to_pmu(pmc)->reprogram_pmi);
+ return pmc_reprogram_counter(pmc, PERF_TYPE_RAW,
+ (eventsel & pmu->raw_event_mask),
+ !(eventsel & ARCH_PERFMON_EVENTSEL_USR),
+ !(eventsel & ARCH_PERFMON_EVENTSEL_OS),
+ eventsel & ARCH_PERFMON_EVENTSEL_INT);
}
void kvm_pmu_handle_event(struct kvm_vcpu *vcpu)
{
+ DECLARE_BITMAP(bitmap, X86_PMC_IDX_MAX);
struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
+ struct kvm_pmc *pmc;
int bit;
- for_each_set_bit(bit, pmu->reprogram_pmi, X86_PMC_IDX_MAX) {
- struct kvm_pmc *pmc = static_call(kvm_x86_pmu_pmc_idx_to_pmc)(pmu, bit);
+ bitmap_copy(bitmap, pmu->reprogram_pmi, X86_PMC_IDX_MAX);
- if (unlikely(!pmc)) {
- clear_bit(bit, pmu->reprogram_pmi);
- continue;
- }
+ /*
+ * The reprogramming bitmap can be written asynchronously by something
+ * other than the task that holds vcpu->mutex, take care to clear only
+ * the bits that will actually processed.
+ */
+ BUILD_BUG_ON(sizeof(bitmap) != sizeof(atomic64_t));
+ atomic64_andnot(*(s64 *)bitmap, &pmu->__reprogram_pmi);
- reprogram_counter(pmc);
+ kvm_for_each_pmc(pmu, pmc, bit, bitmap) {
+ /*
+ * If reprogramming fails, e.g. due to contention, re-set the
+ * regprogram bit set, i.e. opportunistically try again on the
+ * next PMU refresh. Don't make a new request as doing so can
+ * stall the guest if reprogramming repeatedly fails.
+ */
+ if (reprogram_counter(pmc))
+ set_bit(pmc->idx, pmu->reprogram_pmi);
}
/*
@@ -525,10 +529,20 @@ void kvm_pmu_handle_event(struct kvm_vcpu *vcpu)
kvm_pmu_cleanup(vcpu);
}
-/* check if idx is a valid index to access PMU */
-bool kvm_pmu_is_valid_rdpmc_ecx(struct kvm_vcpu *vcpu, unsigned int idx)
+int kvm_pmu_check_rdpmc_early(struct kvm_vcpu *vcpu, unsigned int idx)
{
- return static_call(kvm_x86_pmu_is_valid_rdpmc_ecx)(vcpu, idx);
+ /*
+ * On Intel, VMX interception has priority over RDPMC exceptions that
+ * aren't already handled by the emulator, i.e. there are no additional
+ * check needed for Intel PMUs.
+ *
+ * On AMD, _all_ exceptions on RDPMC have priority over SVM intercepts,
+ * i.e. an invalid PMC results in a #GP, not #VMEXIT.
+ */
+ if (!kvm_pmu_ops.check_rdpmc_early)
+ return 0;
+
+ return static_call(kvm_x86_pmu_check_rdpmc_early)(vcpu, idx);
}
bool is_vmware_backdoor_pmc(u32 pmc_idx)
@@ -567,10 +581,9 @@ static int kvm_pmu_rdpmc_vmware(struct kvm_vcpu *vcpu, unsigned idx, u64 *data)
int kvm_pmu_rdpmc(struct kvm_vcpu *vcpu, unsigned idx, u64 *data)
{
- bool fast_mode = idx & (1u << 31);
struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
struct kvm_pmc *pmc;
- u64 mask = fast_mode ? ~0u : ~0ull;
+ u64 mask = ~0ull;
if (!pmu->version)
return 1;
@@ -716,11 +729,7 @@ static void kvm_pmu_reset(struct kvm_vcpu *vcpu)
bitmap_zero(pmu->reprogram_pmi, X86_PMC_IDX_MAX);
- for_each_set_bit(i, pmu->all_valid_pmc_idx, X86_PMC_IDX_MAX) {
- pmc = static_call(kvm_x86_pmu_pmc_idx_to_pmc)(pmu, i);
- if (!pmc)
- continue;
-
+ kvm_for_each_pmc(pmu, pmc, i, pmu->all_valid_pmc_idx) {
pmc_stop_counter(pmc);
pmc->counter = 0;
pmc->emulated_counter = 0;
@@ -741,6 +750,8 @@ static void kvm_pmu_reset(struct kvm_vcpu *vcpu)
*/
void kvm_pmu_refresh(struct kvm_vcpu *vcpu)
{
+ struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
+
if (KVM_BUG_ON(kvm_vcpu_has_run(vcpu), vcpu->kvm))
return;
@@ -750,8 +761,22 @@ void kvm_pmu_refresh(struct kvm_vcpu *vcpu)
*/
kvm_pmu_reset(vcpu);
- bitmap_zero(vcpu_to_pmu(vcpu)->all_valid_pmc_idx, X86_PMC_IDX_MAX);
- static_call(kvm_x86_pmu_refresh)(vcpu);
+ pmu->version = 0;
+ pmu->nr_arch_gp_counters = 0;
+ pmu->nr_arch_fixed_counters = 0;
+ pmu->counter_bitmask[KVM_PMC_GP] = 0;
+ 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;
+ bitmap_zero(pmu->all_valid_pmc_idx, X86_PMC_IDX_MAX);
+
+ if (vcpu->kvm->arch.enable_pmu)
+ static_call(kvm_x86_pmu_refresh)(vcpu);
}
void kvm_pmu_init(struct kvm_vcpu *vcpu)
@@ -776,10 +801,8 @@ void kvm_pmu_cleanup(struct kvm_vcpu *vcpu)
bitmap_andnot(bitmask, pmu->all_valid_pmc_idx,
pmu->pmc_in_use, X86_PMC_IDX_MAX);
- for_each_set_bit(i, bitmask, X86_PMC_IDX_MAX) {
- pmc = static_call(kvm_x86_pmu_pmc_idx_to_pmc)(pmu, i);
-
- if (pmc && pmc->perf_event && !pmc_speculative_in_use(pmc))
+ kvm_for_each_pmc(pmu, pmc, i, bitmask) {
+ if (pmc->perf_event && !pmc_speculative_in_use(pmc))
pmc_stop_counter(pmc);
}
@@ -799,13 +822,6 @@ static void kvm_pmu_incr_counter(struct kvm_pmc *pmc)
kvm_pmu_request_counter_reprogram(pmc);
}
-static inline bool eventsel_match_perf_hw_id(struct kvm_pmc *pmc,
- unsigned int perf_hw_id)
-{
- return !((pmc->eventsel ^ perf_get_hw_event_config(perf_hw_id)) &
- AMD64_RAW_EVENT_MASK_NB);
-}
-
static inline bool cpl_is_matched(struct kvm_pmc *pmc)
{
bool select_os, select_user;
@@ -817,29 +833,56 @@ static inline bool cpl_is_matched(struct kvm_pmc *pmc)
select_user = config & ARCH_PERFMON_EVENTSEL_USR;
} else {
config = fixed_ctrl_field(pmc_to_pmu(pmc)->fixed_ctr_ctrl,
- pmc->idx - INTEL_PMC_IDX_FIXED);
+ pmc->idx - KVM_FIXED_PMC_BASE_IDX);
select_os = config & 0x1;
select_user = config & 0x2;
}
+ /*
+ * Skip the CPL lookup, which isn't free on Intel, if the result will
+ * be the same regardless of the CPL.
+ */
+ if (select_os == select_user)
+ return select_os;
+
return (static_call(kvm_x86_get_cpl)(pmc->vcpu) == 0) ? select_os : select_user;
}
-void kvm_pmu_trigger_event(struct kvm_vcpu *vcpu, u64 perf_hw_id)
+void kvm_pmu_trigger_event(struct kvm_vcpu *vcpu, u64 eventsel)
{
+ DECLARE_BITMAP(bitmap, X86_PMC_IDX_MAX);
struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
struct kvm_pmc *pmc;
int i;
- for_each_set_bit(i, pmu->all_valid_pmc_idx, X86_PMC_IDX_MAX) {
- pmc = static_call(kvm_x86_pmu_pmc_idx_to_pmc)(pmu, i);
+ BUILD_BUG_ON(sizeof(pmu->global_ctrl) * BITS_PER_BYTE != X86_PMC_IDX_MAX);
- if (!pmc || !pmc_event_is_allowed(pmc))
+ if (!kvm_pmu_has_perf_global_ctrl(pmu))
+ bitmap_copy(bitmap, pmu->all_valid_pmc_idx, X86_PMC_IDX_MAX);
+ else if (!bitmap_and(bitmap, pmu->all_valid_pmc_idx,
+ (unsigned long *)&pmu->global_ctrl, X86_PMC_IDX_MAX))
+ return;
+
+ kvm_for_each_pmc(pmu, pmc, i, bitmap) {
+ /*
+ * Ignore checks for edge detect (all events currently emulated
+ * but KVM are always rising edges), pin control (unsupported
+ * by modern CPUs), and counter mask and its invert flag (KVM
+ * doesn't emulate multiple events in a single clock cycle).
+ *
+ * Note, the uppermost nibble of AMD's mask overlaps Intel's
+ * IN_TX (bit 32) and IN_TXCP (bit 33), as well as two reserved
+ * bits (bits 35:34). Checking the "in HLE/RTM transaction"
+ * flags is correct as the vCPU can't be in a transaction if
+ * KVM is emulating an instruction. Checking the reserved bits
+ * might be wrong if they are defined in the future, but so
+ * could ignoring them, so do the simple thing for now.
+ */
+ if (((pmc->eventsel ^ eventsel) & AMD64_RAW_EVENT_MASK_NB) ||
+ !pmc_event_is_allowed(pmc) || !cpl_is_matched(pmc))
continue;
- /* Ignore checks for edge detect, pin control, invert and CMASK bits */
- if (eventsel_match_perf_hw_id(pmc, perf_hw_id) && cpl_is_matched(pmc))
- kvm_pmu_incr_counter(pmc);
+ kvm_pmu_incr_counter(pmc);
}
}
EXPORT_SYMBOL_GPL(kvm_pmu_trigger_event);
diff --git a/arch/x86/kvm/pmu.h b/arch/x86/kvm/pmu.h
index 7caeb3d8d4fd..4d52b0b539ba 100644
--- a/arch/x86/kvm/pmu.h
+++ b/arch/x86/kvm/pmu.h
@@ -4,6 +4,8 @@
#include <linux/nospec.h>
+#include <asm/kvm_host.h>
+
#define vcpu_to_pmu(vcpu) (&(vcpu)->arch.pmu)
#define pmu_to_vcpu(pmu) (container_of((pmu), struct kvm_vcpu, arch.pmu))
#define pmc_to_pmu(pmc) (&(pmc)->vcpu->arch.pmu)
@@ -18,13 +20,18 @@
#define VMWARE_BACKDOOR_PMC_REAL_TIME 0x10001
#define VMWARE_BACKDOOR_PMC_APPARENT_TIME 0x10002
+#define KVM_FIXED_PMC_BASE_IDX INTEL_PMC_IDX_FIXED
+
+struct kvm_pmu_emulated_event_selectors {
+ u64 INSTRUCTIONS_RETIRED;
+ u64 BRANCH_INSTRUCTIONS_RETIRED;
+};
+
struct kvm_pmu_ops {
- bool (*hw_event_available)(struct kvm_pmc *pmc);
- struct kvm_pmc *(*pmc_idx_to_pmc)(struct kvm_pmu *pmu, int pmc_idx);
struct kvm_pmc *(*rdpmc_ecx_to_pmc)(struct kvm_vcpu *vcpu,
unsigned int idx, u64 *mask);
struct kvm_pmc *(*msr_idx_to_pmc)(struct kvm_vcpu *vcpu, u32 msr);
- bool (*is_valid_rdpmc_ecx)(struct kvm_vcpu *vcpu, unsigned int idx);
+ int (*check_rdpmc_early)(struct kvm_vcpu *vcpu, unsigned int idx);
bool (*is_valid_msr)(struct kvm_vcpu *vcpu, u32 msr);
int (*get_msr)(struct kvm_vcpu *vcpu, struct msr_data *msr_info);
int (*set_msr)(struct kvm_vcpu *vcpu, struct msr_data *msr_info);
@@ -55,6 +62,38 @@ static inline bool kvm_pmu_has_perf_global_ctrl(struct kvm_pmu *pmu)
return pmu->version > 1;
}
+/*
+ * KVM tracks all counters in 64-bit bitmaps, with general purpose counters
+ * mapped to bits 31:0 and fixed counters mapped to 63:32, e.g. fixed counter 0
+ * is tracked internally via index 32. On Intel, (AMD doesn't support fixed
+ * counters), this mirrors how fixed counters are mapped to PERF_GLOBAL_CTRL
+ * and similar MSRs, i.e. tracking fixed counters at base index 32 reduces the
+ * amounter of boilerplate needed to iterate over PMCs *and* simplifies common
+ * enabling/disable/reset operations.
+ *
+ * WARNING! This helper is only for lookups that are initiated by KVM, it is
+ * NOT safe for guest lookups, e.g. will do the wrong thing if passed a raw
+ * ECX value from RDPMC (fixed counters are accessed by setting bit 30 in ECX
+ * for RDPMC, not by adding 32 to the fixed counter index).
+ */
+static inline struct kvm_pmc *kvm_pmc_idx_to_pmc(struct kvm_pmu *pmu, int idx)
+{
+ if (idx < pmu->nr_arch_gp_counters)
+ return &pmu->gp_counters[idx];
+
+ idx -= KVM_FIXED_PMC_BASE_IDX;
+ if (idx >= 0 && idx < pmu->nr_arch_fixed_counters)
+ return &pmu->fixed_counters[idx];
+
+ return NULL;
+}
+
+#define kvm_for_each_pmc(pmu, pmc, i, bitmap) \
+ for_each_set_bit(i, bitmap, X86_PMC_IDX_MAX) \
+ if (!(pmc = kvm_pmc_idx_to_pmc(pmu, i))) \
+ continue; \
+ else \
+
static inline u64 pmc_bitmask(struct kvm_pmc *pmc)
{
struct kvm_pmu *pmu = pmc_to_pmu(pmc);
@@ -131,12 +170,13 @@ 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 - INTEL_PMC_IDX_FIXED) & 0x3;
+ pmc->idx - KVM_FIXED_PMC_BASE_IDX) & 0x3;
return pmc->eventsel & ARCH_PERFMON_EVENTSEL_ENABLE;
}
extern struct x86_pmu_capability kvm_pmu_cap;
+extern struct kvm_pmu_emulated_event_selectors kvm_pmu_eventsel;
static inline void kvm_init_pmu_capability(const struct kvm_pmu_ops *pmu_ops)
{
@@ -178,6 +218,11 @@ static inline void kvm_init_pmu_capability(const struct kvm_pmu_ops *pmu_ops)
pmu_ops->MAX_NR_GP_COUNTERS);
kvm_pmu_cap.num_counters_fixed = min(kvm_pmu_cap.num_counters_fixed,
KVM_PMC_MAX_FIXED);
+
+ kvm_pmu_eventsel.INSTRUCTIONS_RETIRED =
+ perf_get_hw_event_config(PERF_COUNT_HW_INSTRUCTIONS);
+ kvm_pmu_eventsel.BRANCH_INSTRUCTIONS_RETIRED =
+ perf_get_hw_event_config(PERF_COUNT_HW_BRANCH_INSTRUCTIONS);
}
static inline void kvm_pmu_request_counter_reprogram(struct kvm_pmc *pmc)
@@ -216,7 +261,7 @@ static inline bool pmc_is_globally_enabled(struct kvm_pmc *pmc)
void kvm_pmu_deliver_pmi(struct kvm_vcpu *vcpu);
void kvm_pmu_handle_event(struct kvm_vcpu *vcpu);
int kvm_pmu_rdpmc(struct kvm_vcpu *vcpu, unsigned pmc, u64 *data);
-bool kvm_pmu_is_valid_rdpmc_ecx(struct kvm_vcpu *vcpu, unsigned int idx);
+int kvm_pmu_check_rdpmc_early(struct kvm_vcpu *vcpu, unsigned int idx);
bool kvm_pmu_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr);
int kvm_pmu_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info);
int kvm_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info);
@@ -225,7 +270,7 @@ void kvm_pmu_init(struct kvm_vcpu *vcpu);
void kvm_pmu_cleanup(struct kvm_vcpu *vcpu);
void kvm_pmu_destroy(struct kvm_vcpu *vcpu);
int kvm_vm_ioctl_set_pmu_event_filter(struct kvm *kvm, void __user *argp);
-void kvm_pmu_trigger_event(struct kvm_vcpu *vcpu, u64 perf_hw_id);
+void kvm_pmu_trigger_event(struct kvm_vcpu *vcpu, u64 eventsel);
bool is_vmware_backdoor_pmc(u32 pmc_idx);
diff --git a/arch/x86/kvm/reverse_cpuid.h b/arch/x86/kvm/reverse_cpuid.h
index aadefcaa9561..2f4e155080ba 100644
--- a/arch/x86/kvm/reverse_cpuid.h
+++ b/arch/x86/kvm/reverse_cpuid.h
@@ -52,7 +52,7 @@ enum kvm_only_cpuid_leafs {
#define X86_FEATURE_IPRED_CTRL KVM_X86_FEATURE(CPUID_7_2_EDX, 1)
#define KVM_X86_FEATURE_RRSBA_CTRL KVM_X86_FEATURE(CPUID_7_2_EDX, 2)
#define X86_FEATURE_DDPD_U KVM_X86_FEATURE(CPUID_7_2_EDX, 3)
-#define X86_FEATURE_BHI_CTRL KVM_X86_FEATURE(CPUID_7_2_EDX, 4)
+#define KVM_X86_FEATURE_BHI_CTRL KVM_X86_FEATURE(CPUID_7_2_EDX, 4)
#define X86_FEATURE_MCDT_NO KVM_X86_FEATURE(CPUID_7_2_EDX, 5)
/* CPUID level 0x80000007 (EDX). */
@@ -102,10 +102,12 @@ static const struct cpuid_reg reverse_cpuid[] = {
*/
static __always_inline void reverse_cpuid_check(unsigned int x86_leaf)
{
+ BUILD_BUG_ON(NR_CPUID_WORDS != NCAPINTS);
BUILD_BUG_ON(x86_leaf == CPUID_LNX_1);
BUILD_BUG_ON(x86_leaf == CPUID_LNX_2);
BUILD_BUG_ON(x86_leaf == CPUID_LNX_3);
BUILD_BUG_ON(x86_leaf == CPUID_LNX_4);
+ BUILD_BUG_ON(x86_leaf == CPUID_LNX_5);
BUILD_BUG_ON(x86_leaf >= ARRAY_SIZE(reverse_cpuid));
BUILD_BUG_ON(reverse_cpuid[x86_leaf].function == 0);
}
@@ -126,6 +128,7 @@ static __always_inline u32 __feature_translate(int x86_feature)
KVM_X86_TRANSLATE_FEATURE(CONSTANT_TSC);
KVM_X86_TRANSLATE_FEATURE(PERFMON_V2);
KVM_X86_TRANSLATE_FEATURE(RRSBA_CTRL);
+ KVM_X86_TRANSLATE_FEATURE(BHI_CTRL);
default:
return x86_feature;
}
diff --git a/arch/x86/kvm/smm.c b/arch/x86/kvm/smm.c
index dc3d95fdca7d..d06d43d8d2aa 100644
--- a/arch/x86/kvm/smm.c
+++ b/arch/x86/kvm/smm.c
@@ -184,7 +184,6 @@ static void enter_smm_save_state_32(struct kvm_vcpu *vcpu,
struct kvm_smram_state_32 *smram)
{
struct desc_ptr dt;
- unsigned long val;
int i;
smram->cr0 = kvm_read_cr0(vcpu);
@@ -195,10 +194,8 @@ static void enter_smm_save_state_32(struct kvm_vcpu *vcpu,
for (i = 0; i < 8; i++)
smram->gprs[i] = kvm_register_read_raw(vcpu, i);
- kvm_get_dr(vcpu, 6, &val);
- smram->dr6 = (u32)val;
- kvm_get_dr(vcpu, 7, &val);
- smram->dr7 = (u32)val;
+ smram->dr6 = (u32)vcpu->arch.dr6;
+ smram->dr7 = (u32)vcpu->arch.dr7;
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);
@@ -231,7 +228,6 @@ static void enter_smm_save_state_64(struct kvm_vcpu *vcpu,
struct kvm_smram_state_64 *smram)
{
struct desc_ptr dt;
- unsigned long val;
int i;
for (i = 0; i < 16; i++)
@@ -240,11 +236,8 @@ static void enter_smm_save_state_64(struct kvm_vcpu *vcpu,
smram->rip = kvm_rip_read(vcpu);
smram->rflags = kvm_get_rflags(vcpu);
-
- kvm_get_dr(vcpu, 6, &val);
- smram->dr6 = val;
- kvm_get_dr(vcpu, 7, &val);
- smram->dr7 = val;
+ smram->dr6 = vcpu->arch.dr6;
+ smram->dr7 = vcpu->arch.dr7;
smram->cr0 = kvm_read_cr0(vcpu);
smram->cr3 = kvm_read_cr3(vcpu);
diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
index dee62362a360..55b9a6d96bcf 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 = alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO);
+ vmcb02_page = snp_safe_alloc_page(&svm->vcpu);
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 b6a7ad4d6914..dfcc38bd97d3 100644
--- a/arch/x86/kvm/svm/pmu.c
+++ b/arch/x86/kvm/svm/pmu.c
@@ -25,7 +25,7 @@ enum pmu_type {
PMU_TYPE_EVNTSEL,
};
-static struct kvm_pmc *amd_pmc_idx_to_pmc(struct kvm_pmu *pmu, int pmc_idx)
+static struct kvm_pmc *amd_pmu_get_pmc(struct kvm_pmu *pmu, int pmc_idx)
{
unsigned int num_counters = pmu->nr_arch_gp_counters;
@@ -70,28 +70,24 @@ static inline struct kvm_pmc *get_gp_pmc_amd(struct kvm_pmu *pmu, u32 msr,
return NULL;
}
- return amd_pmc_idx_to_pmc(pmu, idx);
+ return amd_pmu_get_pmc(pmu, idx);
}
-static bool amd_hw_event_available(struct kvm_pmc *pmc)
-{
- return true;
-}
-
-static bool amd_is_valid_rdpmc_ecx(struct kvm_vcpu *vcpu, unsigned int idx)
+static int amd_check_rdpmc_early(struct kvm_vcpu *vcpu, unsigned int idx)
{
struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
- idx &= ~(3u << 30);
+ if (idx >= pmu->nr_arch_gp_counters)
+ return -EINVAL;
- return idx < pmu->nr_arch_gp_counters;
+ return 0;
}
/* idx is the ECX register of RDPMC instruction */
static struct kvm_pmc *amd_rdpmc_ecx_to_pmc(struct kvm_vcpu *vcpu,
unsigned int idx, u64 *mask)
{
- return amd_pmc_idx_to_pmc(vcpu_to_pmu(vcpu), idx & ~(3u << 30));
+ return amd_pmu_get_pmc(vcpu_to_pmu(vcpu), idx);
}
static struct kvm_pmc *amd_msr_idx_to_pmc(struct kvm_vcpu *vcpu, u32 msr)
@@ -233,11 +229,9 @@ static void amd_pmu_init(struct kvm_vcpu *vcpu)
}
struct kvm_pmu_ops amd_pmu_ops __initdata = {
- .hw_event_available = amd_hw_event_available,
- .pmc_idx_to_pmc = amd_pmc_idx_to_pmc,
.rdpmc_ecx_to_pmc = amd_rdpmc_ecx_to_pmc,
.msr_idx_to_pmc = amd_msr_idx_to_pmc,
- .is_valid_rdpmc_ecx = amd_is_valid_rdpmc_ecx,
+ .check_rdpmc_early = amd_check_rdpmc_early,
.is_valid_msr = amd_is_valid_msr,
.get_msr = amd_pmu_get_msr,
.set_msr = amd_pmu_set_msr,
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index a8ce5226b3b5..61a7531d41b0 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -84,9 +84,10 @@ struct enc_region {
};
/* Called with the sev_bitmap_lock held, or on shutdown */
-static int sev_flush_asids(int min_asid, int max_asid)
+static int sev_flush_asids(unsigned int min_asid, unsigned int max_asid)
{
- int ret, asid, error = 0;
+ int ret, error = 0;
+ unsigned int asid;
/* Check if there are any ASIDs to reclaim before performing a flush */
asid = find_next_bit(sev_reclaim_asid_bitmap, nr_asids, min_asid);
@@ -116,7 +117,7 @@ static inline bool is_mirroring_enc_context(struct kvm *kvm)
}
/* Must be called with the sev_bitmap_lock held */
-static bool __sev_recycle_asids(int min_asid, int max_asid)
+static bool __sev_recycle_asids(unsigned int min_asid, unsigned int max_asid)
{
if (sev_flush_asids(min_asid, max_asid))
return false;
@@ -143,8 +144,20 @@ static void sev_misc_cg_uncharge(struct kvm_sev_info *sev)
static int sev_asid_new(struct kvm_sev_info *sev)
{
- int asid, min_asid, max_asid, ret;
+ /*
+ * SEV-enabled guests must use asid from min_sev_asid to max_sev_asid.
+ * SEV-ES-enabled guest can use from 1 to min_sev_asid - 1.
+ * Note: min ASID can end up larger than the max if basic SEV support is
+ * effectively disabled by disallowing use of ASIDs for SEV guests.
+ */
+ unsigned int min_asid = sev->es_active ? 1 : min_sev_asid;
+ unsigned int max_asid = sev->es_active ? min_sev_asid - 1 : max_sev_asid;
+ unsigned int asid;
bool retry = true;
+ int ret;
+
+ if (min_asid > max_asid)
+ return -ENOTTY;
WARN_ON(sev->misc_cg);
sev->misc_cg = get_current_misc_cg();
@@ -157,12 +170,6 @@ static int sev_asid_new(struct kvm_sev_info *sev)
mutex_lock(&sev_bitmap_lock);
- /*
- * SEV-enabled guests must use asid from min_sev_asid to max_sev_asid.
- * SEV-ES-enabled guest can use from 1 to min_sev_asid - 1.
- */
- min_asid = sev->es_active ? 1 : min_sev_asid;
- max_asid = sev->es_active ? min_sev_asid - 1 : max_sev_asid;
again:
asid = find_next_zero_bit(sev_asid_bitmap, max_asid + 1, min_asid);
if (asid > max_asid) {
@@ -179,7 +186,8 @@ again:
mutex_unlock(&sev_bitmap_lock);
- return asid;
+ sev->asid = asid;
+ return 0;
e_uncharge:
sev_misc_cg_uncharge(sev);
put_misc_cg(sev->misc_cg);
@@ -187,7 +195,7 @@ e_uncharge:
return ret;
}
-static int sev_get_asid(struct kvm *kvm)
+static unsigned int sev_get_asid(struct kvm *kvm)
{
struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
@@ -246,23 +254,23 @@ static void sev_unbind_asid(struct kvm *kvm, unsigned int handle)
static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp)
{
struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
- int asid, ret;
+ struct sev_platform_init_args init_args = {0};
+ int ret;
if (kvm->created_vcpus)
return -EINVAL;
- ret = -EBUSY;
if (unlikely(sev->active))
- return ret;
+ return -EINVAL;
sev->active = true;
sev->es_active = argp->id == KVM_SEV_ES_INIT;
- asid = sev_asid_new(sev);
- if (asid < 0)
+ ret = sev_asid_new(sev);
+ if (ret)
goto e_no_asid;
- sev->asid = asid;
- ret = sev_platform_init(&argp->error);
+ init_args.probe = false;
+ ret = sev_platform_init(&init_args);
if (ret)
goto e_free;
@@ -274,6 +282,7 @@ static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp)
return 0;
e_free:
+ argp->error = init_args.error;
sev_asid_free(sev);
sev->asid = 0;
e_no_asid:
@@ -284,8 +293,8 @@ e_no_asid:
static int sev_bind_asid(struct kvm *kvm, unsigned int handle, int *error)
{
+ unsigned int asid = sev_get_asid(kvm);
struct sev_data_activate activate;
- int asid = sev_get_asid(kvm);
int ret;
/* activate ASID on the given handle */
@@ -2237,8 +2246,10 @@ void __init sev_hardware_setup(void)
goto out;
}
- sev_asid_count = max_sev_asid - min_sev_asid + 1;
- WARN_ON_ONCE(misc_cg_set_capacity(MISC_CG_RES_SEV, sev_asid_count));
+ if (min_sev_asid <= max_sev_asid) {
+ sev_asid_count = max_sev_asid - min_sev_asid + 1;
+ WARN_ON_ONCE(misc_cg_set_capacity(MISC_CG_RES_SEV, sev_asid_count));
+ }
sev_supported = true;
/* SEV-ES support requested? */
@@ -2269,7 +2280,9 @@ void __init sev_hardware_setup(void)
out:
if (boot_cpu_has(X86_FEATURE_SEV))
pr_info("SEV %s (ASIDs %u - %u)\n",
- sev_supported ? "enabled" : "disabled",
+ sev_supported ? min_sev_asid <= max_sev_asid ? "enabled" :
+ "unusable" :
+ "disabled",
min_sev_asid, max_sev_asid);
if (boot_cpu_has(X86_FEATURE_SEV_ES))
pr_info("SEV-ES %s (ASIDs %u - %u)\n",
@@ -2317,7 +2330,7 @@ int sev_cpu_init(struct svm_cpu_data *sd)
*/
static void sev_flush_encrypted_page(struct kvm_vcpu *vcpu, void *va)
{
- int asid = to_kvm_svm(vcpu->kvm)->sev_info.asid;
+ unsigned int asid = sev_get_asid(vcpu->kvm);
/*
* Note! The address must be a kernel address, as regular page walk
@@ -2635,7 +2648,7 @@ void sev_es_unmap_ghcb(struct vcpu_svm *svm)
void pre_sev_run(struct vcpu_svm *svm, int cpu)
{
struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, cpu);
- int asid = sev_get_asid(svm->vcpu.kvm);
+ unsigned int asid = sev_get_asid(svm->vcpu.kvm);
/* Assign the asid allocated with this SEV guest */
svm->asid = asid;
@@ -3165,3 +3178,35 @@ void sev_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector)
ghcb_set_sw_exit_info_2(svm->sev_es.ghcb, 1);
}
+
+struct page *snp_safe_alloc_page(struct kvm_vcpu *vcpu)
+{
+ unsigned long pfn;
+ struct page *p;
+
+ if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP))
+ return alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO);
+
+ /*
+ * Allocate an SNP-safe page to workaround the SNP erratum where
+ * the CPU will incorrectly signal an RMP violation #PF if a
+ * hugepage (2MB or 1GB) collides with the RMP entry of a
+ * 2MB-aligned VMCB, VMSA, or AVIC backing page.
+ *
+ * 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);
+ if (!p)
+ return NULL;
+
+ split_page(p, 1);
+
+ pfn = page_to_pfn(p);
+ if (IS_ALIGNED(pfn, PTRS_PER_PMD))
+ __free_page(p++);
+ else
+ __free_page(p + 1);
+
+ return p;
+}
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index e90b429c84f1..d1a9f9951635 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -703,7 +703,7 @@ static int svm_cpu_init(int cpu)
int ret = -ENOMEM;
memset(sd, 0, sizeof(struct svm_cpu_data));
- sd->save_area = alloc_page(GFP_KERNEL | __GFP_ZERO);
+ sd->save_area = snp_safe_alloc_page(NULL);
if (!sd->save_area)
return ret;
@@ -1421,7 +1421,7 @@ static int svm_vcpu_create(struct kvm_vcpu *vcpu)
svm = to_svm(vcpu);
err = -ENOMEM;
- vmcb01_page = alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO);
+ vmcb01_page = snp_safe_alloc_page(vcpu);
if (!vmcb01_page)
goto out;
@@ -1430,7 +1430,7 @@ 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 = alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO);
+ vmsa_page = snp_safe_alloc_page(vcpu);
if (!vmsa_page)
goto error_free_vmcb_page;
@@ -2735,7 +2735,6 @@ static int dr_interception(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
int reg, dr;
- unsigned long val;
int err = 0;
/*
@@ -2763,11 +2762,9 @@ static int dr_interception(struct kvm_vcpu *vcpu)
dr = svm->vmcb->control.exit_code - SVM_EXIT_READ_DR0;
if (dr >= 16) { /* mov to DRn */
dr -= 16;
- val = kvm_register_read(vcpu, reg);
- err = kvm_set_dr(vcpu, dr, val);
+ err = kvm_set_dr(vcpu, dr, kvm_register_read(vcpu, reg));
} else {
- kvm_get_dr(vcpu, dr, &val);
- kvm_register_write(vcpu, reg, val);
+ kvm_register_write(vcpu, reg, kvm_get_dr(vcpu, dr));
}
return kvm_complete_insn_gp(vcpu, err);
@@ -3455,7 +3452,7 @@ int svm_invoke_exit_handler(struct kvm_vcpu *vcpu, u64 exit_code)
if (!svm_check_exit_valid(exit_code))
return svm_handle_invalid_exit(vcpu, exit_code);
-#ifdef CONFIG_RETPOLINE
+#ifdef CONFIG_MITIGATION_RETPOLINE
if (exit_code == SVM_EXIT_MSR)
return msr_interception(vcpu);
else if (exit_code == SVM_EXIT_VINTR)
@@ -4092,6 +4089,9 @@ static int svm_vcpu_pre_run(struct kvm_vcpu *vcpu)
static fastpath_t svm_exit_handlers_fastpath(struct kvm_vcpu *vcpu)
{
+ if (is_guest_mode(vcpu))
+ return EXIT_FASTPATH_NONE;
+
if (to_svm(vcpu)->vmcb->control.exit_code == SVM_EXIT_MSR &&
to_svm(vcpu)->vmcb->control.exit_info_1)
return handle_fastpath_set_msr_irqoff(vcpu);
@@ -4115,12 +4115,13 @@ static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu, bool spec_ctrl_in
guest_state_exit_irqoff();
}
-static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu)
+static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu,
+ bool force_immediate_exit)
{
struct vcpu_svm *svm = to_svm(vcpu);
bool spec_ctrl_intercepted = msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL);
- trace_kvm_entry(vcpu);
+ trace_kvm_entry(vcpu, force_immediate_exit);
svm->vmcb->save.rax = vcpu->arch.regs[VCPU_REGS_RAX];
svm->vmcb->save.rsp = vcpu->arch.regs[VCPU_REGS_RSP];
@@ -4139,9 +4140,12 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu)
* is enough to force an immediate vmexit.
*/
disable_nmi_singlestep(svm);
- smp_send_reschedule(vcpu->cpu);
+ force_immediate_exit = true;
}
+ if (force_immediate_exit)
+ smp_send_reschedule(vcpu->cpu);
+
pre_svm_run(vcpu);
sync_lapic_to_cr8(vcpu);
@@ -4237,9 +4241,6 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu)
svm_complete_interrupts(vcpu);
- if (is_guest_mode(vcpu))
- return EXIT_FASTPATH_NONE;
-
return svm_exit_handlers_fastpath(vcpu);
}
@@ -4900,6 +4901,16 @@ static int svm_vm_init(struct kvm *kvm)
return 0;
}
+static void *svm_alloc_apic_backing_page(struct kvm_vcpu *vcpu)
+{
+ struct page *page = snp_safe_alloc_page(vcpu);
+
+ if (!page)
+ return NULL;
+
+ return page_address(page);
+}
+
static struct kvm_x86_ops svm_x86_ops __initdata = {
.name = KBUILD_MODNAME,
@@ -4997,8 +5008,6 @@ static struct kvm_x86_ops svm_x86_ops __initdata = {
.check_intercept = svm_check_intercept,
.handle_exit_irqoff = svm_handle_exit_irqoff,
- .request_immediate_exit = __kvm_request_immediate_exit,
-
.sched_in = svm_sched_in,
.nested_ops = &svm_nested_ops,
@@ -5031,6 +5040,7 @@ 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,
};
/*
diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index 8ef95139cd24..7f1fbd874c45 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -694,6 +694,7 @@ 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);
/* vmenter.S */
diff --git a/arch/x86/kvm/svm/vmenter.S b/arch/x86/kvm/svm/vmenter.S
index 9499f9c6b077..187018c424bf 100644
--- a/arch/x86/kvm/svm/vmenter.S
+++ b/arch/x86/kvm/svm/vmenter.S
@@ -207,7 +207,7 @@ SYM_FUNC_START(__svm_vcpu_run)
7: vmload %_ASM_AX
8:
-#ifdef CONFIG_RETPOLINE
+#ifdef CONFIG_MITIGATION_RETPOLINE
/* IMPORTANT: Stuff the RSB immediately after VM-Exit, before RET! */
FILL_RETURN_BUFFER %_ASM_AX, RSB_CLEAR_LOOPS, X86_FEATURE_RETPOLINE
#endif
@@ -344,7 +344,7 @@ SYM_FUNC_START(__svm_sev_es_vcpu_run)
/* Pop @svm to RDI, guest registers have been saved already. */
pop %_ASM_DI
-#ifdef CONFIG_RETPOLINE
+#ifdef CONFIG_MITIGATION_RETPOLINE
/* IMPORTANT: Stuff the RSB immediately after VM-Exit, before RET! */
FILL_RETURN_BUFFER %_ASM_AX, RSB_CLEAR_LOOPS, X86_FEATURE_RETPOLINE
#endif
diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h
index 83843379813e..c6b4b1728006 100644
--- a/arch/x86/kvm/trace.h
+++ b/arch/x86/kvm/trace.h
@@ -15,20 +15,23 @@
* Tracepoint for guest mode entry.
*/
TRACE_EVENT(kvm_entry,
- TP_PROTO(struct kvm_vcpu *vcpu),
- TP_ARGS(vcpu),
+ TP_PROTO(struct kvm_vcpu *vcpu, bool force_immediate_exit),
+ TP_ARGS(vcpu, force_immediate_exit),
TP_STRUCT__entry(
__field( unsigned int, vcpu_id )
__field( unsigned long, rip )
+ __field( bool, immediate_exit )
),
TP_fast_assign(
__entry->vcpu_id = vcpu->vcpu_id;
__entry->rip = kvm_rip_read(vcpu);
+ __entry->immediate_exit = force_immediate_exit;
),
- TP_printk("vcpu %u, rip 0x%lx", __entry->vcpu_id, __entry->rip)
+ TP_printk("vcpu %u, rip 0x%lx%s", __entry->vcpu_id, __entry->rip,
+ __entry->immediate_exit ? "[immediate exit]" : "")
);
/*
@@ -732,13 +735,13 @@ TRACE_EVENT(kvm_nested_intr_vmexit,
* Tracepoint for nested #vmexit because of interrupt pending
*/
TRACE_EVENT(kvm_invlpga,
- TP_PROTO(__u64 rip, int asid, u64 address),
+ TP_PROTO(__u64 rip, unsigned int asid, u64 address),
TP_ARGS(rip, asid, address),
TP_STRUCT__entry(
- __field( __u64, rip )
- __field( int, asid )
- __field( __u64, address )
+ __field( __u64, rip )
+ __field( unsigned int, asid )
+ __field( __u64, address )
),
TP_fast_assign(
@@ -747,7 +750,7 @@ TRACE_EVENT(kvm_invlpga,
__entry->address = address;
),
- TP_printk("rip: 0x%016llx asid: %d address: 0x%016llx",
+ TP_printk("rip: 0x%016llx asid: %u address: 0x%016llx",
__entry->rip, __entry->asid, __entry->address)
);
diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
index 6329a306856b..d05ddf751491 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -3606,7 +3606,7 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch)
return 1;
}
- kvm_pmu_trigger_event(vcpu, PERF_COUNT_HW_BRANCH_INSTRUCTIONS);
+ kvm_pmu_trigger_event(vcpu, kvm_pmu_eventsel.BRANCH_INSTRUCTIONS_RETIRED);
if (CC(evmptrld_status == EVMPTRLD_VMFAIL))
return nested_vmx_failInvalid(vcpu);
@@ -4433,7 +4433,7 @@ static void sync_vmcs02_to_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
(vm_entry_controls_get(to_vmx(vcpu)) & VM_ENTRY_IA32E_MODE);
if (vmcs12->vm_exit_controls & VM_EXIT_SAVE_DEBUG_CONTROLS)
- kvm_get_dr(vcpu, 7, (unsigned long *)&vmcs12->guest_dr7);
+ vmcs12->guest_dr7 = vcpu->arch.dr7;
if (vmcs12->vm_exit_controls & VM_EXIT_SAVE_IA32_EFER)
vmcs12->guest_ia32_efer = vcpu->arch.efer;
diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
index 315c7c2ba89b..12ade343a17e 100644
--- a/arch/x86/kvm/vmx/pmu_intel.c
+++ b/arch/x86/kvm/vmx/pmu_intel.c
@@ -20,53 +20,19 @@
#include "nested.h"
#include "pmu.h"
-#define MSR_PMC_FULL_WIDTH_BIT (MSR_IA32_PMC0 - MSR_IA32_PERFCTR0)
-
-enum intel_pmu_architectural_events {
- /*
- * The order of the architectural events matters as support for each
- * event is enumerated via CPUID using the index of the event.
- */
- INTEL_ARCH_CPU_CYCLES,
- INTEL_ARCH_INSTRUCTIONS_RETIRED,
- INTEL_ARCH_REFERENCE_CYCLES,
- INTEL_ARCH_LLC_REFERENCES,
- INTEL_ARCH_LLC_MISSES,
- INTEL_ARCH_BRANCHES_RETIRED,
- INTEL_ARCH_BRANCHES_MISPREDICTED,
-
- NR_REAL_INTEL_ARCH_EVENTS,
-
- /*
- * Pseudo-architectural event used to implement IA32_FIXED_CTR2, a.k.a.
- * TSC reference cycles. The architectural reference cycles event may
- * or may not actually use the TSC as the reference, e.g. might use the
- * core crystal clock or the bus clock (yeah, "architectural").
- */
- PSEUDO_ARCH_REFERENCE_CYCLES = NR_REAL_INTEL_ARCH_EVENTS,
- NR_INTEL_ARCH_EVENTS,
-};
+/*
+ * Perf's "BASE" is wildly misleading, architectural PMUs use bits 31:16 of ECX
+ * to encode the "type" of counter to read, i.e. this is not a "base". And to
+ * further confuse things, non-architectural PMUs use bit 31 as a flag for
+ * "fast" reads, whereas the "type" is an explicit value.
+ */
+#define INTEL_RDPMC_GP 0
+#define INTEL_RDPMC_FIXED INTEL_PMC_FIXED_RDPMC_BASE
-static struct {
- u8 eventsel;
- u8 unit_mask;
-} const intel_arch_events[] = {
- [INTEL_ARCH_CPU_CYCLES] = { 0x3c, 0x00 },
- [INTEL_ARCH_INSTRUCTIONS_RETIRED] = { 0xc0, 0x00 },
- [INTEL_ARCH_REFERENCE_CYCLES] = { 0x3c, 0x01 },
- [INTEL_ARCH_LLC_REFERENCES] = { 0x2e, 0x4f },
- [INTEL_ARCH_LLC_MISSES] = { 0x2e, 0x41 },
- [INTEL_ARCH_BRANCHES_RETIRED] = { 0xc4, 0x00 },
- [INTEL_ARCH_BRANCHES_MISPREDICTED] = { 0xc5, 0x00 },
- [PSEUDO_ARCH_REFERENCE_CYCLES] = { 0x00, 0x03 },
-};
+#define INTEL_RDPMC_TYPE_MASK GENMASK(31, 16)
+#define INTEL_RDPMC_INDEX_MASK GENMASK(15, 0)
-/* mapping between fixed pmc index and intel_arch_events array */
-static int fixed_pmc_events[] = {
- [0] = INTEL_ARCH_INSTRUCTIONS_RETIRED,
- [1] = INTEL_ARCH_CPU_CYCLES,
- [2] = PSEUDO_ARCH_REFERENCE_CYCLES,
-};
+#define MSR_PMC_FULL_WIDTH_BIT (MSR_IA32_PMC0 - MSR_IA32_PERFCTR0)
static void reprogram_fixed_counters(struct kvm_pmu *pmu, u64 data)
{
@@ -84,77 +50,61 @@ static void reprogram_fixed_counters(struct kvm_pmu *pmu, u64 data)
pmc = get_fixed_pmc(pmu, MSR_CORE_PERF_FIXED_CTR0 + i);
- __set_bit(INTEL_PMC_IDX_FIXED + i, pmu->pmc_in_use);
+ __set_bit(KVM_FIXED_PMC_BASE_IDX + i, pmu->pmc_in_use);
kvm_pmu_request_counter_reprogram(pmc);
}
}
-static struct kvm_pmc *intel_pmc_idx_to_pmc(struct kvm_pmu *pmu, int pmc_idx)
-{
- if (pmc_idx < INTEL_PMC_IDX_FIXED) {
- return get_gp_pmc(pmu, MSR_P6_EVNTSEL0 + pmc_idx,
- MSR_P6_EVNTSEL0);
- } else {
- u32 idx = pmc_idx - INTEL_PMC_IDX_FIXED;
-
- return get_fixed_pmc(pmu, idx + MSR_CORE_PERF_FIXED_CTR0);
- }
-}
-
-static bool intel_hw_event_available(struct kvm_pmc *pmc)
-{
- struct kvm_pmu *pmu = pmc_to_pmu(pmc);
- u8 event_select = pmc->eventsel & ARCH_PERFMON_EVENTSEL_EVENT;
- u8 unit_mask = (pmc->eventsel & ARCH_PERFMON_EVENTSEL_UMASK) >> 8;
- int i;
-
- BUILD_BUG_ON(ARRAY_SIZE(intel_arch_events) != NR_INTEL_ARCH_EVENTS);
-
- /*
- * Disallow events reported as unavailable in guest CPUID. Note, this
- * doesn't apply to pseudo-architectural events.
- */
- for (i = 0; i < NR_REAL_INTEL_ARCH_EVENTS; i++) {
- if (intel_arch_events[i].eventsel != event_select ||
- intel_arch_events[i].unit_mask != unit_mask)
- continue;
-
- return pmu->available_event_types & BIT(i);
- }
-
- return true;
-}
-
-static bool intel_is_valid_rdpmc_ecx(struct kvm_vcpu *vcpu, unsigned int idx)
-{
- struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
- bool fixed = idx & (1u << 30);
-
- idx &= ~(3u << 30);
-
- return fixed ? idx < pmu->nr_arch_fixed_counters
- : idx < pmu->nr_arch_gp_counters;
-}
-
static struct kvm_pmc *intel_rdpmc_ecx_to_pmc(struct kvm_vcpu *vcpu,
unsigned int idx, u64 *mask)
{
+ unsigned int type = idx & INTEL_RDPMC_TYPE_MASK;
struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
- bool fixed = idx & (1u << 30);
struct kvm_pmc *counters;
unsigned int num_counters;
+ u64 bitmask;
- idx &= ~(3u << 30);
- if (fixed) {
+ /*
+ * The encoding of ECX for RDPMC is different for architectural versus
+ * non-architecturals PMUs (PMUs with version '0'). For architectural
+ * PMUs, bits 31:16 specify the PMC type and bits 15:0 specify the PMC
+ * index. For non-architectural PMUs, bit 31 is a "fast" flag, and
+ * bits 30:0 specify the PMC index.
+ *
+ * Yell and reject attempts to read PMCs for a non-architectural PMU,
+ * as KVM doesn't support such PMUs.
+ */
+ if (WARN_ON_ONCE(!pmu->version))
+ return NULL;
+
+ /*
+ * General Purpose (GP) PMCs are supported on all PMUs, and fixed PMCs
+ * are supported on all architectural PMUs, i.e. on all virtual PMUs
+ * supported by KVM. Note, KVM only emulates fixed PMCs for PMU v2+,
+ * but the type itself is still valid, i.e. let RDPMC fail due to
+ * accessing a non-existent counter. Reject attempts to read all other
+ * types, which are unknown/unsupported.
+ */
+ switch (type) {
+ case INTEL_RDPMC_FIXED:
counters = pmu->fixed_counters;
num_counters = pmu->nr_arch_fixed_counters;
- } else {
+ bitmask = pmu->counter_bitmask[KVM_PMC_FIXED];
+ break;
+ case INTEL_RDPMC_GP:
counters = pmu->gp_counters;
num_counters = pmu->nr_arch_gp_counters;
+ bitmask = pmu->counter_bitmask[KVM_PMC_GP];
+ break;
+ default:
+ return NULL;
}
+
+ idx &= INTEL_RDPMC_INDEX_MASK;
if (idx >= num_counters)
return NULL;
- *mask &= pmu->counter_bitmask[fixed ? KVM_PMC_FIXED : KVM_PMC_GP];
+
+ *mask &= bitmask;
return &counters[array_index_nospec(idx, num_counters)];
}
@@ -464,20 +414,38 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
return 0;
}
-static void setup_fixed_pmc_eventsel(struct kvm_pmu *pmu)
+/*
+ * Map fixed counter events to architectural general purpose event encodings.
+ * Perf doesn't provide APIs to allow KVM to directly program a fixed counter,
+ * and so KVM instead programs the architectural event to effectively request
+ * the fixed counter. Perf isn't guaranteed to use a fixed counter and may
+ * instead program the encoding into a general purpose counter, e.g. if a
+ * different perf_event is already utilizing the requested counter, but the end
+ * result is the same (ignoring the fact that using a general purpose counter
+ * will likely exacerbate counter contention).
+ *
+ * Forcibly inlined to allow asserting on @index at build time, and there should
+ * never be more than one user.
+ */
+static __always_inline u64 intel_get_fixed_pmc_eventsel(unsigned int index)
{
- int i;
-
- BUILD_BUG_ON(ARRAY_SIZE(fixed_pmc_events) != KVM_PMC_MAX_FIXED);
+ const enum perf_hw_id fixed_pmc_perf_ids[] = {
+ [0] = PERF_COUNT_HW_INSTRUCTIONS,
+ [1] = PERF_COUNT_HW_CPU_CYCLES,
+ [2] = PERF_COUNT_HW_REF_CPU_CYCLES,
+ };
+ u64 eventsel;
- for (i = 0; i < pmu->nr_arch_fixed_counters; i++) {
- int index = array_index_nospec(i, KVM_PMC_MAX_FIXED);
- struct kvm_pmc *pmc = &pmu->fixed_counters[index];
- u32 event = fixed_pmc_events[index];
+ BUILD_BUG_ON(ARRAY_SIZE(fixed_pmc_perf_ids) != KVM_PMC_MAX_FIXED);
+ BUILD_BUG_ON(index >= KVM_PMC_MAX_FIXED);
- pmc->eventsel = (intel_arch_events[event].unit_mask << 8) |
- intel_arch_events[event].eventsel;
- }
+ /*
+ * Yell if perf reports support for a fixed counter but perf doesn't
+ * have a known encoding for the associated general purpose event.
+ */
+ eventsel = perf_get_hw_event_config(fixed_pmc_perf_ids[index]);
+ WARN_ON_ONCE(!eventsel && index < kvm_pmu_cap.num_counters_fixed);
+ return eventsel;
}
static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
@@ -491,19 +459,6 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
u64 counter_mask;
int i;
- pmu->nr_arch_gp_counters = 0;
- pmu->nr_arch_fixed_counters = 0;
- pmu->counter_bitmask[KVM_PMC_GP] = 0;
- pmu->counter_bitmask[KVM_PMC_FIXED] = 0;
- pmu->version = 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;
-
memset(&lbr_desc->records, 0, sizeof(lbr_desc->records));
/*
@@ -515,8 +470,9 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
return;
entry = kvm_find_cpuid_entry(vcpu, 0xa);
- if (!entry || !vcpu->kvm->arch.enable_pmu)
+ if (!entry)
return;
+
eax.full = entry->eax;
edx.full = entry->edx;
@@ -543,13 +499,12 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
kvm_pmu_cap.bit_width_fixed);
pmu->counter_bitmask[KVM_PMC_FIXED] =
((u64)1 << edx.split.bit_width_fixed) - 1;
- setup_fixed_pmc_eventsel(pmu);
}
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) |
- (((1ull << pmu->nr_arch_fixed_counters) - 1) << INTEL_PMC_IDX_FIXED));
+ (((1ull << pmu->nr_arch_fixed_counters) - 1) << KVM_FIXED_PMC_BASE_IDX));
pmu->global_ctrl_mask = counter_mask;
/*
@@ -593,7 +548,7 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
pmu->reserved_bits &= ~ICL_EVENTSEL_ADAPTIVE;
for (i = 0; i < pmu->nr_arch_fixed_counters; i++) {
pmu->fixed_ctr_ctrl_mask &=
- ~(1ULL << (INTEL_PMC_IDX_FIXED + i * 4));
+ ~(1ULL << (KVM_FIXED_PMC_BASE_IDX + i * 4));
}
pmu->pebs_data_cfg_mask = ~0xff00000full;
} else {
@@ -619,8 +574,9 @@ static void intel_pmu_init(struct kvm_vcpu *vcpu)
for (i = 0; i < KVM_PMC_MAX_FIXED; i++) {
pmu->fixed_counters[i].type = KVM_PMC_FIXED;
pmu->fixed_counters[i].vcpu = vcpu;
- pmu->fixed_counters[i].idx = i + INTEL_PMC_IDX_FIXED;
+ pmu->fixed_counters[i].idx = i + KVM_FIXED_PMC_BASE_IDX;
pmu->fixed_counters[i].current_config = 0;
+ pmu->fixed_counters[i].eventsel = intel_get_fixed_pmc_eventsel(i);
}
lbr_desc->records.nr = 0;
@@ -748,11 +704,8 @@ void intel_pmu_cross_mapped_check(struct kvm_pmu *pmu)
struct kvm_pmc *pmc = NULL;
int bit, hw_idx;
- for_each_set_bit(bit, (unsigned long *)&pmu->global_ctrl,
- X86_PMC_IDX_MAX) {
- pmc = intel_pmc_idx_to_pmc(pmu, bit);
-
- if (!pmc || !pmc_speculative_in_use(pmc) ||
+ kvm_for_each_pmc(pmu, pmc, bit, (unsigned long *)&pmu->global_ctrl) {
+ if (!pmc_speculative_in_use(pmc) ||
!pmc_is_globally_enabled(pmc) || !pmc->perf_event)
continue;
@@ -767,11 +720,8 @@ void intel_pmu_cross_mapped_check(struct kvm_pmu *pmu)
}
struct kvm_pmu_ops intel_pmu_ops __initdata = {
- .hw_event_available = intel_hw_event_available,
- .pmc_idx_to_pmc = intel_pmc_idx_to_pmc,
.rdpmc_ecx_to_pmc = intel_rdpmc_ecx_to_pmc,
.msr_idx_to_pmc = intel_msr_idx_to_pmc,
- .is_valid_rdpmc_ecx = intel_is_valid_rdpmc_ecx,
.is_valid_msr = intel_is_valid_msr,
.get_msr = intel_pmu_get_msr,
.set_msr = intel_pmu_set_msr,
diff --git a/arch/x86/kvm/vmx/vmenter.S b/arch/x86/kvm/vmx/vmenter.S
index 2bfbf758d061..f6986dee6f8c 100644
--- a/arch/x86/kvm/vmx/vmenter.S
+++ b/arch/x86/kvm/vmx/vmenter.S
@@ -275,6 +275,8 @@ SYM_INNER_LABEL_ALIGN(vmx_vmexit, SYM_L_GLOBAL)
call vmx_spec_ctrl_restore_host
+ CLEAR_BRANCH_HISTORY_VMEXIT
+
/* Put return value in AX */
mov %_ASM_BX, %_ASM_AX
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 88a4ff200d04..c37a89eda90f 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -38,6 +38,7 @@
#include <asm/desc.h>
#include <asm/fpu/api.h>
#include <asm/fpu/xstate.h>
+#include <asm/fred.h>
#include <asm/idtentry.h>
#include <asm/io.h>
#include <asm/irq_remapping.h>
@@ -49,6 +50,8 @@
#include <asm/spec-ctrl.h>
#include <asm/vmx.h>
+#include <trace/events/ipi.h>
+
#include "capabilities.h"
#include "cpuid.h"
#include "hyperv.h"
@@ -159,7 +162,7 @@ module_param(allow_smaller_maxphyaddr, bool, S_IRUGO);
/*
* List of MSRs that can be directly passed to the guest.
- * In addition to these x2apic and PT MSRs are handled specially.
+ * In addition to these x2apic, PT and LBR MSRs are handled specially.
*/
static u32 vmx_possible_passthrough_msrs[MAX_POSSIBLE_PASSTHROUGH_MSRS] = {
MSR_IA32_SPEC_CTRL,
@@ -667,25 +670,14 @@ static inline bool cpu_need_virtualize_apic_accesses(struct kvm_vcpu *vcpu)
return flexpriority_enabled && lapic_in_kernel(vcpu);
}
-static int possible_passthrough_msr_slot(u32 msr)
+static int vmx_get_passthrough_msr_slot(u32 msr)
{
- u32 i;
-
- for (i = 0; i < ARRAY_SIZE(vmx_possible_passthrough_msrs); i++)
- if (vmx_possible_passthrough_msrs[i] == msr)
- return i;
-
- return -ENOENT;
-}
-
-static bool is_valid_passthrough_msr(u32 msr)
-{
- bool r;
+ int i;
switch (msr) {
case 0x800 ... 0x8ff:
/* x2APIC MSRs. These are handled in vmx_update_msr_bitmap_x2apic() */
- return true;
+ return -ENOENT;
case MSR_IA32_RTIT_STATUS:
case MSR_IA32_RTIT_OUTPUT_BASE:
case MSR_IA32_RTIT_OUTPUT_MASK:
@@ -700,14 +692,16 @@ static bool is_valid_passthrough_msr(u32 msr)
case MSR_LBR_CORE_FROM ... MSR_LBR_CORE_FROM + 8:
case MSR_LBR_CORE_TO ... MSR_LBR_CORE_TO + 8:
/* LBR MSRs. These are handled in vmx_update_intercept_for_lbr_msrs() */
- return true;
+ return -ENOENT;
}
- r = possible_passthrough_msr_slot(msr) != -ENOENT;
-
- WARN(!r, "Invalid MSR %x, please adapt vmx_possible_passthrough_msrs[]", msr);
+ for (i = 0; i < ARRAY_SIZE(vmx_possible_passthrough_msrs); i++) {
+ if (vmx_possible_passthrough_msrs[i] == msr)
+ return i;
+ }
- return r;
+ WARN(1, "Invalid MSR %x, please adapt vmx_possible_passthrough_msrs[]", msr);
+ return -ENOENT;
}
struct vmx_uret_msr *vmx_find_uret_msr(struct vcpu_vmx *vmx, u32 msr)
@@ -1290,8 +1284,6 @@ void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
u16 fs_sel, gs_sel;
int i;
- vmx->req_immediate_exit = false;
-
/*
* Note that guest MSRs to be saved/restored can also be changed
* when guest state is loaded. This happens when guest transitions
@@ -3963,6 +3955,7 @@ void vmx_disable_intercept_for_msr(struct kvm_vcpu *vcpu, u32 msr, int type)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
unsigned long *msr_bitmap = vmx->vmcs01.msr_bitmap;
+ int idx;
if (!cpu_has_vmx_msr_bitmap())
return;
@@ -3972,16 +3965,13 @@ void vmx_disable_intercept_for_msr(struct kvm_vcpu *vcpu, u32 msr, int type)
/*
* Mark the desired intercept state in shadow bitmap, this is needed
* for resync when the MSR filters change.
- */
- if (is_valid_passthrough_msr(msr)) {
- int idx = possible_passthrough_msr_slot(msr);
-
- if (idx != -ENOENT) {
- if (type & MSR_TYPE_R)
- clear_bit(idx, vmx->shadow_msr_intercept.read);
- if (type & MSR_TYPE_W)
- clear_bit(idx, vmx->shadow_msr_intercept.write);
- }
+ */
+ idx = vmx_get_passthrough_msr_slot(msr);
+ if (idx >= 0) {
+ if (type & MSR_TYPE_R)
+ clear_bit(idx, vmx->shadow_msr_intercept.read);
+ if (type & MSR_TYPE_W)
+ clear_bit(idx, vmx->shadow_msr_intercept.write);
}
if ((type & MSR_TYPE_R) &&
@@ -4007,6 +3997,7 @@ void vmx_enable_intercept_for_msr(struct kvm_vcpu *vcpu, u32 msr, int type)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
unsigned long *msr_bitmap = vmx->vmcs01.msr_bitmap;
+ int idx;
if (!cpu_has_vmx_msr_bitmap())
return;
@@ -4016,16 +4007,13 @@ void vmx_enable_intercept_for_msr(struct kvm_vcpu *vcpu, u32 msr, int type)
/*
* Mark the desired intercept state in shadow bitmap, this is needed
* for resync when the MSR filter changes.
- */
- if (is_valid_passthrough_msr(msr)) {
- int idx = possible_passthrough_msr_slot(msr);
-
- if (idx != -ENOENT) {
- if (type & MSR_TYPE_R)
- set_bit(idx, vmx->shadow_msr_intercept.read);
- if (type & MSR_TYPE_W)
- set_bit(idx, vmx->shadow_msr_intercept.write);
- }
+ */
+ idx = vmx_get_passthrough_msr_slot(msr);
+ if (idx >= 0) {
+ if (type & MSR_TYPE_R)
+ set_bit(idx, vmx->shadow_msr_intercept.read);
+ if (type & MSR_TYPE_W)
+ set_bit(idx, vmx->shadow_msr_intercept.write);
}
if (type & MSR_TYPE_R)
@@ -4136,6 +4124,9 @@ static void vmx_msr_filter_changed(struct kvm_vcpu *vcpu)
struct vcpu_vmx *vmx = to_vmx(vcpu);
u32 i;
+ if (!cpu_has_vmx_msr_bitmap())
+ return;
+
/*
* Redo intercept permissions for MSRs that KVM is passing through to
* the guest. Disabling interception will check the new MSR filter and
@@ -5575,10 +5566,7 @@ static int handle_dr(struct kvm_vcpu *vcpu)
reg = DEBUG_REG_ACCESS_REG(exit_qualification);
if (exit_qualification & TYPE_MOV_FROM_DR) {
- unsigned long val;
-
- kvm_get_dr(vcpu, dr, &val);
- kvm_register_write(vcpu, reg, val);
+ kvm_register_write(vcpu, reg, kvm_get_dr(vcpu, dr));
err = 0;
} else {
err = kvm_set_dr(vcpu, dr, kvm_register_read(vcpu, reg));
@@ -6000,22 +5988,46 @@ static int handle_pml_full(struct kvm_vcpu *vcpu)
return 1;
}
-static fastpath_t handle_fastpath_preemption_timer(struct kvm_vcpu *vcpu)
+static fastpath_t handle_fastpath_preemption_timer(struct kvm_vcpu *vcpu,
+ bool force_immediate_exit)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
- if (!vmx->req_immediate_exit &&
- !unlikely(vmx->loaded_vmcs->hv_timer_soft_disabled)) {
- kvm_lapic_expired_hv_timer(vcpu);
+ /*
+ * In the *extremely* unlikely scenario that this is a spurious VM-Exit
+ * due to the timer expiring while it was "soft" disabled, just eat the
+ * exit and re-enter the guest.
+ */
+ if (unlikely(vmx->loaded_vmcs->hv_timer_soft_disabled))
return EXIT_FASTPATH_REENTER_GUEST;
- }
- return EXIT_FASTPATH_NONE;
+ /*
+ * If the timer expired because KVM used it to force an immediate exit,
+ * then mission accomplished.
+ */
+ if (force_immediate_exit)
+ return EXIT_FASTPATH_EXIT_HANDLED;
+
+ /*
+ * If L2 is active, go down the slow path as emulating the guest timer
+ * expiration likely requires synthesizing a nested VM-Exit.
+ */
+ if (is_guest_mode(vcpu))
+ return EXIT_FASTPATH_NONE;
+
+ kvm_lapic_expired_hv_timer(vcpu);
+ return EXIT_FASTPATH_REENTER_GUEST;
}
static int handle_preemption_timer(struct kvm_vcpu *vcpu)
{
- handle_fastpath_preemption_timer(vcpu);
+ /*
+ * This non-fastpath handler is reached if and only if the preemption
+ * timer was being used to emulate a guest timer while L2 is active.
+ * All other scenarios are supposed to be handled in the fastpath.
+ */
+ WARN_ON_ONCE(!is_guest_mode(vcpu));
+ kvm_lapic_expired_hv_timer(vcpu);
return 1;
}
@@ -6518,7 +6530,7 @@ static int __vmx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath)
vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_DELIVERY_EV;
vcpu->run->internal.data[0] = vectoring_info;
vcpu->run->internal.data[1] = exit_reason.full;
- vcpu->run->internal.data[2] = vcpu->arch.exit_qualification;
+ vcpu->run->internal.data[2] = vmx_get_exit_qual(vcpu);
if (exit_reason.basic == EXIT_REASON_EPT_MISCONFIG) {
vcpu->run->internal.data[ndata++] =
vmcs_read64(GUEST_PHYSICAL_ADDRESS);
@@ -6552,7 +6564,7 @@ static int __vmx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath)
if (exit_reason.basic >= kvm_vmx_max_exit_handlers)
goto unexpected_vmexit;
-#ifdef CONFIG_RETPOLINE
+#ifdef CONFIG_MITIGATION_RETPOLINE
if (exit_reason.basic == EXIT_REASON_MSR_WRITE)
return kvm_emulate_wrmsr(vcpu);
else if (exit_reason.basic == EXIT_REASON_PREEMPTION_TIMER)
@@ -6969,14 +6981,16 @@ static void handle_external_interrupt_irqoff(struct kvm_vcpu *vcpu)
{
u32 intr_info = vmx_get_intr_info(vcpu);
unsigned int vector = intr_info & INTR_INFO_VECTOR_MASK;
- gate_desc *desc = (gate_desc *)host_idt_base + vector;
if (KVM_BUG(!is_external_intr(intr_info), vcpu->kvm,
"unexpected VM-Exit interrupt info: 0x%x", intr_info))
return;
kvm_before_interrupt(vcpu, KVM_HANDLING_IRQ);
- vmx_do_interrupt_irqoff(gate_offset(desc));
+ if (cpu_feature_enabled(X86_FEATURE_FRED))
+ fred_entry_from_kvm(EVENT_TYPE_EXTINT, vector);
+ else
+ vmx_do_interrupt_irqoff(gate_offset((gate_desc *)host_idt_base + vector));
kvm_after_interrupt(vcpu);
vcpu->arch.at_instruction_boundary = true;
@@ -7155,13 +7169,13 @@ static void atomic_switch_perf_msrs(struct vcpu_vmx *vmx)
msrs[i].host, false);
}
-static void vmx_update_hv_timer(struct kvm_vcpu *vcpu)
+static void vmx_update_hv_timer(struct kvm_vcpu *vcpu, bool force_immediate_exit)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
u64 tscl;
u32 delta_tsc;
- if (vmx->req_immediate_exit) {
+ if (force_immediate_exit) {
vmcs_write32(VMX_PREEMPTION_TIMER_VALUE, 0);
vmx->loaded_vmcs->hv_timer_soft_disabled = false;
} else if (vmx->hv_deadline_tsc != -1) {
@@ -7214,13 +7228,22 @@ void noinstr vmx_spec_ctrl_restore_host(struct vcpu_vmx *vmx,
barrier_nospec();
}
-static fastpath_t vmx_exit_handlers_fastpath(struct kvm_vcpu *vcpu)
+static fastpath_t vmx_exit_handlers_fastpath(struct kvm_vcpu *vcpu,
+ bool force_immediate_exit)
{
+ /*
+ * If L2 is active, some VMX preemption timer exits can be handled in
+ * the fastpath even, all other exits must use the slow path.
+ */
+ if (is_guest_mode(vcpu) &&
+ to_vmx(vcpu)->exit_reason.basic != EXIT_REASON_PREEMPTION_TIMER)
+ return EXIT_FASTPATH_NONE;
+
switch (to_vmx(vcpu)->exit_reason.basic) {
case EXIT_REASON_MSR_WRITE:
return handle_fastpath_set_msr_irqoff(vcpu);
case EXIT_REASON_PREEMPTION_TIMER:
- return handle_fastpath_preemption_timer(vcpu);
+ return handle_fastpath_preemption_timer(vcpu, force_immediate_exit);
default:
return EXIT_FASTPATH_NONE;
}
@@ -7272,7 +7295,10 @@ static noinstr void vmx_vcpu_enter_exit(struct kvm_vcpu *vcpu,
if ((u16)vmx->exit_reason.basic == EXIT_REASON_EXCEPTION_NMI &&
is_nmi(vmx_get_intr_info(vcpu))) {
kvm_before_interrupt(vcpu, KVM_HANDLING_NMI);
- vmx_do_nmi_irqoff();
+ if (cpu_feature_enabled(X86_FEATURE_FRED))
+ fred_entry_from_kvm(EVENT_TYPE_NMI, NMI_VECTOR);
+ else
+ vmx_do_nmi_irqoff();
kvm_after_interrupt(vcpu);
}
@@ -7280,7 +7306,7 @@ out:
guest_state_exit_irqoff();
}
-static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu)
+static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu, bool force_immediate_exit)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
unsigned long cr3, cr4;
@@ -7307,7 +7333,7 @@ static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu)
return EXIT_FASTPATH_NONE;
}
- trace_kvm_entry(vcpu);
+ trace_kvm_entry(vcpu, force_immediate_exit);
if (vmx->ple_window_dirty) {
vmx->ple_window_dirty = false;
@@ -7366,7 +7392,9 @@ static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu)
vmx_passthrough_lbr_msrs(vcpu);
if (enable_preemption_timer)
- vmx_update_hv_timer(vcpu);
+ vmx_update_hv_timer(vcpu, force_immediate_exit);
+ else if (force_immediate_exit)
+ smp_send_reschedule(vcpu->cpu);
kvm_wait_lapic_expire(vcpu);
@@ -7430,10 +7458,7 @@ static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu)
vmx_recover_nmi_blocking(vmx);
vmx_complete_interrupts(vmx);
- if (is_guest_mode(vcpu))
- return EXIT_FASTPATH_NONE;
-
- return vmx_exit_handlers_fastpath(vcpu);
+ return vmx_exit_handlers_fastpath(vcpu, force_immediate_exit);
}
static void vmx_vcpu_free(struct kvm_vcpu *vcpu)
@@ -7913,11 +7938,6 @@ static __init void vmx_set_cpu_caps(void)
kvm_cpu_cap_check_and_set(X86_FEATURE_WAITPKG);
}
-static void vmx_request_immediate_exit(struct kvm_vcpu *vcpu)
-{
- to_vmx(vcpu)->req_immediate_exit = true;
-}
-
static int vmx_check_intercept_io(struct kvm_vcpu *vcpu,
struct x86_instruction_info *info)
{
@@ -8370,8 +8390,6 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = {
.check_intercept = vmx_check_intercept,
.handle_exit_irqoff = vmx_handle_exit_irqoff,
- .request_immediate_exit = vmx_request_immediate_exit,
-
.sched_in = vmx_sched_in,
.cpu_dirty_log_size = PML_ENTITY_NUM,
@@ -8631,7 +8649,6 @@ static __init int hardware_setup(void)
if (!enable_preemption_timer) {
vmx_x86_ops.set_hv_timer = NULL;
vmx_x86_ops.cancel_hv_timer = NULL;
- vmx_x86_ops.request_immediate_exit = __kvm_request_immediate_exit;
}
kvm_caps.supported_mce_cap |= MCG_LMCE_P;
diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h
index e3b0985bb74a..65786dbe7d60 100644
--- a/arch/x86/kvm/vmx/vmx.h
+++ b/arch/x86/kvm/vmx/vmx.h
@@ -332,8 +332,6 @@ struct vcpu_vmx {
unsigned int ple_window;
bool ple_window_dirty;
- bool req_immediate_exit;
-
/* Support for PML */
#define PML_ENTITY_NUM 512
struct page *pml_pg;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index e02cc710f56d..984ea2089efc 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1399,22 +1399,19 @@ int kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val)
}
EXPORT_SYMBOL_GPL(kvm_set_dr);
-void kvm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *val)
+unsigned long kvm_get_dr(struct kvm_vcpu *vcpu, int dr)
{
size_t size = ARRAY_SIZE(vcpu->arch.db);
switch (dr) {
case 0 ... 3:
- *val = vcpu->arch.db[array_index_nospec(dr, size)];
- break;
+ return vcpu->arch.db[array_index_nospec(dr, size)];
case 4:
case 6:
- *val = vcpu->arch.dr6;
- break;
+ return vcpu->arch.dr6;
case 5:
default: /* 7 */
- *val = vcpu->arch.dr7;
- break;
+ return vcpu->arch.dr7;
}
}
EXPORT_SYMBOL_GPL(kvm_get_dr);
@@ -1623,7 +1620,8 @@ static bool kvm_is_immutable_feature_msr(u32 msr)
ARCH_CAP_SKIP_VMENTRY_L1DFLUSH | ARCH_CAP_SSB_NO | ARCH_CAP_MDS_NO | \
ARCH_CAP_PSCHANGE_MC_NO | ARCH_CAP_TSX_CTRL_MSR | ARCH_CAP_TAA_NO | \
ARCH_CAP_SBDR_SSDP_NO | ARCH_CAP_FBSDP_NO | ARCH_CAP_PSDP_NO | \
- ARCH_CAP_FB_CLEAR | ARCH_CAP_RRSBA | ARCH_CAP_PBRSB_NO | ARCH_CAP_GDS_NO)
+ ARCH_CAP_FB_CLEAR | ARCH_CAP_RRSBA | ARCH_CAP_PBRSB_NO | ARCH_CAP_GDS_NO | \
+ ARCH_CAP_RFDS_NO | ARCH_CAP_RFDS_CLEAR | ARCH_CAP_BHI_NO)
static u64 kvm_get_arch_capabilities(void)
{
@@ -1655,6 +1653,8 @@ static u64 kvm_get_arch_capabilities(void)
data |= ARCH_CAP_SSB_NO;
if (!boot_cpu_has_bug(X86_BUG_MDS))
data |= ARCH_CAP_MDS_NO;
+ if (!boot_cpu_has_bug(X86_BUG_RFDS))
+ data |= ARCH_CAP_RFDS_NO;
if (!boot_cpu_has(X86_FEATURE_RTM)) {
/*
@@ -2857,7 +2857,11 @@ static inline u64 vgettsc(struct pvclock_clock *clock, u64 *tsc_timestamp,
return v * clock->mult;
}
-static int do_monotonic_raw(s64 *t, u64 *tsc_timestamp)
+/*
+ * As with get_kvmclock_base_ns(), this counts from boot time, at the
+ * frequency of CLOCK_MONOTONIC_RAW (hence adding gtos->offs_boot).
+ */
+static int do_kvmclock_base(s64 *t, u64 *tsc_timestamp)
{
struct pvclock_gtod_data *gtod = &pvclock_gtod_data;
unsigned long seq;
@@ -2876,6 +2880,29 @@ static int do_monotonic_raw(s64 *t, u64 *tsc_timestamp)
return mode;
}
+/*
+ * This calculates CLOCK_MONOTONIC at the time of the TSC snapshot, with
+ * no boot time offset.
+ */
+static int do_monotonic(s64 *t, u64 *tsc_timestamp)
+{
+ struct pvclock_gtod_data *gtod = &pvclock_gtod_data;
+ unsigned long seq;
+ int mode;
+ u64 ns;
+
+ do {
+ seq = read_seqcount_begin(&gtod->seq);
+ ns = gtod->clock.base_cycles;
+ ns += vgettsc(&gtod->clock, tsc_timestamp, &mode);
+ ns >>= gtod->clock.shift;
+ ns += ktime_to_ns(gtod->clock.offset);
+ } while (unlikely(read_seqcount_retry(&gtod->seq, seq)));
+ *t = ns;
+
+ return mode;
+}
+
static int do_realtime(struct timespec64 *ts, u64 *tsc_timestamp)
{
struct pvclock_gtod_data *gtod = &pvclock_gtod_data;
@@ -2897,18 +2924,42 @@ static int do_realtime(struct timespec64 *ts, u64 *tsc_timestamp)
return mode;
}
-/* returns true if host is using TSC based clocksource */
+/*
+ * Calculates the kvmclock_base_ns (CLOCK_MONOTONIC_RAW + boot time) and
+ * reports the TSC value from which it do so. Returns true if host is
+ * using TSC based clocksource.
+ */
static bool kvm_get_time_and_clockread(s64 *kernel_ns, u64 *tsc_timestamp)
{
/* checked again under seqlock below */
if (!gtod_is_based_on_tsc(pvclock_gtod_data.clock.vclock_mode))
return false;
- return gtod_is_based_on_tsc(do_monotonic_raw(kernel_ns,
- tsc_timestamp));
+ return gtod_is_based_on_tsc(do_kvmclock_base(kernel_ns,
+ tsc_timestamp));
}
-/* returns true if host is using TSC based clocksource */
+/*
+ * Calculates CLOCK_MONOTONIC and reports the TSC value from which it did
+ * so. Returns true if host is using TSC based clocksource.
+ */
+bool kvm_get_monotonic_and_clockread(s64 *kernel_ns, u64 *tsc_timestamp)
+{
+ /* checked again under seqlock below */
+ if (!gtod_is_based_on_tsc(pvclock_gtod_data.clock.vclock_mode))
+ return false;
+
+ return gtod_is_based_on_tsc(do_monotonic(kernel_ns,
+ tsc_timestamp));
+}
+
+/*
+ * Calculates CLOCK_REALTIME and reports the TSC value from which it did
+ * so. Returns true if host is using TSC based clocksource.
+ *
+ * DO NOT USE this for anything related to migration. You want CLOCK_TAI
+ * for that.
+ */
static bool kvm_get_walltime_and_clockread(struct timespec64 *ts,
u64 *tsc_timestamp)
{
@@ -3155,7 +3206,7 @@ static void kvm_setup_guest_pvclock(struct kvm_vcpu *v,
guest_hv_clock->version = ++vcpu->hv_clock.version;
- mark_page_dirty_in_slot(v->kvm, gpc->memslot, gpc->gpa >> PAGE_SHIFT);
+ kvm_gpc_mark_dirty_in_slot(gpc);
read_unlock_irqrestore(&gpc->lock, flags);
trace_kvm_pvclock_update(v->vcpu_id, &vcpu->hv_clock);
@@ -4677,7 +4728,8 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
KVM_XEN_HVM_CONFIG_SHARED_INFO |
KVM_XEN_HVM_CONFIG_EVTCHN_2LEVEL |
KVM_XEN_HVM_CONFIG_EVTCHN_SEND |
- KVM_XEN_HVM_CONFIG_PVCLOCK_TSC_UNSTABLE;
+ KVM_XEN_HVM_CONFIG_PVCLOCK_TSC_UNSTABLE |
+ KVM_XEN_HVM_CONFIG_SHARED_INFO_HVA;
if (sched_info_on())
r |= KVM_XEN_HVM_CONFIG_RUNSTATE |
KVM_XEN_HVM_CONFIG_RUNSTATE_UPDATE_FLAG;
@@ -5061,8 +5113,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
int idx;
if (vcpu->preempted) {
- if (!vcpu->arch.guest_state_protected)
- vcpu->arch.preempted_in_kernel = !static_call(kvm_x86_get_cpl)(vcpu);
+ vcpu->arch.preempted_in_kernel = kvm_arch_vcpu_in_kernel(vcpu);
/*
* Take the srcu lock as memslots will be accessed to check the gfn
@@ -5509,18 +5560,23 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
static void kvm_vcpu_ioctl_x86_get_debugregs(struct kvm_vcpu *vcpu,
struct kvm_debugregs *dbgregs)
{
- unsigned long val;
+ unsigned int i;
memset(dbgregs, 0, sizeof(*dbgregs));
- memcpy(dbgregs->db, vcpu->arch.db, sizeof(vcpu->arch.db));
- kvm_get_dr(vcpu, 6, &val);
- dbgregs->dr6 = val;
+
+ BUILD_BUG_ON(ARRAY_SIZE(vcpu->arch.db) != ARRAY_SIZE(dbgregs->db));
+ for (i = 0; i < ARRAY_SIZE(vcpu->arch.db); i++)
+ dbgregs->db[i] = vcpu->arch.db[i];
+
+ dbgregs->dr6 = vcpu->arch.dr6;
dbgregs->dr7 = vcpu->arch.dr7;
}
static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
struct kvm_debugregs *dbgregs)
{
+ unsigned int i;
+
if (dbgregs->flags)
return -EINVAL;
@@ -5529,7 +5585,9 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
if (!kvm_dr7_valid(dbgregs->dr7))
return -EINVAL;
- memcpy(vcpu->arch.db, dbgregs->db, sizeof(vcpu->arch.db));
+ for (i = 0; i < ARRAY_SIZE(vcpu->arch.db); i++)
+ vcpu->arch.db[i] = dbgregs->db[i];
+
kvm_update_dr0123(vcpu);
vcpu->arch.dr6 = dbgregs->dr6;
vcpu->arch.dr7 = dbgregs->dr7;
@@ -8177,10 +8235,9 @@ static void emulator_wbinvd(struct x86_emulate_ctxt *ctxt)
kvm_emulate_wbinvd_noskip(emul_to_vcpu(ctxt));
}
-static void emulator_get_dr(struct x86_emulate_ctxt *ctxt, int dr,
- unsigned long *dest)
+static unsigned long emulator_get_dr(struct x86_emulate_ctxt *ctxt, int dr)
{
- kvm_get_dr(emul_to_vcpu(ctxt), dr, dest);
+ return kvm_get_dr(emul_to_vcpu(ctxt), dr);
}
static int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr,
@@ -8402,12 +8459,9 @@ static int emulator_get_msr(struct x86_emulate_ctxt *ctxt,
return kvm_get_msr(emul_to_vcpu(ctxt), msr_index, pdata);
}
-static int emulator_check_pmc(struct x86_emulate_ctxt *ctxt,
- u32 pmc)
+static int emulator_check_rdpmc_early(struct x86_emulate_ctxt *ctxt, u32 pmc)
{
- if (kvm_pmu_is_valid_rdpmc_ecx(emul_to_vcpu(ctxt), pmc))
- return 0;
- return -EINVAL;
+ return kvm_pmu_check_rdpmc_early(emul_to_vcpu(ctxt), pmc);
}
static int emulator_read_pmc(struct x86_emulate_ctxt *ctxt,
@@ -8539,7 +8593,7 @@ static const struct x86_emulate_ops emulate_ops = {
.set_msr_with_filter = emulator_set_msr_with_filter,
.get_msr_with_filter = emulator_get_msr_with_filter,
.get_msr = emulator_get_msr,
- .check_pmc = emulator_check_pmc,
+ .check_rdpmc_early = emulator_check_rdpmc_early,
.read_pmc = emulator_read_pmc,
.halt = emulator_halt,
.wbinvd = emulator_wbinvd,
@@ -8800,31 +8854,24 @@ static bool reexecute_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
kvm_release_pfn_clean(pfn);
- /* The instructions are well-emulated on direct mmu. */
- if (vcpu->arch.mmu->root_role.direct) {
- unsigned int indirect_shadow_pages;
-
- write_lock(&vcpu->kvm->mmu_lock);
- indirect_shadow_pages = vcpu->kvm->arch.indirect_shadow_pages;
- write_unlock(&vcpu->kvm->mmu_lock);
-
- if (indirect_shadow_pages)
- kvm_mmu_unprotect_page(vcpu->kvm, gpa_to_gfn(gpa));
-
- return true;
- }
-
/*
- * if emulation was due to access to shadowed page table
- * and it failed try to unshadow page and re-enter the
- * guest to let CPU execute the instruction.
+ * If emulation may have been triggered by a write to a shadowed page
+ * table, unprotect the gfn (zap any relevant SPTEs) and re-enter the
+ * guest to let the CPU re-execute the instruction in the hope that the
+ * CPU can cleanly execute the instruction that KVM failed to emulate.
*/
- kvm_mmu_unprotect_page(vcpu->kvm, gpa_to_gfn(gpa));
+ if (vcpu->kvm->arch.indirect_shadow_pages)
+ kvm_mmu_unprotect_page(vcpu->kvm, gpa_to_gfn(gpa));
/*
- * If the access faults on its page table, it can not
- * be fixed by unprotecting shadow page and it should
- * be reported to userspace.
+ * If the failed instruction faulted on an access to page tables that
+ * are used to translate any part of the instruction, KVM can't resolve
+ * the issue by unprotecting the gfn, as zapping the shadow page will
+ * result in the instruction taking a !PRESENT page fault and thus put
+ * the vCPU into an infinite loop of page faults. E.g. KVM will create
+ * a SPTE and write-protect the gfn to resolve the !PRESENT fault, and
+ * then zap the SPTE to unprotect the gfn, and then do it all over
+ * again. Report the error to userspace.
*/
return !(emulation_type & EMULTYPE_WRITE_PF_TO_SP);
}
@@ -8919,7 +8966,7 @@ int kvm_skip_emulated_instruction(struct kvm_vcpu *vcpu)
if (unlikely(!r))
return 0;
- kvm_pmu_trigger_event(vcpu, PERF_COUNT_HW_INSTRUCTIONS);
+ kvm_pmu_trigger_event(vcpu, kvm_pmu_eventsel.INSTRUCTIONS_RETIRED);
/*
* rflags is the old, "raw" value of the flags. The new value has
@@ -9232,9 +9279,9 @@ writeback:
*/
if (!ctxt->have_exception ||
exception_type(ctxt->exception.vector) == EXCPT_TRAP) {
- kvm_pmu_trigger_event(vcpu, PERF_COUNT_HW_INSTRUCTIONS);
+ kvm_pmu_trigger_event(vcpu, kvm_pmu_eventsel.INSTRUCTIONS_RETIRED);
if (ctxt->is_branch)
- kvm_pmu_trigger_event(vcpu, PERF_COUNT_HW_BRANCH_INSTRUCTIONS);
+ kvm_pmu_trigger_event(vcpu, kvm_pmu_eventsel.BRANCH_INSTRUCTIONS_RETIRED);
kvm_rip_write(vcpu, ctxt->eip);
if (r && (ctxt->tf || (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)))
r = kvm_vcpu_do_singlestep(vcpu);
@@ -9645,11 +9692,13 @@ static void kvm_x86_check_cpu_compat(void *ret)
*(int *)ret = kvm_x86_check_processor_compatibility();
}
-static int __kvm_x86_vendor_init(struct kvm_x86_init_ops *ops)
+int kvm_x86_vendor_init(struct kvm_x86_init_ops *ops)
{
u64 host_pat;
int r, cpu;
+ guard(mutex)(&vendor_module_lock);
+
if (kvm_x86_ops.hardware_enable) {
pr_err("already loaded vendor module '%s'\n", kvm_x86_ops.name);
return -EEXIST;
@@ -9779,17 +9828,6 @@ out_free_x86_emulator_cache:
kmem_cache_destroy(x86_emulator_cache);
return r;
}
-
-int kvm_x86_vendor_init(struct kvm_x86_init_ops *ops)
-{
- int r;
-
- mutex_lock(&vendor_module_lock);
- r = __kvm_x86_vendor_init(ops);
- mutex_unlock(&vendor_module_lock);
-
- return r;
-}
EXPORT_SYMBOL_GPL(kvm_x86_vendor_init);
void kvm_x86_vendor_exit(void)
@@ -10686,12 +10724,6 @@ static void kvm_vcpu_reload_apic_access_page(struct kvm_vcpu *vcpu)
static_call_cond(kvm_x86_set_apic_access_page_addr)(vcpu);
}
-void __kvm_request_immediate_exit(struct kvm_vcpu *vcpu)
-{
- smp_send_reschedule(vcpu->cpu);
-}
-EXPORT_SYMBOL_GPL(__kvm_request_immediate_exit);
-
/*
* Called within kvm->srcu read side.
* Returns 1 to let vcpu_run() continue the guest execution loop without
@@ -10941,10 +10973,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
goto cancel_injection;
}
- if (req_immediate_exit) {
+ if (req_immediate_exit)
kvm_make_request(KVM_REQ_EVENT, vcpu);
- static_call(kvm_x86_request_immediate_exit)(vcpu);
- }
fpregs_assert_state_consistent();
if (test_thread_flag(TIF_NEED_FPU_LOAD))
@@ -10975,7 +11005,7 @@ 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);
+ exit_fastpath = static_call(kvm_x86_vcpu_run)(vcpu, req_immediate_exit);
if (likely(exit_fastpath != EXIT_FASTPATH_REENTER_GUEST))
break;
@@ -12062,7 +12092,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
vcpu->arch.regs_avail = ~0;
vcpu->arch.regs_dirty = ~0;
- kvm_gpc_init(&vcpu->arch.pv_time, vcpu->kvm, vcpu, KVM_HOST_USES_PFN);
+ kvm_gpc_init(&vcpu->arch.pv_time, vcpu->kvm);
if (!irqchip_in_kernel(vcpu->kvm) || kvm_vcpu_is_reset_bsp(vcpu))
vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
@@ -12073,27 +12103,9 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
if (r < 0)
return r;
- if (irqchip_in_kernel(vcpu->kvm)) {
- r = kvm_create_lapic(vcpu, lapic_timer_advance_ns);
- if (r < 0)
- goto fail_mmu_destroy;
-
- /*
- * Defer evaluating inhibits until the vCPU is first run, as
- * this vCPU will not get notified of any changes until this
- * vCPU is visible to other vCPUs (marked online and added to
- * the set of vCPUs). Opportunistically mark APICv active as
- * VMX in particularly is highly unlikely to have inhibits.
- * Ignore the current per-VM APICv state so that vCPU creation
- * is guaranteed to run with a deterministic value, the request
- * will ensure the vCPU gets the correct state before VM-Entry.
- */
- if (enable_apicv) {
- vcpu->arch.apic->apicv_active = true;
- kvm_make_request(KVM_REQ_APICV_UPDATE, vcpu);
- }
- } else
- static_branch_inc(&kvm_has_noapic_vcpu);
+ r = kvm_create_lapic(vcpu, lapic_timer_advance_ns);
+ if (r < 0)
+ goto fail_mmu_destroy;
r = -ENOMEM;
@@ -12214,8 +12226,6 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
srcu_read_unlock(&vcpu->kvm->srcu, idx);
free_page((unsigned long)vcpu->arch.pio_data);
kvfree(vcpu->arch.cpuid_entries);
- if (!lapic_in_kernel(vcpu))
- static_branch_dec(&kvm_has_noapic_vcpu);
}
void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
@@ -12492,9 +12502,6 @@ bool kvm_vcpu_is_bsp(struct kvm_vcpu *vcpu)
return (vcpu->arch.apic_base & MSR_IA32_APICBASE_BSP) != 0;
}
-__read_mostly DEFINE_STATIC_KEY_FALSE(kvm_has_noapic_vcpu);
-EXPORT_SYMBOL_GPL(kvm_has_noapic_vcpu);
-
void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu)
{
struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
@@ -13097,11 +13104,13 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
bool kvm_arch_dy_has_pending_interrupt(struct kvm_vcpu *vcpu)
{
- if (kvm_vcpu_apicv_active(vcpu) &&
- static_call(kvm_x86_dy_apicv_has_pending_interrupt)(vcpu))
- return true;
+ return kvm_vcpu_apicv_active(vcpu) &&
+ static_call(kvm_x86_dy_apicv_has_pending_interrupt)(vcpu);
+}
- return false;
+bool kvm_arch_vcpu_preempted_in_kernel(struct kvm_vcpu *vcpu)
+{
+ return vcpu->arch.preempted_in_kernel;
}
bool kvm_arch_dy_runnable(struct kvm_vcpu *vcpu)
@@ -13124,9 +13133,6 @@ bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu)
if (vcpu->arch.guest_state_protected)
return true;
- if (vcpu != kvm_get_running_vcpu())
- return vcpu->arch.preempted_in_kernel;
-
return static_call(kvm_x86_get_cpl)(vcpu) == 0;
}
@@ -13921,9 +13927,6 @@ module_init(kvm_x86_init);
static void __exit kvm_x86_exit(void)
{
- /*
- * If module_init() is implemented, module_exit() must also be
- * implemented to allow module unload.
- */
+ WARN_ON_ONCE(static_branch_unlikely(&kvm_has_noapic_vcpu));
}
module_exit(kvm_x86_exit);
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index 2f7e19166658..a8b71803777b 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -294,6 +294,7 @@ void kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq, int inc_eip);
u64 get_kvmclock_ns(struct kvm *kvm);
uint64_t kvm_get_wall_clock_epoch(struct kvm *kvm);
+bool kvm_get_monotonic_and_clockread(s64 *kernel_ns, u64 *tsc_timestamp);
int kvm_read_guest_virt(struct kvm_vcpu *vcpu,
gva_t addr, void *val, unsigned int bytes,
@@ -431,12 +432,6 @@ static inline bool kvm_notify_vmexit_enabled(struct kvm *kvm)
return kvm->arch.notify_vmexit_flags & KVM_X86_NOTIFY_VMEXIT_ENABLED;
}
-enum kvm_intr_type {
- /* Values are arbitrary, but must be non-zero. */
- KVM_HANDLING_IRQ = 1,
- KVM_HANDLING_NMI,
-};
-
static __always_inline void kvm_before_interrupt(struct kvm_vcpu *vcpu,
enum kvm_intr_type intr)
{
diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c
index 4b4e738c6f1b..f65b35a05d91 100644
--- a/arch/x86/kvm/xen.c
+++ b/arch/x86/kvm/xen.c
@@ -10,7 +10,7 @@
#include "x86.h"
#include "xen.h"
#include "hyperv.h"
-#include "lapic.h"
+#include "irq.h"
#include <linux/eventfd.h>
#include <linux/kvm_host.h>
@@ -24,6 +24,7 @@
#include <xen/interface/sched.h>
#include <asm/xen/cpuid.h>
+#include <asm/pvclock.h>
#include "cpuid.h"
#include "trace.h"
@@ -34,41 +35,32 @@ static bool kvm_xen_hcall_evtchn_send(struct kvm_vcpu *vcpu, u64 param, u64 *r);
DEFINE_STATIC_KEY_DEFERRED_FALSE(kvm_xen_enabled, HZ);
-static int kvm_xen_shared_info_init(struct kvm *kvm, gfn_t gfn)
+static int kvm_xen_shared_info_init(struct kvm *kvm)
{
struct gfn_to_pfn_cache *gpc = &kvm->arch.xen.shinfo_cache;
struct pvclock_wall_clock *wc;
- gpa_t gpa = gfn_to_gpa(gfn);
u32 *wc_sec_hi;
u32 wc_version;
u64 wall_nsec;
int ret = 0;
int idx = srcu_read_lock(&kvm->srcu);
- if (gfn == KVM_XEN_INVALID_GFN) {
- kvm_gpc_deactivate(gpc);
- goto out;
- }
+ read_lock_irq(&gpc->lock);
+ while (!kvm_gpc_check(gpc, PAGE_SIZE)) {
+ read_unlock_irq(&gpc->lock);
- do {
- ret = kvm_gpc_activate(gpc, gpa, PAGE_SIZE);
+ ret = kvm_gpc_refresh(gpc, PAGE_SIZE);
if (ret)
goto out;
- /*
- * This code mirrors kvm_write_wall_clock() except that it writes
- * directly through the pfn cache and doesn't mark the page dirty.
- */
- wall_nsec = kvm_get_wall_clock_epoch(kvm);
-
- /* It could be invalid again already, so we need to check */
read_lock_irq(&gpc->lock);
+ }
- if (gpc->valid)
- break;
-
- read_unlock_irq(&gpc->lock);
- } while (1);
+ /*
+ * This code mirrors kvm_write_wall_clock() except that it writes
+ * directly through the pfn cache and doesn't mark the page dirty.
+ */
+ wall_nsec = kvm_get_wall_clock_epoch(kvm);
/* Paranoia checks on the 32-bit struct layout */
BUILD_BUG_ON(offsetof(struct compat_shared_info, wc) != 0x900);
@@ -158,8 +150,93 @@ static enum hrtimer_restart xen_timer_callback(struct hrtimer *timer)
return HRTIMER_NORESTART;
}
-static void kvm_xen_start_timer(struct kvm_vcpu *vcpu, u64 guest_abs, s64 delta_ns)
+static void kvm_xen_start_timer(struct kvm_vcpu *vcpu, u64 guest_abs,
+ bool linux_wa)
{
+ int64_t kernel_now, delta;
+ uint64_t guest_now;
+
+ /*
+ * The guest provides the requested timeout in absolute nanoseconds
+ * of the KVM clock — as *it* sees it, based on the scaled TSC and
+ * the pvclock information provided by KVM.
+ *
+ * The kernel doesn't support hrtimers based on CLOCK_MONOTONIC_RAW
+ * so use CLOCK_MONOTONIC. In the timescales covered by timers, the
+ * difference won't matter much as there is no cumulative effect.
+ *
+ * Calculate the time for some arbitrary point in time around "now"
+ * in terms of both kvmclock and CLOCK_MONOTONIC. Calculate the
+ * delta between the kvmclock "now" value and the guest's requested
+ * timeout, apply the "Linux workaround" described below, and add
+ * the resulting delta to the CLOCK_MONOTONIC "now" value, to get
+ * the absolute CLOCK_MONOTONIC time at which the timer should
+ * fire.
+ */
+ if (vcpu->arch.hv_clock.version && vcpu->kvm->arch.use_master_clock &&
+ static_cpu_has(X86_FEATURE_CONSTANT_TSC)) {
+ uint64_t host_tsc, guest_tsc;
+
+ if (!IS_ENABLED(CONFIG_64BIT) ||
+ !kvm_get_monotonic_and_clockread(&kernel_now, &host_tsc)) {
+ /*
+ * Don't fall back to get_kvmclock_ns() because it's
+ * broken; it has a systemic error in its results
+ * because it scales directly from host TSC to
+ * nanoseconds, and doesn't scale first to guest TSC
+ * and *then* to nanoseconds as the guest does.
+ *
+ * There is a small error introduced here because time
+ * continues to elapse between the ktime_get() and the
+ * subsequent rdtsc(). But not the systemic drift due
+ * to get_kvmclock_ns().
+ */
+ kernel_now = ktime_get(); /* This is CLOCK_MONOTONIC */
+ host_tsc = rdtsc();
+ }
+
+ /* Calculate the guest kvmclock as the guest would do it. */
+ guest_tsc = kvm_read_l1_tsc(vcpu, host_tsc);
+ guest_now = __pvclock_read_cycles(&vcpu->arch.hv_clock,
+ guest_tsc);
+ } else {
+ /*
+ * Without CONSTANT_TSC, get_kvmclock_ns() is the only option.
+ *
+ * Also if the guest PV clock hasn't been set up yet, as is
+ * likely to be the case during migration when the vCPU has
+ * not been run yet. It would be possible to calculate the
+ * scaling factors properly in that case but there's not much
+ * point in doing so. The get_kvmclock_ns() drift accumulates
+ * over time, so it's OK to use it at startup. Besides, on
+ * migration there's going to be a little bit of skew in the
+ * precise moment at which timers fire anyway. Often they'll
+ * be in the "past" by the time the VM is running again after
+ * migration.
+ */
+ guest_now = get_kvmclock_ns(vcpu->kvm);
+ kernel_now = ktime_get();
+ }
+
+ delta = guest_abs - guest_now;
+
+ /*
+ * Xen has a 'Linux workaround' in do_set_timer_op() which checks for
+ * negative absolute timeout values (caused by integer overflow), and
+ * for values about 13 days in the future (2^50ns) which would be
+ * caused by jiffies overflow. For those cases, Xen sets the timeout
+ * 100ms in the future (not *too* soon, since if a guest really did
+ * set a long timeout on purpose we don't want to keep churning CPU
+ * time by waking it up). Emulate Xen's workaround when starting the
+ * timer in response to __HYPERVISOR_set_timer_op.
+ */
+ if (linux_wa &&
+ unlikely((int64_t)guest_abs < 0 ||
+ (delta > 0 && (uint32_t) (delta >> 50) != 0))) {
+ delta = 100 * NSEC_PER_MSEC;
+ guest_abs = guest_now + delta;
+ }
+
/*
* Avoid races with the old timer firing. Checking timer_expires
* to avoid calling hrtimer_cancel() will only have false positives
@@ -171,14 +248,12 @@ static void kvm_xen_start_timer(struct kvm_vcpu *vcpu, u64 guest_abs, s64 delta_
atomic_set(&vcpu->arch.xen.timer_pending, 0);
vcpu->arch.xen.timer_expires = guest_abs;
- if (delta_ns <= 0) {
+ if (delta <= 0)
xen_timer_callback(&vcpu->arch.xen.timer);
- } else {
- ktime_t ktime_now = ktime_get();
+ else
hrtimer_start(&vcpu->arch.xen.timer,
- ktime_add_ns(ktime_now, delta_ns),
+ ktime_add_ns(kernel_now, delta),
HRTIMER_MODE_ABS_HARD);
- }
}
static void kvm_xen_stop_timer(struct kvm_vcpu *vcpu)
@@ -452,14 +527,13 @@ static void kvm_xen_update_runstate_guest(struct kvm_vcpu *v, bool atomic)
smp_wmb();
}
- if (user_len2)
+ if (user_len2) {
+ kvm_gpc_mark_dirty_in_slot(gpc2);
read_unlock(&gpc2->lock);
+ }
+ kvm_gpc_mark_dirty_in_slot(gpc1);
read_unlock_irqrestore(&gpc1->lock, flags);
-
- mark_page_dirty_in_slot(v->kvm, gpc1->memslot, gpc1->gpa >> PAGE_SHIFT);
- if (user_len2)
- mark_page_dirty_in_slot(v->kvm, gpc2->memslot, gpc2->gpa >> PAGE_SHIFT);
}
void kvm_xen_update_runstate(struct kvm_vcpu *v, int state)
@@ -493,10 +567,9 @@ void kvm_xen_update_runstate(struct kvm_vcpu *v, int state)
kvm_xen_update_runstate_guest(v, state == RUNSTATE_runnable);
}
-static void kvm_xen_inject_vcpu_vector(struct kvm_vcpu *v)
+void kvm_xen_inject_vcpu_vector(struct kvm_vcpu *v)
{
struct kvm_lapic_irq irq = { };
- int r;
irq.dest_id = v->vcpu_id;
irq.vector = v->arch.xen.upcall_vector;
@@ -505,8 +578,7 @@ static void kvm_xen_inject_vcpu_vector(struct kvm_vcpu *v)
irq.delivery_mode = APIC_DM_FIXED;
irq.level = 1;
- /* The fast version will always work for physical unicast */
- WARN_ON_ONCE(!kvm_irq_delivery_to_apic_fast(v->kvm, NULL, &irq, &r, NULL));
+ kvm_irq_delivery_to_apic(v->kvm, NULL, &irq, NULL);
}
/*
@@ -565,13 +637,13 @@ void kvm_xen_inject_pending_events(struct kvm_vcpu *v)
: "0" (evtchn_pending_sel32));
WRITE_ONCE(vi->evtchn_upcall_pending, 1);
}
+
+ kvm_gpc_mark_dirty_in_slot(gpc);
read_unlock_irqrestore(&gpc->lock, flags);
/* For the per-vCPU lapic vector, deliver it as MSI. */
if (v->arch.xen.upcall_vector)
kvm_xen_inject_vcpu_vector(v);
-
- mark_page_dirty_in_slot(v->kvm, gpc->memslot, gpc->gpa >> PAGE_SHIFT);
}
int __kvm_xen_has_interrupt(struct kvm_vcpu *v)
@@ -635,17 +707,59 @@ int kvm_xen_hvm_set_attr(struct kvm *kvm, struct kvm_xen_hvm_attr *data)
} else {
mutex_lock(&kvm->arch.xen.xen_lock);
kvm->arch.xen.long_mode = !!data->u.long_mode;
+
+ /*
+ * Re-initialize shared_info to put the wallclock in the
+ * correct place. Whilst it's not necessary to do this
+ * unless the mode is actually changed, it does no harm
+ * to make the call anyway.
+ */
+ r = kvm->arch.xen.shinfo_cache.active ?
+ kvm_xen_shared_info_init(kvm) : 0;
mutex_unlock(&kvm->arch.xen.xen_lock);
- r = 0;
}
break;
case KVM_XEN_ATTR_TYPE_SHARED_INFO:
+ case KVM_XEN_ATTR_TYPE_SHARED_INFO_HVA: {
+ int idx;
+
mutex_lock(&kvm->arch.xen.xen_lock);
- r = kvm_xen_shared_info_init(kvm, data->u.shared_info.gfn);
+
+ idx = srcu_read_lock(&kvm->srcu);
+
+ if (data->type == KVM_XEN_ATTR_TYPE_SHARED_INFO) {
+ gfn_t gfn = data->u.shared_info.gfn;
+
+ if (gfn == KVM_XEN_INVALID_GFN) {
+ kvm_gpc_deactivate(&kvm->arch.xen.shinfo_cache);
+ r = 0;
+ } else {
+ r = kvm_gpc_activate(&kvm->arch.xen.shinfo_cache,
+ gfn_to_gpa(gfn), PAGE_SIZE);
+ }
+ } else {
+ void __user * hva = u64_to_user_ptr(data->u.shared_info.hva);
+
+ if (!PAGE_ALIGNED(hva) || !access_ok(hva, PAGE_SIZE)) {
+ r = -EINVAL;
+ } else if (!hva) {
+ kvm_gpc_deactivate(&kvm->arch.xen.shinfo_cache);
+ r = 0;
+ } else {
+ r = kvm_gpc_activate_hva(&kvm->arch.xen.shinfo_cache,
+ (unsigned long)hva, PAGE_SIZE);
+ }
+ }
+
+ srcu_read_unlock(&kvm->srcu, idx);
+
+ if (!r && kvm->arch.xen.shinfo_cache.active)
+ r = kvm_xen_shared_info_init(kvm);
+
mutex_unlock(&kvm->arch.xen.xen_lock);
break;
-
+ }
case KVM_XEN_ATTR_TYPE_UPCALL_VECTOR:
if (data->u.vector && data->u.vector < 0x10)
r = -EINVAL;
@@ -699,13 +813,21 @@ int kvm_xen_hvm_get_attr(struct kvm *kvm, struct kvm_xen_hvm_attr *data)
break;
case KVM_XEN_ATTR_TYPE_SHARED_INFO:
- if (kvm->arch.xen.shinfo_cache.active)
+ if (kvm_gpc_is_gpa_active(&kvm->arch.xen.shinfo_cache))
data->u.shared_info.gfn = gpa_to_gfn(kvm->arch.xen.shinfo_cache.gpa);
else
data->u.shared_info.gfn = KVM_XEN_INVALID_GFN;
r = 0;
break;
+ case KVM_XEN_ATTR_TYPE_SHARED_INFO_HVA:
+ if (kvm_gpc_is_hva_active(&kvm->arch.xen.shinfo_cache))
+ data->u.shared_info.hva = kvm->arch.xen.shinfo_cache.uhva;
+ else
+ data->u.shared_info.hva = 0;
+ r = 0;
+ break;
+
case KVM_XEN_ATTR_TYPE_UPCALL_VECTOR:
data->u.vector = kvm->arch.xen.upcall_vector;
r = 0;
@@ -742,20 +864,33 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data)
switch (data->type) {
case KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO:
+ case KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO_HVA:
/* No compat necessary here. */
BUILD_BUG_ON(sizeof(struct vcpu_info) !=
sizeof(struct compat_vcpu_info));
BUILD_BUG_ON(offsetof(struct vcpu_info, time) !=
offsetof(struct compat_vcpu_info, time));
- if (data->u.gpa == KVM_XEN_INVALID_GPA) {
- kvm_gpc_deactivate(&vcpu->arch.xen.vcpu_info_cache);
- r = 0;
- break;
+ if (data->type == KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO) {
+ if (data->u.gpa == KVM_XEN_INVALID_GPA) {
+ kvm_gpc_deactivate(&vcpu->arch.xen.vcpu_info_cache);
+ r = 0;
+ break;
+ }
+
+ r = kvm_gpc_activate(&vcpu->arch.xen.vcpu_info_cache,
+ data->u.gpa, sizeof(struct vcpu_info));
+ } else {
+ if (data->u.hva == 0) {
+ kvm_gpc_deactivate(&vcpu->arch.xen.vcpu_info_cache);
+ r = 0;
+ break;
+ }
+
+ r = kvm_gpc_activate_hva(&vcpu->arch.xen.vcpu_info_cache,
+ data->u.hva, sizeof(struct vcpu_info));
}
- r = kvm_gpc_activate(&vcpu->arch.xen.vcpu_info_cache,
- data->u.gpa, sizeof(struct vcpu_info));
if (!r)
kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
@@ -944,9 +1079,7 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data)
/* Start the timer if the new value has a valid vector+expiry. */
if (data->u.timer.port && data->u.timer.expires_ns)
- kvm_xen_start_timer(vcpu, data->u.timer.expires_ns,
- data->u.timer.expires_ns -
- get_kvmclock_ns(vcpu->kvm));
+ kvm_xen_start_timer(vcpu, data->u.timer.expires_ns, false);
r = 0;
break;
@@ -977,13 +1110,21 @@ int kvm_xen_vcpu_get_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data)
switch (data->type) {
case KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO:
- if (vcpu->arch.xen.vcpu_info_cache.active)
+ if (kvm_gpc_is_gpa_active(&vcpu->arch.xen.vcpu_info_cache))
data->u.gpa = vcpu->arch.xen.vcpu_info_cache.gpa;
else
data->u.gpa = KVM_XEN_INVALID_GPA;
r = 0;
break;
+ case KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO_HVA:
+ if (kvm_gpc_is_hva_active(&vcpu->arch.xen.vcpu_info_cache))
+ data->u.hva = vcpu->arch.xen.vcpu_info_cache.uhva;
+ else
+ data->u.hva = 0;
+ r = 0;
+ break;
+
case KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO:
if (vcpu->arch.xen.vcpu_time_info_cache.active)
data->u.gpa = vcpu->arch.xen.vcpu_time_info_cache.gpa;
@@ -1093,9 +1234,24 @@ int kvm_xen_write_hypercall_page(struct kvm_vcpu *vcpu, u64 data)
u32 page_num = data & ~PAGE_MASK;
u64 page_addr = data & PAGE_MASK;
bool lm = is_long_mode(vcpu);
+ int r = 0;
+
+ mutex_lock(&kvm->arch.xen.xen_lock);
+ if (kvm->arch.xen.long_mode != lm) {
+ kvm->arch.xen.long_mode = lm;
+
+ /*
+ * Re-initialize shared_info to put the wallclock in the
+ * correct place.
+ */
+ if (kvm->arch.xen.shinfo_cache.active &&
+ kvm_xen_shared_info_init(kvm))
+ r = 1;
+ }
+ mutex_unlock(&kvm->arch.xen.xen_lock);
- /* Latch long_mode for shared_info pages etc. */
- vcpu->kvm->arch.xen.long_mode = lm;
+ if (r)
+ return r;
/*
* If Xen hypercall intercept is enabled, fill the hypercall
@@ -1396,7 +1552,6 @@ static bool kvm_xen_hcall_vcpu_op(struct kvm_vcpu *vcpu, bool longmode, int cmd,
{
struct vcpu_set_singleshot_timer oneshot;
struct x86_exception e;
- s64 delta;
if (!kvm_xen_timer_enabled(vcpu))
return false;
@@ -1430,9 +1585,7 @@ static bool kvm_xen_hcall_vcpu_op(struct kvm_vcpu *vcpu, bool longmode, int cmd,
return true;
}
- /* A delta <= 0 results in an immediate callback, which is what we want */
- delta = oneshot.timeout_abs_ns - get_kvmclock_ns(vcpu->kvm);
- kvm_xen_start_timer(vcpu, oneshot.timeout_abs_ns, delta);
+ kvm_xen_start_timer(vcpu, oneshot.timeout_abs_ns, false);
*r = 0;
return true;
@@ -1455,29 +1608,10 @@ static bool kvm_xen_hcall_set_timer_op(struct kvm_vcpu *vcpu, uint64_t timeout,
if (!kvm_xen_timer_enabled(vcpu))
return false;
- if (timeout) {
- uint64_t guest_now = get_kvmclock_ns(vcpu->kvm);
- int64_t delta = timeout - guest_now;
-
- /* Xen has a 'Linux workaround' in do_set_timer_op() which
- * checks for negative absolute timeout values (caused by
- * integer overflow), and for values about 13 days in the
- * future (2^50ns) which would be caused by jiffies
- * overflow. For those cases, it sets the timeout 100ms in
- * the future (not *too* soon, since if a guest really did
- * set a long timeout on purpose we don't want to keep
- * churning CPU time by waking it up).
- */
- if (unlikely((int64_t)timeout < 0 ||
- (delta > 0 && (uint32_t) (delta >> 50) != 0))) {
- delta = 100 * NSEC_PER_MSEC;
- timeout = guest_now + delta;
- }
-
- kvm_xen_start_timer(vcpu, timeout, delta);
- } else {
+ if (timeout)
+ kvm_xen_start_timer(vcpu, timeout, true);
+ else
kvm_xen_stop_timer(vcpu);
- }
*r = 0;
return true;
@@ -1621,9 +1755,6 @@ int kvm_xen_set_evtchn_fast(struct kvm_xen_evtchn *xe, struct kvm *kvm)
WRITE_ONCE(xe->vcpu_idx, vcpu->vcpu_idx);
}
- if (!vcpu->arch.xen.vcpu_info_cache.active)
- return -EINVAL;
-
if (xe->port >= max_evtchn_port(kvm))
return -EINVAL;
@@ -1731,8 +1862,6 @@ static int kvm_xen_set_evtchn(struct kvm_xen_evtchn *xe, struct kvm *kvm)
mm_borrowed = true;
}
- mutex_lock(&kvm->arch.xen.xen_lock);
-
/*
* It is theoretically possible for the page to be unmapped
* and the MMU notifier to invalidate the shared_info before
@@ -1760,8 +1889,6 @@ static int kvm_xen_set_evtchn(struct kvm_xen_evtchn *xe, struct kvm *kvm)
srcu_read_unlock(&kvm->srcu, idx);
} while(!rc);
- mutex_unlock(&kvm->arch.xen.xen_lock);
-
if (mm_borrowed)
kthread_unuse_mm(kvm->mm);
@@ -2109,14 +2236,10 @@ void kvm_xen_init_vcpu(struct kvm_vcpu *vcpu)
timer_setup(&vcpu->arch.xen.poll_timer, cancel_evtchn_poll, 0);
- kvm_gpc_init(&vcpu->arch.xen.runstate_cache, vcpu->kvm, NULL,
- KVM_HOST_USES_PFN);
- kvm_gpc_init(&vcpu->arch.xen.runstate2_cache, vcpu->kvm, NULL,
- KVM_HOST_USES_PFN);
- kvm_gpc_init(&vcpu->arch.xen.vcpu_info_cache, vcpu->kvm, NULL,
- KVM_HOST_USES_PFN);
- kvm_gpc_init(&vcpu->arch.xen.vcpu_time_info_cache, vcpu->kvm, NULL,
- KVM_HOST_USES_PFN);
+ kvm_gpc_init(&vcpu->arch.xen.runstate_cache, vcpu->kvm);
+ kvm_gpc_init(&vcpu->arch.xen.runstate2_cache, vcpu->kvm);
+ kvm_gpc_init(&vcpu->arch.xen.vcpu_info_cache, vcpu->kvm);
+ kvm_gpc_init(&vcpu->arch.xen.vcpu_time_info_cache, vcpu->kvm);
}
void kvm_xen_destroy_vcpu(struct kvm_vcpu *vcpu)
@@ -2159,7 +2282,7 @@ void kvm_xen_init_vm(struct kvm *kvm)
{
mutex_init(&kvm->arch.xen.xen_lock);
idr_init(&kvm->arch.xen.evtchn_ports);
- kvm_gpc_init(&kvm->arch.xen.shinfo_cache, kvm, NULL, KVM_HOST_USES_PFN);
+ kvm_gpc_init(&kvm->arch.xen.shinfo_cache, kvm);
}
void kvm_xen_destroy_vm(struct kvm *kvm)
diff --git a/arch/x86/kvm/xen.h b/arch/x86/kvm/xen.h
index f8f1fe22d090..f5841d9000ae 100644
--- a/arch/x86/kvm/xen.h
+++ b/arch/x86/kvm/xen.h
@@ -18,6 +18,7 @@ extern struct static_key_false_deferred kvm_xen_enabled;
int __kvm_xen_has_interrupt(struct kvm_vcpu *vcpu);
void kvm_xen_inject_pending_events(struct kvm_vcpu *vcpu);
+void kvm_xen_inject_vcpu_vector(struct kvm_vcpu *vcpu);
int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data);
int kvm_xen_vcpu_get_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data);
int kvm_xen_hvm_set_attr(struct kvm *kvm, struct kvm_xen_hvm_attr *data);
@@ -36,6 +37,19 @@ int kvm_xen_setup_evtchn(struct kvm *kvm,
const struct kvm_irq_routing_entry *ue);
void kvm_xen_update_tsc_info(struct kvm_vcpu *vcpu);
+static inline void kvm_xen_sw_enable_lapic(struct kvm_vcpu *vcpu)
+{
+ /*
+ * The local APIC is being enabled. If the per-vCPU upcall vector is
+ * set and the vCPU's evtchn_upcall_pending flag is set, inject the
+ * interrupt.
+ */
+ if (static_branch_unlikely(&kvm_xen_enabled.key) &&
+ vcpu->arch.xen.vcpu_info_cache.active &&
+ vcpu->arch.xen.upcall_vector && __kvm_xen_has_interrupt(vcpu))
+ kvm_xen_inject_vcpu_vector(vcpu);
+}
+
static inline bool kvm_xen_msr_enabled(struct kvm *kvm)
{
return static_branch_unlikely(&kvm_xen_enabled.key) &&
@@ -101,6 +115,10 @@ static inline void kvm_xen_destroy_vcpu(struct kvm_vcpu *vcpu)
{
}
+static inline void kvm_xen_sw_enable_lapic(struct kvm_vcpu *vcpu)
+{
+}
+
static inline bool kvm_xen_msr_enabled(struct kvm *kvm)
{
return false;
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index ea3a28e7b613..6da73513f026 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -14,19 +14,6 @@ ifdef CONFIG_KCSAN
CFLAGS_REMOVE_delay.o = $(CC_FLAGS_FTRACE)
endif
-# Early boot use of cmdline; don't instrument it
-ifdef CONFIG_AMD_MEM_ENCRYPT
-KCOV_INSTRUMENT_cmdline.o := n
-KASAN_SANITIZE_cmdline.o := n
-KCSAN_SANITIZE_cmdline.o := n
-
-ifdef CONFIG_FUNCTION_TRACER
-CFLAGS_REMOVE_cmdline.o = -pg
-endif
-
-CFLAGS_cmdline.o := -fno-stack-protector -fno-jump-tables
-endif
-
inat_tables_script = $(srctree)/arch/x86/tools/gen-insn-attr-x86.awk
inat_tables_maps = $(srctree)/arch/x86/lib/x86-opcode-map.txt
quiet_cmd_inat_tables = GEN $@
@@ -49,7 +36,7 @@ lib-$(CONFIG_ARCH_HAS_COPY_MC) += copy_mc.o copy_mc_64.o
lib-$(CONFIG_INSTRUCTION_DECODER) += insn.o inat.o insn-eval.o
lib-$(CONFIG_RANDOMIZE_BASE) += kaslr.o
lib-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
-lib-$(CONFIG_RETPOLINE) += retpoline.o
+lib-$(CONFIG_MITIGATION_RETPOLINE) += retpoline.o
obj-y += msr.o msr-reg.o msr-reg-export.o hweight.o
obj-y += iomem.o
diff --git a/arch/x86/lib/cmpxchg16b_emu.S b/arch/x86/lib/cmpxchg16b_emu.S
index 6962df315793..4fb44894ad87 100644
--- a/arch/x86/lib/cmpxchg16b_emu.S
+++ b/arch/x86/lib/cmpxchg16b_emu.S
@@ -23,14 +23,14 @@ SYM_FUNC_START(this_cpu_cmpxchg16b_emu)
cli
/* if (*ptr == old) */
- cmpq PER_CPU_VAR(0(%rsi)), %rax
+ cmpq __percpu (%rsi), %rax
jne .Lnot_same
- cmpq PER_CPU_VAR(8(%rsi)), %rdx
+ cmpq __percpu 8(%rsi), %rdx
jne .Lnot_same
/* *ptr = new */
- movq %rbx, PER_CPU_VAR(0(%rsi))
- movq %rcx, PER_CPU_VAR(8(%rsi))
+ movq %rbx, __percpu (%rsi)
+ movq %rcx, __percpu 8(%rsi)
/* set ZF in EFLAGS to indicate success */
orl $X86_EFLAGS_ZF, (%rsp)
@@ -42,8 +42,8 @@ SYM_FUNC_START(this_cpu_cmpxchg16b_emu)
/* *ptr != old */
/* old = *ptr */
- movq PER_CPU_VAR(0(%rsi)), %rax
- movq PER_CPU_VAR(8(%rsi)), %rdx
+ movq __percpu (%rsi), %rax
+ movq __percpu 8(%rsi), %rdx
/* clear ZF in EFLAGS to indicate failure */
andl $(~X86_EFLAGS_ZF), (%rsp)
diff --git a/arch/x86/lib/cmpxchg8b_emu.S b/arch/x86/lib/cmpxchg8b_emu.S
index 873e4ef23e49..1c96be769adc 100644
--- a/arch/x86/lib/cmpxchg8b_emu.S
+++ b/arch/x86/lib/cmpxchg8b_emu.S
@@ -24,12 +24,12 @@ SYM_FUNC_START(cmpxchg8b_emu)
pushfl
cli
- cmpl 0(%esi), %eax
+ cmpl (%esi), %eax
jne .Lnot_same
cmpl 4(%esi), %edx
jne .Lnot_same
- movl %ebx, 0(%esi)
+ movl %ebx, (%esi)
movl %ecx, 4(%esi)
orl $X86_EFLAGS_ZF, (%esp)
@@ -38,7 +38,7 @@ SYM_FUNC_START(cmpxchg8b_emu)
RET
.Lnot_same:
- movl 0(%esi), %eax
+ movl (%esi), %eax
movl 4(%esi), %edx
andl $(~X86_EFLAGS_ZF), (%esp)
@@ -53,18 +53,30 @@ EXPORT_SYMBOL(cmpxchg8b_emu)
#ifndef CONFIG_UML
+/*
+ * Emulate 'cmpxchg8b %fs:(%rsi)'
+ *
+ * Inputs:
+ * %esi : memory location to compare
+ * %eax : low 32 bits of old value
+ * %edx : high 32 bits of old value
+ * %ebx : low 32 bits of new value
+ * %ecx : high 32 bits of new value
+ *
+ * Notably this is not LOCK prefixed and is not safe against NMIs
+ */
SYM_FUNC_START(this_cpu_cmpxchg8b_emu)
pushfl
cli
- cmpl PER_CPU_VAR(0(%esi)), %eax
+ cmpl __percpu (%esi), %eax
jne .Lnot_same2
- cmpl PER_CPU_VAR(4(%esi)), %edx
+ cmpl __percpu 4(%esi), %edx
jne .Lnot_same2
- movl %ebx, PER_CPU_VAR(0(%esi))
- movl %ecx, PER_CPU_VAR(4(%esi))
+ movl %ebx, __percpu (%esi)
+ movl %ecx, __percpu 4(%esi)
orl $X86_EFLAGS_ZF, (%esp)
@@ -72,8 +84,8 @@ SYM_FUNC_START(this_cpu_cmpxchg8b_emu)
RET
.Lnot_same2:
- movl PER_CPU_VAR(0(%esi)), %eax
- movl PER_CPU_VAR(4(%esi)), %edx
+ movl __percpu (%esi), %eax
+ movl __percpu 4(%esi), %edx
andl $(~X86_EFLAGS_ZF), (%esp)
diff --git a/arch/x86/lib/insn-eval.c b/arch/x86/lib/insn-eval.c
index 558a605929db..98631c0e7a11 100644
--- a/arch/x86/lib/insn-eval.c
+++ b/arch/x86/lib/insn-eval.c
@@ -1129,15 +1129,15 @@ static int get_eff_addr_modrm_16(struct insn *insn, struct pt_regs *regs,
* get_eff_addr_sib() - Obtain referenced effective address via SIB
* @insn: Instruction. Must be valid.
* @regs: Register values as seen when entering kernel mode
- * @regoff: Obtained operand offset, in pt_regs, associated with segment
+ * @base_offset: Obtained operand offset, in pt_regs, associated with segment
* @eff_addr: Obtained effective address
*
* Obtain the effective address referenced by the SIB byte of @insn. After
* identifying the registers involved in the indexed, register-indirect memory
* reference, its value is obtained from the operands in @regs. The computed
* address is stored @eff_addr. Also, the register operand that indicates the
- * associated segment is stored in @regoff, this parameter can later be used to
- * determine such segment.
+ * associated segment is stored in @base_offset; this parameter can later be
+ * used to determine such segment.
*
* Returns:
*
diff --git a/arch/x86/lib/insn.c b/arch/x86/lib/insn.c
index 55e371cc69fd..1bb155a0955b 100644
--- a/arch/x86/lib/insn.c
+++ b/arch/x86/lib/insn.c
@@ -71,7 +71,7 @@ void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64)
insn->kaddr = kaddr;
insn->end_kaddr = kaddr + buf_len;
insn->next_byte = kaddr;
- insn->x86_64 = x86_64 ? 1 : 0;
+ insn->x86_64 = x86_64;
insn->opnd_bytes = 4;
if (x86_64)
insn->addr_bytes = 8;
@@ -268,11 +268,9 @@ int insn_get_opcode(struct insn *insn)
if (opcode->got)
return 0;
- if (!insn->prefixes.got) {
- ret = insn_get_prefixes(insn);
- if (ret)
- return ret;
- }
+ ret = insn_get_prefixes(insn);
+ if (ret)
+ return ret;
/* Get first opcode */
op = get_next(insn_byte_t, insn);
@@ -339,11 +337,9 @@ int insn_get_modrm(struct insn *insn)
if (modrm->got)
return 0;
- if (!insn->opcode.got) {
- ret = insn_get_opcode(insn);
- if (ret)
- return ret;
- }
+ ret = insn_get_opcode(insn);
+ if (ret)
+ return ret;
if (inat_has_modrm(insn->attr)) {
mod = get_next(insn_byte_t, insn);
@@ -386,11 +382,9 @@ int insn_rip_relative(struct insn *insn)
if (!insn->x86_64)
return 0;
- if (!modrm->got) {
- ret = insn_get_modrm(insn);
- if (ret)
- return 0;
- }
+ ret = insn_get_modrm(insn);
+ if (ret)
+ return 0;
/*
* For rip-relative instructions, the mod field (top 2 bits)
* is zero and the r/m field (bottom 3 bits) is 0x5.
@@ -417,11 +411,9 @@ int insn_get_sib(struct insn *insn)
if (insn->sib.got)
return 0;
- if (!insn->modrm.got) {
- ret = insn_get_modrm(insn);
- if (ret)
- return ret;
- }
+ ret = insn_get_modrm(insn);
+ if (ret)
+ return ret;
if (insn->modrm.nbytes) {
modrm = insn->modrm.bytes[0];
@@ -460,11 +452,9 @@ int insn_get_displacement(struct insn *insn)
if (insn->displacement.got)
return 0;
- if (!insn->sib.got) {
- ret = insn_get_sib(insn);
- if (ret)
- return ret;
- }
+ ret = insn_get_sib(insn);
+ if (ret)
+ return ret;
if (insn->modrm.nbytes) {
/*
@@ -628,11 +618,9 @@ int insn_get_immediate(struct insn *insn)
if (insn->immediate.got)
return 0;
- if (!insn->displacement.got) {
- ret = insn_get_displacement(insn);
- if (ret)
- return ret;
- }
+ ret = insn_get_displacement(insn);
+ if (ret)
+ return ret;
if (inat_has_moffset(insn->attr)) {
if (!__get_moffset(insn))
@@ -703,11 +691,9 @@ int insn_get_length(struct insn *insn)
if (insn->length)
return 0;
- if (!insn->immediate.got) {
- ret = insn_get_immediate(insn);
- if (ret)
- return ret;
- }
+ ret = insn_get_immediate(insn);
+ if (ret)
+ return ret;
insn->length = (unsigned char)((unsigned long)insn->next_byte
- (unsigned long)insn->kaddr);
diff --git a/arch/x86/lib/msr-smp.c b/arch/x86/lib/msr-smp.c
index 40bbe56bde32..acd463d887e1 100644
--- a/arch/x86/lib/msr-smp.c
+++ b/arch/x86/lib/msr-smp.c
@@ -9,10 +9,9 @@ static void __rdmsr_on_cpu(void *info)
{
struct msr_info *rv = info;
struct msr *reg;
- int this_cpu = raw_smp_processor_id();
if (rv->msrs)
- reg = per_cpu_ptr(rv->msrs, this_cpu);
+ reg = this_cpu_ptr(rv->msrs);
else
reg = &rv->reg;
@@ -23,10 +22,9 @@ static void __wrmsr_on_cpu(void *info)
{
struct msr_info *rv = info;
struct msr *reg;
- int this_cpu = raw_smp_processor_id();
if (rv->msrs)
- reg = per_cpu_ptr(rv->msrs, this_cpu);
+ reg = this_cpu_ptr(rv->msrs);
else
reg = &rv->reg;
@@ -97,7 +95,7 @@ int wrmsrl_on_cpu(unsigned int cpu, u32 msr_no, u64 q)
EXPORT_SYMBOL(wrmsrl_on_cpu);
static void __rwmsr_on_cpus(const struct cpumask *mask, u32 msr_no,
- struct msr *msrs,
+ struct msr __percpu *msrs,
void (*msr_func) (void *info))
{
struct msr_info rv;
@@ -124,7 +122,7 @@ static void __rwmsr_on_cpus(const struct cpumask *mask, u32 msr_no,
* @msrs: array of MSR values
*
*/
-void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs)
+void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr __percpu *msrs)
{
__rwmsr_on_cpus(mask, msr_no, msrs, __rdmsr_on_cpu);
}
@@ -138,7 +136,7 @@ EXPORT_SYMBOL(rdmsr_on_cpus);
* @msrs: array of MSR values
*
*/
-void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs)
+void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr __percpu *msrs)
{
__rwmsr_on_cpus(mask, msr_no, msrs, __wrmsr_on_cpu);
}
diff --git a/arch/x86/lib/msr.c b/arch/x86/lib/msr.c
index 47fd9bd6b91d..4bf4fad5b148 100644
--- a/arch/x86/lib/msr.c
+++ b/arch/x86/lib/msr.c
@@ -6,9 +6,9 @@
#define CREATE_TRACE_POINTS
#include <asm/msr-trace.h>
-struct msr *msrs_alloc(void)
+struct msr __percpu *msrs_alloc(void)
{
- struct msr *msrs = NULL;
+ struct msr __percpu *msrs = NULL;
msrs = alloc_percpu(struct msr);
if (!msrs) {
@@ -20,7 +20,7 @@ struct msr *msrs_alloc(void)
}
EXPORT_SYMBOL(msrs_alloc);
-void msrs_free(struct msr *msrs)
+void msrs_free(struct msr __percpu *msrs)
{
free_percpu(msrs);
}
diff --git a/arch/x86/lib/retpoline.S b/arch/x86/lib/retpoline.S
index 7b2589877d06..e674ccf720b9 100644
--- a/arch/x86/lib/retpoline.S
+++ b/arch/x86/lib/retpoline.S
@@ -71,7 +71,7 @@ SYM_CODE_END(__x86_indirect_thunk_array)
#include <asm/GEN-for-each-reg.h>
#undef GEN
-#ifdef CONFIG_CALL_DEPTH_TRACKING
+#ifdef CONFIG_MITIGATION_CALL_DEPTH_TRACKING
.macro CALL_THUNK reg
.align RETPOLINE_THUNK_SIZE
@@ -127,7 +127,7 @@ SYM_CODE_END(__x86_indirect_jump_thunk_array)
#undef GEN
#endif
-#ifdef CONFIG_RETHUNK
+#ifdef CONFIG_MITIGATION_RETHUNK
/*
* Be careful here: that label cannot really be removed because in
@@ -138,7 +138,7 @@ SYM_CODE_END(__x86_indirect_jump_thunk_array)
*/
.section .text..__x86.return_thunk
-#ifdef CONFIG_CPU_SRSO
+#ifdef CONFIG_MITIGATION_SRSO
/*
* srso_alias_untrain_ret() and srso_alias_safe_ret() are placed at
@@ -163,6 +163,7 @@ SYM_CODE_START_NOALIGN(srso_alias_untrain_ret)
lfence
jmp srso_alias_return_thunk
SYM_FUNC_END(srso_alias_untrain_ret)
+__EXPORT_THUNK(srso_alias_untrain_ret)
.popsection
.pushsection .text..__x86.rethunk_safe
@@ -224,13 +225,19 @@ SYM_CODE_START(srso_return_thunk)
SYM_CODE_END(srso_return_thunk)
#define JMP_SRSO_UNTRAIN_RET "jmp srso_untrain_ret"
-#define JMP_SRSO_ALIAS_UNTRAIN_RET "jmp srso_alias_untrain_ret"
-#else /* !CONFIG_CPU_SRSO */
+#else /* !CONFIG_MITIGATION_SRSO */
+/* Dummy for the alternative in CALL_UNTRAIN_RET. */
+SYM_CODE_START(srso_alias_untrain_ret)
+ ANNOTATE_UNRET_SAFE
+ ANNOTATE_NOENDBR
+ ret
+ int3
+SYM_FUNC_END(srso_alias_untrain_ret)
+__EXPORT_THUNK(srso_alias_untrain_ret)
#define JMP_SRSO_UNTRAIN_RET "ud2"
-#define JMP_SRSO_ALIAS_UNTRAIN_RET "ud2"
-#endif /* CONFIG_CPU_SRSO */
+#endif /* CONFIG_MITIGATION_SRSO */
-#ifdef CONFIG_CPU_UNRET_ENTRY
+#ifdef CONFIG_MITIGATION_UNRET_ENTRY
/*
* Some generic notes on the untraining sequences:
@@ -312,22 +319,20 @@ SYM_CODE_END(retbleed_return_thunk)
SYM_FUNC_END(retbleed_untrain_ret)
#define JMP_RETBLEED_UNTRAIN_RET "jmp retbleed_untrain_ret"
-#else /* !CONFIG_CPU_UNRET_ENTRY */
+#else /* !CONFIG_MITIGATION_UNRET_ENTRY */
#define JMP_RETBLEED_UNTRAIN_RET "ud2"
-#endif /* CONFIG_CPU_UNRET_ENTRY */
+#endif /* CONFIG_MITIGATION_UNRET_ENTRY */
-#if defined(CONFIG_CPU_UNRET_ENTRY) || defined(CONFIG_CPU_SRSO)
+#if defined(CONFIG_MITIGATION_UNRET_ENTRY) || defined(CONFIG_MITIGATION_SRSO)
SYM_FUNC_START(entry_untrain_ret)
- ALTERNATIVE_2 JMP_RETBLEED_UNTRAIN_RET, \
- JMP_SRSO_UNTRAIN_RET, X86_FEATURE_SRSO, \
- JMP_SRSO_ALIAS_UNTRAIN_RET, X86_FEATURE_SRSO_ALIAS
+ ALTERNATIVE JMP_RETBLEED_UNTRAIN_RET, JMP_SRSO_UNTRAIN_RET, X86_FEATURE_SRSO
SYM_FUNC_END(entry_untrain_ret)
__EXPORT_THUNK(entry_untrain_ret)
-#endif /* CONFIG_CPU_UNRET_ENTRY || CONFIG_CPU_SRSO */
+#endif /* CONFIG_MITIGATION_UNRET_ENTRY || CONFIG_MITIGATION_SRSO */
-#ifdef CONFIG_CALL_DEPTH_TRACKING
+#ifdef CONFIG_MITIGATION_CALL_DEPTH_TRACKING
.align 64
SYM_FUNC_START(call_depth_return_thunk)
@@ -359,7 +364,7 @@ SYM_FUNC_START(call_depth_return_thunk)
int3
SYM_FUNC_END(call_depth_return_thunk)
-#endif /* CONFIG_CALL_DEPTH_TRACKING */
+#endif /* CONFIG_MITIGATION_CALL_DEPTH_TRACKING */
/*
* This function name is magical and is used by -mfunction-return=thunk-extern
@@ -369,21 +374,18 @@ SYM_FUNC_END(call_depth_return_thunk)
* 'JMP __x86_return_thunk' sites are changed to something else by
* apply_returns().
*
- * This should be converted eventually to call a warning function which
- * should scream loudly when the default return thunk is called after
- * alternatives have been applied.
- *
- * That warning function cannot BUG() because the bug splat cannot be
- * displayed in all possible configurations, leading to users not really
- * knowing why the machine froze.
+ * The ALTERNATIVE below adds a really loud warning to catch the case
+ * where the insufficient default return thunk ends up getting used for
+ * whatever reason like miscompilation or failure of
+ * objtool/alternatives/etc to patch all the return sites.
*/
SYM_CODE_START(__x86_return_thunk)
UNWIND_HINT_FUNC
ANNOTATE_NOENDBR
- ANNOTATE_UNRET_SAFE
- ret
+ ALTERNATIVE __stringify(ANNOTATE_UNRET_SAFE; ret), \
+ "jmp warn_thunk_thunk", X86_FEATURE_ALWAYS
int3
SYM_CODE_END(__x86_return_thunk)
EXPORT_SYMBOL(__x86_return_thunk)
-#endif /* CONFIG_RETHUNK */
+#endif /* CONFIG_MITIGATION_RETHUNK */
diff --git a/arch/x86/lib/x86-opcode-map.txt b/arch/x86/lib/x86-opcode-map.txt
index 5168ee0360b2..12af572201a2 100644
--- a/arch/x86/lib/x86-opcode-map.txt
+++ b/arch/x86/lib/x86-opcode-map.txt
@@ -1051,8 +1051,8 @@ 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)
-1: SIDT Ms | MONITOR (000),(11B) | MWAIT (001),(11B) | CLAC (010),(11B) | STAC (011),(11B) | ENCLS (111),(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)
+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
4: SMSW Mw/Rv
diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
index c80febc44cd2..428048e73bd2 100644
--- a/arch/x86/mm/Makefile
+++ b/arch/x86/mm/Makefile
@@ -16,6 +16,7 @@ KASAN_SANITIZE_pgprot.o := n
KCSAN_SANITIZE := n
# Avoid recursion by not calling KMSAN hooks for CEA code.
KMSAN_SANITIZE_cpu_entry_area.o := n
+KMSAN_SANITIZE_mem_encrypt_identity.o := n
ifdef CONFIG_FUNCTION_TRACER
CFLAGS_REMOVE_mem_encrypt.o = -pg
@@ -60,7 +61,7 @@ obj-$(CONFIG_NUMA_EMU) += numa_emulation.o
obj-$(CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS) += pkeys.o
obj-$(CONFIG_RANDOMIZE_MEMORY) += kaslr.o
-obj-$(CONFIG_PAGE_TABLE_ISOLATION) += pti.o
+obj-$(CONFIG_MITIGATION_PAGE_TABLE_ISOLATION) += pti.o
obj-$(CONFIG_X86_MEM_ENCRYPT) += mem_encrypt.o
obj-$(CONFIG_AMD_MEM_ENCRYPT) += mem_encrypt_amd.o
diff --git a/arch/x86/mm/amdtopology.c b/arch/x86/mm/amdtopology.c
index b3ca7d23e4b0..9332b36a1091 100644
--- a/arch/x86/mm/amdtopology.c
+++ b/arch/x86/mm/amdtopology.c
@@ -54,13 +54,11 @@ static __init int find_northbridge(void)
int __init amd_numa_init(void)
{
- u64 start = PFN_PHYS(0);
+ unsigned int numnodes, cores, apicid;
+ u64 prevbase, start = PFN_PHYS(0);
u64 end = PFN_PHYS(max_pfn);
- unsigned numnodes;
- u64 prevbase;
- int i, j, nb;
u32 nodeid, reg;
- unsigned int bits, cores, apicid_base;
+ int i, j, nb;
if (!early_pci_allowed())
return -EINVAL;
@@ -158,26 +156,18 @@ int __init amd_numa_init(void)
return -ENOENT;
/*
- * We seem to have valid NUMA configuration. Map apicids to nodes
- * using the coreid bits from early_identify_cpu.
+ * We seem to have valid NUMA configuration. Map apicids to nodes
+ * using the size of the core domain in the APIC space.
*/
- bits = boot_cpu_data.x86_coreid_bits;
- cores = 1 << bits;
- apicid_base = 0;
+ cores = topology_get_domain_size(TOPO_CORE_DOMAIN);
- /*
- * get boot-time SMP configuration:
- */
- early_get_smp_config();
+ apicid = boot_cpu_physical_apicid;
+ if (apicid > 0)
+ pr_info("BSP APIC ID: %02x\n", apicid);
- if (boot_cpu_physical_apicid > 0) {
- pr_info("BSP APIC ID: %02x\n", boot_cpu_physical_apicid);
- apicid_base = boot_cpu_physical_apicid;
+ for_each_node_mask(i, numa_nodes_parsed) {
+ for (j = 0; j < cores; j++, apicid++)
+ set_apicid_to_node(apicid, i);
}
-
- for_each_node_mask(i, numa_nodes_parsed)
- for (j = apicid_base; j < cores + apicid_base; j++)
- set_apicid_to_node((i << bits) + j, i);
-
return 0;
}
diff --git a/arch/x86/mm/debug_pagetables.c b/arch/x86/mm/debug_pagetables.c
index b43301cb2a80..ae5c213a1cb0 100644
--- a/arch/x86/mm/debug_pagetables.c
+++ b/arch/x86/mm/debug_pagetables.c
@@ -22,7 +22,7 @@ static int ptdump_curknl_show(struct seq_file *m, void *v)
DEFINE_SHOW_ATTRIBUTE(ptdump_curknl);
-#ifdef CONFIG_PAGE_TABLE_ISOLATION
+#ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
static int ptdump_curusr_show(struct seq_file *m, void *v)
{
if (current->mm->pgd)
@@ -54,7 +54,7 @@ static int __init pt_dump_debug_init(void)
debugfs_create_file("current_kernel", 0400, dir, NULL,
&ptdump_curknl_fops);
-#ifdef CONFIG_PAGE_TABLE_ISOLATION
+#ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
debugfs_create_file("current_user", 0400, dir, NULL,
&ptdump_curusr_fops);
#endif
diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c
index e1b599ecbbc2..89079ea73e65 100644
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -362,9 +362,9 @@ static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
}
}
-static void ptdump_walk_pgd_level_core(struct seq_file *m,
- struct mm_struct *mm, pgd_t *pgd,
- bool checkwx, bool dmesg)
+bool ptdump_walk_pgd_level_core(struct seq_file *m,
+ struct mm_struct *mm, pgd_t *pgd,
+ bool checkwx, bool dmesg)
{
const struct ptdump_range ptdump_ranges[] = {
#ifdef CONFIG_X86_64
@@ -391,12 +391,17 @@ static void ptdump_walk_pgd_level_core(struct seq_file *m,
ptdump_walk_pgd(&st.ptdump, mm, pgd);
if (!checkwx)
- return;
- if (st.wx_pages)
+ return true;
+ if (st.wx_pages) {
pr_info("x86/mm: Checked W+X mappings: FAILED, %lu W+X pages found.\n",
st.wx_pages);
- else
+
+ return false;
+ } else {
pr_info("x86/mm: Checked W+X mappings: passed, no W+X pages found.\n");
+
+ return true;
+ }
}
void ptdump_walk_pgd_level(struct seq_file *m, struct mm_struct *mm)
@@ -408,7 +413,7 @@ void ptdump_walk_pgd_level_debugfs(struct seq_file *m, struct mm_struct *mm,
bool user)
{
pgd_t *pgd = mm->pgd;
-#ifdef CONFIG_PAGE_TABLE_ISOLATION
+#ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
if (user && boot_cpu_has(X86_FEATURE_PTI))
pgd = kernel_to_user_pgdp(pgd);
#endif
@@ -418,7 +423,7 @@ EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level_debugfs);
void ptdump_walk_user_pgd_level_checkwx(void)
{
-#ifdef CONFIG_PAGE_TABLE_ISOLATION
+#ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
pgd_t *pgd = INIT_PGD;
if (!(__supported_pte_mask & _PAGE_NX) ||
@@ -431,9 +436,12 @@ void ptdump_walk_user_pgd_level_checkwx(void)
#endif
}
-void ptdump_walk_pgd_level_checkwx(void)
+bool ptdump_walk_pgd_level_checkwx(void)
{
- ptdump_walk_pgd_level_core(NULL, &init_mm, INIT_PGD, true, false);
+ if (!(__supported_pte_mask & _PAGE_NX))
+ return true;
+
+ return ptdump_walk_pgd_level_core(NULL, &init_mm, INIT_PGD, true, false);
}
static int __init pt_dump_init(void)
diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c
index 271dcb2deabc..b522933bfa56 100644
--- a/arch/x86/mm/extable.c
+++ b/arch/x86/mm/extable.c
@@ -6,6 +6,7 @@
#include <xen/xen.h>
#include <asm/fpu/api.h>
+#include <asm/fred.h>
#include <asm/sev.h>
#include <asm/traps.h>
#include <asm/kdebug.h>
@@ -223,6 +224,79 @@ static bool ex_handler_ucopy_len(const struct exception_table_entry *fixup,
return ex_handler_uaccess(fixup, regs, trapnr, fault_address);
}
+#ifdef CONFIG_X86_FRED
+static bool ex_handler_eretu(const struct exception_table_entry *fixup,
+ struct pt_regs *regs, unsigned long error_code)
+{
+ struct pt_regs *uregs = (struct pt_regs *)(regs->sp - offsetof(struct pt_regs, orig_ax));
+ unsigned short ss = uregs->ss;
+ unsigned short cs = uregs->cs;
+
+ /*
+ * Move the NMI bit from the invalid stack frame, which caused ERETU
+ * to fault, to the fault handler's stack frame, thus to unblock NMI
+ * with the fault handler's ERETS instruction ASAP if NMI is blocked.
+ */
+ regs->fred_ss.nmi = uregs->fred_ss.nmi;
+
+ /*
+ * Sync event information to uregs, i.e., the ERETU return frame, but
+ * is it safe to write to the ERETU return frame which is just above
+ * current event stack frame?
+ *
+ * The RSP used by FRED to push a stack frame is not the value in %rsp,
+ * it is calculated from %rsp with the following 2 steps:
+ * 1) RSP = %rsp - (IA32_FRED_CONFIG & 0x1c0) // Reserve N*64 bytes
+ * 2) RSP = RSP & ~0x3f // Align to a 64-byte cache line
+ * when an event delivery doesn't trigger a stack level change.
+ *
+ * Here is an example with N*64 (N=1) bytes reserved:
+ *
+ * 64-byte cache line ==> ______________
+ * |___Reserved___|
+ * |__Event_data__|
+ * |_____SS_______|
+ * |_____RSP______|
+ * |_____FLAGS____|
+ * |_____CS_______|
+ * |_____IP_______|
+ * 64-byte cache line ==> |__Error_code__| <== ERETU return frame
+ * |______________|
+ * |______________|
+ * |______________|
+ * |______________|
+ * |______________|
+ * |______________|
+ * |______________|
+ * 64-byte cache line ==> |______________| <== RSP after step 1) and 2)
+ * |___Reserved___|
+ * |__Event_data__|
+ * |_____SS_______|
+ * |_____RSP______|
+ * |_____FLAGS____|
+ * |_____CS_______|
+ * |_____IP_______|
+ * 64-byte cache line ==> |__Error_code__| <== ERETS return frame
+ *
+ * Thus a new FRED stack frame will always be pushed below a previous
+ * FRED stack frame ((N*64) bytes may be reserved between), and it is
+ * safe to write to a previous FRED stack frame as they never overlap.
+ */
+ fred_info(uregs)->edata = fred_event_data(regs);
+ uregs->ssx = regs->ssx;
+ uregs->fred_ss.ss = ss;
+ /* The NMI bit was moved away above */
+ uregs->fred_ss.nmi = 0;
+ uregs->csx = regs->csx;
+ uregs->fred_cs.sl = 0;
+ uregs->fred_cs.wfe = 0;
+ uregs->cs = cs;
+ uregs->orig_ax = error_code;
+
+ return ex_handler_default(fixup, regs);
+}
+#endif
+
int ex_get_fixup_type(unsigned long ip)
{
const struct exception_table_entry *e = search_exception_tables(ip);
@@ -300,6 +374,10 @@ int fixup_exception(struct pt_regs *regs, int trapnr, unsigned long error_code,
return ex_handler_ucopy_len(e, regs, trapnr, fault_addr, reg, imm);
case EX_TYPE_ZEROPAD:
return ex_handler_zeropad(e, regs, fault_addr);
+#ifdef CONFIG_X86_FRED
+ case EX_TYPE_ERETU:
+ return ex_handler_eretu(e, regs, error_code);
+#endif
}
BUG();
}
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index d6375b3c633b..622d12ec7f08 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -34,6 +34,8 @@
#include <asm/kvm_para.h> /* kvm_handle_async_pf */
#include <asm/vdso.h> /* fixup_vdso_exception() */
#include <asm/irq_stack.h>
+#include <asm/fred.h>
+#include <asm/sev.h> /* snp_dump_hva_rmpentry() */
#define CREATE_TRACE_POINTS
#include <asm/trace/exceptions.h>
@@ -250,7 +252,7 @@ static noinline int vmalloc_fault(unsigned long address)
if (!pmd_k)
return -1;
- if (pmd_large(*pmd_k))
+ if (pmd_leaf(*pmd_k))
return 0;
pte_k = pte_offset_kernel(pmd_k, address);
@@ -319,7 +321,7 @@ static void dump_pagetable(unsigned long address)
* And let's rather not kmap-atomic the pte, just in case
* it's allocated already:
*/
- if (!low_pfn(pmd_pfn(*pmd)) || !pmd_present(*pmd) || pmd_large(*pmd))
+ if (!low_pfn(pmd_pfn(*pmd)) || !pmd_present(*pmd) || pmd_leaf(*pmd))
goto out;
pte = pte_offset_kernel(pmd, address);
@@ -368,7 +370,7 @@ static void dump_pagetable(unsigned long address)
goto bad;
pr_cont("P4D %lx ", p4d_val(*p4d));
- if (!p4d_present(*p4d) || p4d_large(*p4d))
+ if (!p4d_present(*p4d) || p4d_leaf(*p4d))
goto out;
pud = pud_offset(p4d, address);
@@ -376,7 +378,7 @@ static void dump_pagetable(unsigned long address)
goto bad;
pr_cont("PUD %lx ", pud_val(*pud));
- if (!pud_present(*pud) || pud_large(*pud))
+ if (!pud_present(*pud) || pud_leaf(*pud))
goto out;
pmd = pmd_offset(pud, address);
@@ -384,7 +386,7 @@ static void dump_pagetable(unsigned long address)
goto bad;
pr_cont("PMD %lx ", pmd_val(*pmd));
- if (!pmd_present(*pmd) || pmd_large(*pmd))
+ if (!pmd_present(*pmd) || pmd_leaf(*pmd))
goto out;
pte = pte_offset_kernel(pmd, address);
@@ -547,6 +549,7 @@ show_fault_oops(struct pt_regs *regs, unsigned long error_code, unsigned long ad
!(error_code & X86_PF_PROT) ? "not-present page" :
(error_code & X86_PF_RSVD) ? "reserved bit violation" :
(error_code & X86_PF_PK) ? "protection keys violation" :
+ (error_code & X86_PF_RMP) ? "RMP violation" :
"permissions violation");
if (!(error_code & X86_PF_USER) && user_mode(regs)) {
@@ -579,6 +582,9 @@ show_fault_oops(struct pt_regs *regs, unsigned long error_code, unsigned long ad
}
dump_pagetable(address);
+
+ if (error_code & X86_PF_RMP)
+ snp_dump_hva_rmpentry(address);
}
static noinline void
@@ -1030,21 +1036,21 @@ spurious_kernel_fault(unsigned long error_code, unsigned long address)
if (!p4d_present(*p4d))
return 0;
- if (p4d_large(*p4d))
+ if (p4d_leaf(*p4d))
return spurious_kernel_fault_check(error_code, (pte_t *) p4d);
pud = pud_offset(p4d, address);
if (!pud_present(*pud))
return 0;
- if (pud_large(*pud))
+ if (pud_leaf(*pud))
return spurious_kernel_fault_check(error_code, (pte_t *) pud);
pmd = pmd_offset(pud, address);
if (!pmd_present(*pmd))
return 0;
- if (pmd_large(*pmd))
+ if (pmd_leaf(*pmd))
return spurious_kernel_fault_check(error_code, (pte_t *) pmd);
pte = pte_offset_kernel(pmd, address);
@@ -1293,21 +1299,14 @@ void do_user_addr_fault(struct pt_regs *regs,
return;
}
- /*
- * It's safe to allow irq's after cr2 has been saved and the
- * vmalloc fault has been handled.
- *
- * User-mode registers count as a user access even for any
- * potential system fault or CPU buglet:
- */
- if (user_mode(regs)) {
- local_irq_enable();
- flags |= FAULT_FLAG_USER;
- } else {
- if (regs->flags & X86_EFLAGS_IF)
- local_irq_enable();
+ /* Legacy check - remove this after verifying that it doesn't trigger */
+ if (WARN_ON_ONCE(!(regs->flags & X86_EFLAGS_IF))) {
+ bad_area_nosemaphore(regs, error_code, address);
+ return;
}
+ local_irq_enable();
+
perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
/*
@@ -1323,6 +1322,14 @@ void do_user_addr_fault(struct pt_regs *regs,
if (error_code & X86_PF_INSTR)
flags |= FAULT_FLAG_INSTRUCTION;
+ /*
+ * We set FAULT_FLAG_USER based on the register state, not
+ * based on X86_PF_USER. User space accesses that cause
+ * system page faults are still user accesses.
+ */
+ if (user_mode(regs))
+ flags |= FAULT_FLAG_USER;
+
#ifdef CONFIG_X86_64
/*
* Faults in the vsyscall page might need emulation. The
@@ -1509,8 +1516,10 @@ handle_page_fault(struct pt_regs *regs, unsigned long error_code,
DEFINE_IDTENTRY_RAW_ERRORCODE(exc_page_fault)
{
- unsigned long address = read_cr2();
irqentry_state_t state;
+ unsigned long address;
+
+ address = cpu_feature_enabled(X86_FEATURE_FRED) ? fred_event_data(regs) : read_cr2();
prefetchw(&current->mm->mmap_lock);
diff --git a/arch/x86/mm/ident_map.c b/arch/x86/mm/ident_map.c
index f50cc210a981..968d7005f4a7 100644
--- a/arch/x86/mm/ident_map.c
+++ b/arch/x86/mm/ident_map.c
@@ -26,31 +26,18 @@ static int ident_pud_init(struct x86_mapping_info *info, pud_t *pud_page,
for (; addr < end; addr = next) {
pud_t *pud = pud_page + pud_index(addr);
pmd_t *pmd;
- bool use_gbpage;
next = (addr & PUD_MASK) + PUD_SIZE;
if (next > end)
next = end;
- /* if this is already a gbpage, this portion is already mapped */
- if (pud_large(*pud))
- continue;
-
- /* Is using a gbpage allowed? */
- use_gbpage = info->direct_gbpages;
-
- /* Don't use gbpage if it maps more than the requested region. */
- /* at the begining: */
- use_gbpage &= ((addr & ~PUD_MASK) == 0);
- /* ... or at the end: */
- use_gbpage &= ((next & ~PUD_MASK) == 0);
-
- /* Never overwrite existing mappings */
- use_gbpage &= !pud_present(*pud);
-
- if (use_gbpage) {
+ if (info->direct_gbpages) {
pud_t pudval;
+ if (pud_present(*pud))
+ continue;
+
+ addr &= PUD_MASK;
pudval = __pud((addr - info->offset) | info->page_flag);
set_pud(pud, pudval);
continue;
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index b63403d7179d..ac41b1e0940d 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -463,7 +463,7 @@ void __init native_pagetable_init(void)
break;
/* should not be large page here */
- if (pmd_large(*pmd)) {
+ if (pmd_leaf(*pmd)) {
pr_warn("try to clear pte for ram above max_low_pfn: pfn: %lx pmd: %p pmd phys: %lx, but pmd is big page and is not using pte !\n",
pfn, pmd, __pa(pmd));
BUG_ON(1);
@@ -800,6 +800,4 @@ void mark_rodata_ro(void)
set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT);
#endif
mark_nxdata_nx();
- if (__supported_pte_mask & _PAGE_NX)
- debug_checkwx();
}
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index a0dffaca6d2b..7e177856ee4f 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -530,7 +530,7 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long paddr, unsigned long paddr_end,
}
if (!pmd_none(*pmd)) {
- if (!pmd_large(*pmd)) {
+ if (!pmd_leaf(*pmd)) {
spin_lock(&init_mm.page_table_lock);
pte = (pte_t *)pmd_page_vaddr(*pmd);
paddr_last = phys_pte_init(pte, paddr,
@@ -617,7 +617,7 @@ phys_pud_init(pud_t *pud_page, unsigned long paddr, unsigned long paddr_end,
}
if (!pud_none(*pud)) {
- if (!pud_large(*pud)) {
+ if (!pud_leaf(*pud)) {
pmd = pmd_offset(pud, 0);
paddr_last = phys_pmd_init(pmd, paddr,
paddr_end,
@@ -1114,7 +1114,7 @@ remove_pmd_table(pmd_t *pmd_start, unsigned long addr, unsigned long end,
if (!pmd_present(*pmd))
continue;
- if (pmd_large(*pmd)) {
+ if (pmd_leaf(*pmd)) {
if (IS_ALIGNED(addr, PMD_SIZE) &&
IS_ALIGNED(next, PMD_SIZE)) {
if (!direct)
@@ -1163,7 +1163,7 @@ remove_pud_table(pud_t *pud_start, unsigned long addr, unsigned long end,
if (!pud_present(*pud))
continue;
- if (pud_large(*pud) &&
+ if (pud_leaf(*pud) &&
IS_ALIGNED(addr, PUD_SIZE) &&
IS_ALIGNED(next, PUD_SIZE)) {
spin_lock(&init_mm.page_table_lock);
@@ -1197,7 +1197,7 @@ remove_p4d_table(p4d_t *p4d_start, unsigned long addr, unsigned long end,
if (!p4d_present(*p4d))
continue;
- BUILD_BUG_ON(p4d_large(*p4d));
+ BUILD_BUG_ON(p4d_leaf(*p4d));
pud_base = pud_offset(p4d, 0);
remove_pud_table(pud_base, addr, next, altmap, direct);
@@ -1412,8 +1412,6 @@ void mark_rodata_ro(void)
(void *)text_end, (void *)rodata_start);
free_kernel_image_pages("unused kernel image (rodata/data gap)",
(void *)rodata_end, (void *)_sdata);
-
- debug_checkwx();
}
/*
@@ -1522,9 +1520,9 @@ void __meminit vmemmap_set_pmd(pmd_t *pmd, void *p, int node,
int __meminit vmemmap_check_pmd(pmd_t *pmd, int node,
unsigned long addr, unsigned long next)
{
- int large = pmd_large(*pmd);
+ int large = pmd_leaf(*pmd);
- if (pmd_large(*pmd)) {
+ if (pmd_leaf(*pmd)) {
vmemmap_verify((pte_t *)pmd, node, addr, next);
vmemmap_use_sub_pmd(addr, next);
}
diff --git a/arch/x86/mm/kasan_init_64.c b/arch/x86/mm/kasan_init_64.c
index 0302491d799d..9dddf19a5571 100644
--- a/arch/x86/mm/kasan_init_64.c
+++ b/arch/x86/mm/kasan_init_64.c
@@ -95,7 +95,7 @@ static void __init kasan_populate_pud(pud_t *pud, unsigned long addr,
pmd = pmd_offset(pud, addr);
do {
next = pmd_addr_end(addr, end);
- if (!pmd_large(*pmd))
+ if (!pmd_leaf(*pmd))
kasan_populate_pmd(pmd, addr, next, nid);
} while (pmd++, addr = next, addr != end);
}
@@ -115,7 +115,7 @@ static void __init kasan_populate_p4d(p4d_t *p4d, unsigned long addr,
pud = pud_offset(p4d, addr);
do {
next = pud_addr_end(addr, end);
- if (!pud_large(*pud))
+ if (!pud_leaf(*pud))
kasan_populate_pud(pud, addr, next, nid);
} while (pud++, addr = next, addr != end);
}
diff --git a/arch/x86/mm/mem_encrypt.c b/arch/x86/mm/mem_encrypt.c
index c290c55b632b..6f3b3e028718 100644
--- a/arch/x86/mm/mem_encrypt.c
+++ b/arch/x86/mm/mem_encrypt.c
@@ -14,6 +14,8 @@
#include <linux/mem_encrypt.h>
#include <linux/virtio_anchor.h>
+#include <asm/sev.h>
+
/* Override for DMA direct allocation check - ARCH_HAS_FORCE_DMA_UNENCRYPTED */
bool force_dma_unencrypted(struct device *dev)
{
@@ -42,38 +44,45 @@ bool force_dma_unencrypted(struct device *dev)
static void print_mem_encrypt_feature_info(void)
{
- pr_info("Memory Encryption Features active:");
-
- if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) {
- pr_cont(" Intel TDX\n");
- return;
- }
+ pr_info("Memory Encryption Features active: ");
- pr_cont(" AMD");
+ switch (cc_vendor) {
+ case CC_VENDOR_INTEL:
+ pr_cont("Intel TDX\n");
+ break;
+ case CC_VENDOR_AMD:
+ pr_cont("AMD");
- /* Secure Memory Encryption */
- if (cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT)) {
+ /* Secure Memory Encryption */
+ if (cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT)) {
/*
* SME is mutually exclusive with any of the SEV
* features below.
- */
- pr_cont(" SME\n");
- return;
- }
+ */
+ pr_cont(" SME\n");
+ return;
+ }
- /* Secure Encrypted Virtualization */
- if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
- pr_cont(" SEV");
+ /* Secure Encrypted Virtualization */
+ if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
+ pr_cont(" SEV");
+
+ /* Encrypted Register State */
+ if (cc_platform_has(CC_ATTR_GUEST_STATE_ENCRYPT))
+ pr_cont(" SEV-ES");
- /* Encrypted Register State */
- if (cc_platform_has(CC_ATTR_GUEST_STATE_ENCRYPT))
- pr_cont(" SEV-ES");
+ /* Secure Nested Paging */
+ if (cc_platform_has(CC_ATTR_GUEST_SEV_SNP))
+ pr_cont(" SEV-SNP");
- /* Secure Nested Paging */
- if (cc_platform_has(CC_ATTR_GUEST_SEV_SNP))
- pr_cont(" SEV-SNP");
+ pr_cont("\n");
- pr_cont("\n");
+ sev_show_status();
+
+ break;
+ default:
+ pr_cont("Unknown\n");
+ }
}
/* Architecture __weak replacement functions */
diff --git a/arch/x86/mm/mem_encrypt_amd.c b/arch/x86/mm/mem_encrypt_amd.c
index 70b91de2e053..422602f6039b 100644
--- a/arch/x86/mm/mem_encrypt_amd.c
+++ b/arch/x86/mm/mem_encrypt_amd.c
@@ -492,6 +492,24 @@ void __init sme_early_init(void)
*/
if (sev_status & MSR_AMD64_SEV_ENABLED)
ia32_disable();
+
+ /*
+ * Override init functions that scan the ROM region in SEV-SNP guests,
+ * as this memory is not pre-validated and would thus cause a crash.
+ */
+ if (sev_status & MSR_AMD64_SEV_SNP_ENABLED) {
+ x86_init.mpparse.find_mptable = x86_init_noop;
+ x86_init.pci.init_irq = x86_init_noop;
+ x86_init.resources.probe_roms = x86_init_noop;
+
+ /*
+ * DMI setup behavior for SEV-SNP guests depends on
+ * efi_enabled(EFI_CONFIG_TABLES), which hasn't been
+ * parsed yet. snp_dmi_setup() will run after that
+ * parsing has happened.
+ */
+ x86_init.resources.dmi_setup = snp_dmi_setup;
+ }
}
void __init mem_encrypt_free_decrypted_mem(void)
diff --git a/arch/x86/mm/mem_encrypt_identity.c b/arch/x86/mm/mem_encrypt_identity.c
index d73aeb16417f..ac33b2263a43 100644
--- a/arch/x86/mm/mem_encrypt_identity.c
+++ b/arch/x86/mm/mem_encrypt_identity.c
@@ -41,9 +41,9 @@
#include <linux/mem_encrypt.h>
#include <linux/cc_platform.h>
+#include <asm/init.h>
#include <asm/setup.h>
#include <asm/sections.h>
-#include <asm/cmdline.h>
#include <asm/coco.h>
#include <asm/sev.h>
@@ -95,11 +95,7 @@ struct sme_populate_pgd_data {
*/
static char sme_workarea[2 * PMD_SIZE] __section(".init.scratch");
-static char sme_cmdline_arg[] __initdata = "mem_encrypt";
-static char sme_cmdline_on[] __initdata = "on";
-static char sme_cmdline_off[] __initdata = "off";
-
-static void __init sme_clear_pgd(struct sme_populate_pgd_data *ppd)
+static void __head sme_clear_pgd(struct sme_populate_pgd_data *ppd)
{
unsigned long pgd_start, pgd_end, pgd_size;
pgd_t *pgd_p;
@@ -114,7 +110,7 @@ static void __init sme_clear_pgd(struct sme_populate_pgd_data *ppd)
memset(pgd_p, 0, pgd_size);
}
-static pud_t __init *sme_prepare_pgd(struct sme_populate_pgd_data *ppd)
+static pud_t __head *sme_prepare_pgd(struct sme_populate_pgd_data *ppd)
{
pgd_t *pgd;
p4d_t *p4d;
@@ -145,13 +141,13 @@ static pud_t __init *sme_prepare_pgd(struct sme_populate_pgd_data *ppd)
set_pud(pud, __pud(PUD_FLAGS | __pa(pmd)));
}
- if (pud_large(*pud))
+ if (pud_leaf(*pud))
return NULL;
return pud;
}
-static void __init sme_populate_pgd_large(struct sme_populate_pgd_data *ppd)
+static void __head sme_populate_pgd_large(struct sme_populate_pgd_data *ppd)
{
pud_t *pud;
pmd_t *pmd;
@@ -161,13 +157,13 @@ static void __init sme_populate_pgd_large(struct sme_populate_pgd_data *ppd)
return;
pmd = pmd_offset(pud, ppd->vaddr);
- if (pmd_large(*pmd))
+ if (pmd_leaf(*pmd))
return;
set_pmd(pmd, __pmd(ppd->paddr | ppd->pmd_flags));
}
-static void __init sme_populate_pgd(struct sme_populate_pgd_data *ppd)
+static void __head sme_populate_pgd(struct sme_populate_pgd_data *ppd)
{
pud_t *pud;
pmd_t *pmd;
@@ -185,7 +181,7 @@ static void __init sme_populate_pgd(struct sme_populate_pgd_data *ppd)
set_pmd(pmd, __pmd(PMD_FLAGS | __pa(pte)));
}
- if (pmd_large(*pmd))
+ if (pmd_leaf(*pmd))
return;
pte = pte_offset_kernel(pmd, ppd->vaddr);
@@ -193,7 +189,7 @@ static void __init sme_populate_pgd(struct sme_populate_pgd_data *ppd)
set_pte(pte, __pte(ppd->paddr | ppd->pte_flags));
}
-static void __init __sme_map_range_pmd(struct sme_populate_pgd_data *ppd)
+static void __head __sme_map_range_pmd(struct sme_populate_pgd_data *ppd)
{
while (ppd->vaddr < ppd->vaddr_end) {
sme_populate_pgd_large(ppd);
@@ -203,7 +199,7 @@ static void __init __sme_map_range_pmd(struct sme_populate_pgd_data *ppd)
}
}
-static void __init __sme_map_range_pte(struct sme_populate_pgd_data *ppd)
+static void __head __sme_map_range_pte(struct sme_populate_pgd_data *ppd)
{
while (ppd->vaddr < ppd->vaddr_end) {
sme_populate_pgd(ppd);
@@ -213,7 +209,7 @@ static void __init __sme_map_range_pte(struct sme_populate_pgd_data *ppd)
}
}
-static void __init __sme_map_range(struct sme_populate_pgd_data *ppd,
+static void __head __sme_map_range(struct sme_populate_pgd_data *ppd,
pmdval_t pmd_flags, pteval_t pte_flags)
{
unsigned long vaddr_end;
@@ -237,22 +233,22 @@ static void __init __sme_map_range(struct sme_populate_pgd_data *ppd,
__sme_map_range_pte(ppd);
}
-static void __init sme_map_range_encrypted(struct sme_populate_pgd_data *ppd)
+static void __head sme_map_range_encrypted(struct sme_populate_pgd_data *ppd)
{
__sme_map_range(ppd, PMD_FLAGS_ENC, PTE_FLAGS_ENC);
}
-static void __init sme_map_range_decrypted(struct sme_populate_pgd_data *ppd)
+static void __head sme_map_range_decrypted(struct sme_populate_pgd_data *ppd)
{
__sme_map_range(ppd, PMD_FLAGS_DEC, PTE_FLAGS_DEC);
}
-static void __init sme_map_range_decrypted_wp(struct sme_populate_pgd_data *ppd)
+static void __head sme_map_range_decrypted_wp(struct sme_populate_pgd_data *ppd)
{
__sme_map_range(ppd, PMD_FLAGS_DEC_WP, PTE_FLAGS_DEC_WP);
}
-static unsigned long __init sme_pgtable_calc(unsigned long len)
+static unsigned long __head sme_pgtable_calc(unsigned long len)
{
unsigned long entries = 0, tables = 0;
@@ -289,7 +285,7 @@ static unsigned long __init sme_pgtable_calc(unsigned long len)
return entries + tables;
}
-void __init sme_encrypt_kernel(struct boot_params *bp)
+void __head sme_encrypt_kernel(struct boot_params *bp)
{
unsigned long workarea_start, workarea_end, workarea_len;
unsigned long execute_start, execute_end, execute_len;
@@ -305,7 +301,8 @@ void __init sme_encrypt_kernel(struct boot_params *bp)
* instrumentation or checking boot_cpu_data in the cc_platform_has()
* function.
*/
- if (!sme_get_me_mask() || sev_status & MSR_AMD64_SEV_ENABLED)
+ if (!sme_get_me_mask() ||
+ RIP_REL_REF(sev_status) & MSR_AMD64_SEV_ENABLED)
return;
/*
@@ -323,9 +320,8 @@ void __init sme_encrypt_kernel(struct boot_params *bp)
* memory from being cached.
*/
- /* Physical addresses gives us the identity mapped virtual addresses */
- kernel_start = __pa_symbol(_text);
- kernel_end = ALIGN(__pa_symbol(_end), PMD_SIZE);
+ kernel_start = (unsigned long)RIP_REL_REF(_text);
+ kernel_end = ALIGN((unsigned long)RIP_REL_REF(_end), PMD_SIZE);
kernel_len = kernel_end - kernel_start;
initrd_start = 0;
@@ -343,14 +339,6 @@ void __init sme_encrypt_kernel(struct boot_params *bp)
#endif
/*
- * We're running identity mapped, so we must obtain the address to the
- * SME encryption workarea using rip-relative addressing.
- */
- asm ("lea sme_workarea(%%rip), %0"
- : "=r" (workarea_start)
- : "p" (sme_workarea));
-
- /*
* Calculate required number of workarea bytes needed:
* executable encryption area size:
* stack page (PAGE_SIZE)
@@ -359,7 +347,7 @@ void __init sme_encrypt_kernel(struct boot_params *bp)
* pagetable structures for the encryption of the kernel
* pagetable structures for workarea (in case not currently mapped)
*/
- execute_start = workarea_start;
+ execute_start = workarea_start = (unsigned long)RIP_REL_REF(sme_workarea);
execute_end = execute_start + (PAGE_SIZE * 2) + PMD_SIZE;
execute_len = execute_end - execute_start;
@@ -502,14 +490,11 @@ void __init sme_encrypt_kernel(struct boot_params *bp)
native_write_cr3(__native_read_cr3());
}
-void __init sme_enable(struct boot_params *bp)
+void __head sme_enable(struct boot_params *bp)
{
- const char *cmdline_ptr, *cmdline_arg, *cmdline_on, *cmdline_off;
unsigned int eax, ebx, ecx, edx;
unsigned long feature_mask;
- bool active_by_default;
unsigned long me_mask;
- char buffer[16];
bool snp;
u64 msr;
@@ -543,15 +528,18 @@ void __init sme_enable(struct boot_params *bp)
me_mask = 1UL << (ebx & 0x3f);
/* Check the SEV MSR whether SEV or SME is enabled */
- sev_status = __rdmsr(MSR_AMD64_SEV);
- feature_mask = (sev_status & MSR_AMD64_SEV_ENABLED) ? AMD_SEV_BIT : AMD_SME_BIT;
+ RIP_REL_REF(sev_status) = msr = __rdmsr(MSR_AMD64_SEV);
+ feature_mask = (msr & MSR_AMD64_SEV_ENABLED) ? AMD_SEV_BIT : AMD_SME_BIT;
/* The SEV-SNP CC blob should never be present unless SEV-SNP is enabled. */
- if (snp && !(sev_status & MSR_AMD64_SEV_SNP_ENABLED))
+ if (snp && !(msr & MSR_AMD64_SEV_SNP_ENABLED))
snp_abort();
/* Check if memory encryption is enabled */
if (feature_mask == AMD_SME_BIT) {
+ if (!(bp->hdr.xloadflags & XLF_MEM_ENCRYPTION))
+ return;
+
/*
* No SME if Hypervisor bit is set. This check is here to
* prevent a guest from trying to enable SME. For running as a
@@ -571,48 +559,10 @@ void __init sme_enable(struct boot_params *bp)
msr = __rdmsr(MSR_AMD64_SYSCFG);
if (!(msr & MSR_AMD64_SYSCFG_MEM_ENCRYPT))
return;
- } else {
- /* SEV state cannot be controlled by a command line option */
- sme_me_mask = me_mask;
- goto out;
}
- /*
- * Fixups have not been applied to phys_base yet and we're running
- * identity mapped, so we must obtain the address to the SME command
- * line argument data using rip-relative addressing.
- */
- asm ("lea sme_cmdline_arg(%%rip), %0"
- : "=r" (cmdline_arg)
- : "p" (sme_cmdline_arg));
- asm ("lea sme_cmdline_on(%%rip), %0"
- : "=r" (cmdline_on)
- : "p" (sme_cmdline_on));
- asm ("lea sme_cmdline_off(%%rip), %0"
- : "=r" (cmdline_off)
- : "p" (sme_cmdline_off));
-
- if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT))
- active_by_default = true;
- else
- active_by_default = false;
-
- cmdline_ptr = (const char *)((u64)bp->hdr.cmd_line_ptr |
- ((u64)bp->ext_cmd_line_ptr << 32));
-
- if (cmdline_find_option(cmdline_ptr, cmdline_arg, buffer, sizeof(buffer)) < 0)
- return;
-
- if (!strncmp(buffer, cmdline_on, sizeof(buffer)))
- sme_me_mask = me_mask;
- else if (!strncmp(buffer, cmdline_off, sizeof(buffer)))
- sme_me_mask = 0;
- else
- sme_me_mask = active_by_default ? me_mask : 0;
-out:
- if (sme_me_mask) {
- physical_mask &= ~sme_me_mask;
- cc_vendor = CC_VENDOR_AMD;
- cc_set_mask(sme_me_mask);
- }
+ RIP_REL_REF(sme_me_mask) = me_mask;
+ physical_mask &= ~me_mask;
+ cc_vendor = CC_VENDOR_AMD;
+ cc_set_mask(me_mask);
}
diff --git a/arch/x86/mm/numa_32.c b/arch/x86/mm/numa_32.c
index 104544359d69..025fd7ea5d69 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 <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 0904d7e8e126..36b603d0cdde 100644
--- a/arch/x86/mm/pat/memtype.c
+++ b/arch/x86/mm/pat/memtype.c
@@ -240,6 +240,8 @@ void pat_cpu_init(void)
}
wrmsrl(MSR_IA32_CR_PAT, pat_msr_val);
+
+ __flush_tlb_all();
}
/**
@@ -296,13 +298,8 @@ void __init pat_bp_init(void)
/*
* Xen PV doesn't allow to set PAT MSR, but all cache modes are
* supported.
- * When running as TDX guest setting the PAT MSR won't work either
- * due to the requirement to set CR0.CD when doing so. Rely on
- * firmware to have set the PAT MSR correctly.
*/
- if (pat_disabled ||
- cpu_feature_enabled(X86_FEATURE_XENPV) ||
- cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) {
+ if (pat_disabled || cpu_feature_enabled(X86_FEATURE_XENPV)) {
init_cache_modes(pat_msr_val);
return;
}
@@ -950,6 +947,38 @@ static void free_pfn_range(u64 paddr, unsigned long size)
memtype_free(paddr, paddr + size);
}
+static int get_pat_info(struct vm_area_struct *vma, resource_size_t *paddr,
+ pgprot_t *pgprot)
+{
+ unsigned long prot;
+
+ VM_WARN_ON_ONCE(!(vma->vm_flags & VM_PAT));
+
+ /*
+ * We need the starting PFN and cachemode used for track_pfn_remap()
+ * that covered the whole VMA. For most mappings, we can obtain that
+ * information from the page tables. For COW mappings, we might now
+ * suddenly have anon folios mapped and follow_phys() will fail.
+ *
+ * Fallback to using vma->vm_pgoff, see remap_pfn_range_notrack(), to
+ * 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 (pgprot)
+ *pgprot = __pgprot(prot);
+ return 0;
+ }
+ if (is_cow_mapping(vma->vm_flags)) {
+ if (pgprot)
+ return -EINVAL;
+ *paddr = (resource_size_t)vma->vm_pgoff << PAGE_SHIFT;
+ return 0;
+ }
+ WARN_ON_ONCE(1);
+ return -EINVAL;
+}
+
/*
* track_pfn_copy is called when vma that is covering the pfnmap gets
* copied through copy_page_range().
@@ -960,20 +989,13 @@ static void free_pfn_range(u64 paddr, unsigned long size)
int track_pfn_copy(struct vm_area_struct *vma)
{
resource_size_t paddr;
- unsigned long prot;
unsigned long vma_size = vma->vm_end - vma->vm_start;
pgprot_t pgprot;
if (vma->vm_flags & VM_PAT) {
- /*
- * reserve the whole chunk covered by vma. We need the
- * starting address and protection from pte.
- */
- if (follow_phys(vma, vma->vm_start, 0, &prot, &paddr)) {
- WARN_ON_ONCE(1);
+ if (get_pat_info(vma, &paddr, &pgprot))
return -EINVAL;
- }
- pgprot = __pgprot(prot);
+ /* reserve the whole chunk covered by vma. */
return reserve_pfn_range(paddr, vma_size, &pgprot, 1);
}
@@ -1048,7 +1070,6 @@ void untrack_pfn(struct vm_area_struct *vma, unsigned long pfn,
unsigned long size, bool mm_wr_locked)
{
resource_size_t paddr;
- unsigned long prot;
if (vma && !(vma->vm_flags & VM_PAT))
return;
@@ -1056,11 +1077,8 @@ void untrack_pfn(struct vm_area_struct *vma, unsigned long pfn,
/* free the chunk starting from pfn or the whole chunk */
paddr = (resource_size_t)pfn << PAGE_SHIFT;
if (!paddr && !size) {
- if (follow_phys(vma, vma->vm_start, 0, &prot, &paddr)) {
- WARN_ON_ONCE(1);
+ if (get_pat_info(vma, &paddr, NULL))
return;
- }
-
size = vma->vm_end - vma->vm_start;
}
free_pfn_range(paddr, size);
diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
index 102880404046..80c9037ffadf 100644
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -676,7 +676,7 @@ pte_t *lookup_address_in_pgd(pgd_t *pgd, unsigned long address,
return NULL;
*level = PG_LEVEL_512G;
- if (p4d_large(*p4d) || !p4d_present(*p4d))
+ if (p4d_leaf(*p4d) || !p4d_present(*p4d))
return (pte_t *)p4d;
pud = pud_offset(p4d, address);
@@ -684,7 +684,7 @@ pte_t *lookup_address_in_pgd(pgd_t *pgd, unsigned long address,
return NULL;
*level = PG_LEVEL_1G;
- if (pud_large(*pud) || !pud_present(*pud))
+ if (pud_leaf(*pud) || !pud_present(*pud))
return (pte_t *)pud;
pmd = pmd_offset(pud, address);
@@ -692,7 +692,7 @@ pte_t *lookup_address_in_pgd(pgd_t *pgd, unsigned long address,
return NULL;
*level = PG_LEVEL_2M;
- if (pmd_large(*pmd) || !pmd_present(*pmd))
+ if (pmd_leaf(*pmd) || !pmd_present(*pmd))
return (pte_t *)pmd;
*level = PG_LEVEL_4K;
@@ -739,11 +739,11 @@ pmd_t *lookup_pmd_address(unsigned long address)
return NULL;
p4d = p4d_offset(pgd, address);
- if (p4d_none(*p4d) || p4d_large(*p4d) || !p4d_present(*p4d))
+ if (p4d_none(*p4d) || p4d_leaf(*p4d) || !p4d_present(*p4d))
return NULL;
pud = pud_offset(p4d, address);
- if (pud_none(*pud) || pud_large(*pud) || !pud_present(*pud))
+ if (pud_none(*pud) || pud_leaf(*pud) || !pud_present(*pud))
return NULL;
return pmd_offset(pud, address);
@@ -1233,7 +1233,7 @@ static void unmap_pmd_range(pud_t *pud, unsigned long start, unsigned long end)
* Try to unmap in 2M chunks.
*/
while (end - start >= PMD_SIZE) {
- if (pmd_large(*pmd))
+ if (pmd_leaf(*pmd))
pmd_clear(pmd);
else
__unmap_pmd_range(pud, pmd, start, start + PMD_SIZE);
@@ -1278,7 +1278,7 @@ static void unmap_pud_range(p4d_t *p4d, unsigned long start, unsigned long end)
*/
while (end - start >= PUD_SIZE) {
- if (pud_large(*pud))
+ if (pud_leaf(*pud))
pud_clear(pud);
else
unmap_pmd_range(pud, start, start + PUD_SIZE);
@@ -2157,7 +2157,7 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
/* Notify hypervisor that we are about to set/clr encryption attribute. */
if (!x86_platform.guest.enc_status_change_prepare(addr, numpages, enc))
- return -EIO;
+ goto vmm_fail;
ret = __change_page_attr_set_clr(&cpa, 1);
@@ -2170,13 +2170,20 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
*/
cpa_flush(&cpa, 0);
+ if (ret)
+ return ret;
+
/* Notify hypervisor that we have successfully set/clr encryption attribute. */
- if (!ret) {
- if (!x86_platform.guest.enc_status_change_finish(addr, numpages, enc))
- ret = -EIO;
- }
+ if (!x86_platform.guest.enc_status_change_finish(addr, numpages, enc))
+ goto vmm_fail;
- return ret;
+ 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");
+
+ return -EIO;
}
static int __set_memory_enc_dec(unsigned long addr, int numpages, bool enc)
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
index 0cbc1b8e8e3d..d007591b8059 100644
--- a/arch/x86/mm/pgtable.c
+++ b/arch/x86/mm/pgtable.c
@@ -293,7 +293,7 @@ static void pgd_mop_up_pmds(struct mm_struct *mm, pgd_t *pgdp)
for (i = 0; i < PREALLOCATED_PMDS; i++)
mop_up_one_pmd(mm, &pgdp[i]);
-#ifdef CONFIG_PAGE_TABLE_ISOLATION
+#ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
if (!boot_cpu_has(X86_FEATURE_PTI))
return;
@@ -325,7 +325,7 @@ static void pgd_prepopulate_pmd(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmds[])
}
}
-#ifdef CONFIG_PAGE_TABLE_ISOLATION
+#ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
static void pgd_prepopulate_user_pmd(struct mm_struct *mm,
pgd_t *k_pgd, pmd_t *pmds[])
{
@@ -777,7 +777,7 @@ int pmd_set_huge(pmd_t *pmd, phys_addr_t addr, pgprot_t prot)
*/
int pud_clear_huge(pud_t *pud)
{
- if (pud_large(*pud)) {
+ if (pud_leaf(*pud)) {
pud_clear(pud);
return 1;
}
@@ -792,7 +792,7 @@ int pud_clear_huge(pud_t *pud)
*/
int pmd_clear_huge(pmd_t *pmd)
{
- if (pmd_large(*pmd)) {
+ if (pmd_leaf(*pmd)) {
pmd_clear(pmd);
return 1;
}
diff --git a/arch/x86/mm/pti.c b/arch/x86/mm/pti.c
index 669ba1c345b3..2e69abf4f852 100644
--- a/arch/x86/mm/pti.c
+++ b/arch/x86/mm/pti.c
@@ -185,7 +185,7 @@ static p4d_t *pti_user_pagetable_walk_p4d(unsigned long address)
set_pgd(pgd, __pgd(_KERNPG_TABLE | __pa(new_p4d_page)));
}
- BUILD_BUG_ON(pgd_large(*pgd) != 0);
+ BUILD_BUG_ON(pgd_leaf(*pgd) != 0);
return p4d_offset(pgd, address);
}
@@ -206,7 +206,7 @@ static pmd_t *pti_user_pagetable_walk_pmd(unsigned long address)
if (!p4d)
return NULL;
- BUILD_BUG_ON(p4d_large(*p4d) != 0);
+ BUILD_BUG_ON(p4d_leaf(*p4d) != 0);
if (p4d_none(*p4d)) {
unsigned long new_pud_page = __get_free_page(gfp);
if (WARN_ON_ONCE(!new_pud_page))
@@ -217,7 +217,7 @@ static pmd_t *pti_user_pagetable_walk_pmd(unsigned long address)
pud = pud_offset(p4d, address);
/* The user page tables do not use large mappings: */
- if (pud_large(*pud)) {
+ if (pud_leaf(*pud)) {
WARN_ON(1);
return NULL;
}
@@ -252,7 +252,7 @@ static pte_t *pti_user_pagetable_walk_pte(unsigned long address)
return NULL;
/* We can't do anything sensible if we hit a large mapping. */
- if (pmd_large(*pmd)) {
+ if (pmd_leaf(*pmd)) {
WARN_ON(1);
return NULL;
}
@@ -341,7 +341,7 @@ pti_clone_pgtable(unsigned long start, unsigned long end,
continue;
}
- if (pmd_large(*pmd) || level == PTI_CLONE_PMD) {
+ if (pmd_leaf(*pmd) || level == PTI_CLONE_PMD) {
target_pmd = pti_user_pagetable_walk_pmd(addr);
if (WARN_ON(!target_pmd))
return;
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index 5768d386efab..44ac64f3a047 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -89,10 +89,10 @@
#define CR3_HW_ASID_BITS 12
/*
- * When enabled, PAGE_TABLE_ISOLATION consumes a single bit for
+ * When enabled, MITIGATION_PAGE_TABLE_ISOLATION consumes a single bit for
* user/kernel switches
*/
-#ifdef CONFIG_PAGE_TABLE_ISOLATION
+#ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
# define PTI_CONSUMED_PCID_BITS 1
#else
# define PTI_CONSUMED_PCID_BITS 0
@@ -114,7 +114,7 @@ static inline u16 kern_pcid(u16 asid)
{
VM_WARN_ON_ONCE(asid > MAX_ASID_AVAILABLE);
-#ifdef CONFIG_PAGE_TABLE_ISOLATION
+#ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
/*
* Make sure that the dynamic ASID space does not conflict with the
* bit we are using to switch between user and kernel ASIDs.
@@ -149,7 +149,7 @@ static inline u16 kern_pcid(u16 asid)
static inline u16 user_pcid(u16 asid)
{
u16 ret = kern_pcid(asid);
-#ifdef CONFIG_PAGE_TABLE_ISOLATION
+#ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
ret |= 1 << X86_CR3_PTI_PCID_USER_BIT;
#endif
return ret;
@@ -262,7 +262,7 @@ static void choose_new_asid(struct mm_struct *next, u64 next_tlb_gen,
static inline void invalidate_user_asid(u16 asid)
{
/* There is no user ASID if address space separation is off */
- if (!IS_ENABLED(CONFIG_PAGE_TABLE_ISOLATION))
+ if (!IS_ENABLED(CONFIG_MITIGATION_PAGE_TABLE_ISOLATION))
return;
/*
@@ -299,7 +299,7 @@ static void load_new_mm_cr3(pgd_t *pgdir, u16 new_asid, unsigned long lam,
write_cr3(new_mm_cr3);
}
-void leave_mm(int cpu)
+void leave_mm(void)
{
struct mm_struct *loaded_mm = this_cpu_read(cpu_tlbstate.loaded_mm);
@@ -327,7 +327,7 @@ void switch_mm(struct mm_struct *prev, struct mm_struct *next,
unsigned long flags;
local_irq_save(flags);
- switch_mm_irqs_off(prev, next, tsk);
+ switch_mm_irqs_off(NULL, next, tsk);
local_irq_restore(flags);
}
@@ -492,10 +492,16 @@ void cr4_update_pce(void *ignored)
static inline void cr4_update_pce_mm(struct mm_struct *mm) { }
#endif
-void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
+/*
+ * This optimizes when not actually switching mm's. Some architectures use the
+ * 'unused' argument for this optimization, but x86 must use
+ * 'cpu_tlbstate.loaded_mm' instead because it does not always keep
+ * 'current->active_mm' up to date.
+ */
+void switch_mm_irqs_off(struct mm_struct *unused, struct mm_struct *next,
struct task_struct *tsk)
{
- struct mm_struct *real_prev = this_cpu_read(cpu_tlbstate.loaded_mm);
+ struct mm_struct *prev = this_cpu_read(cpu_tlbstate.loaded_mm);
u16 prev_asid = this_cpu_read(cpu_tlbstate.loaded_mm_asid);
unsigned long new_lam = mm_lam_cr3_mask(next);
bool was_lazy = this_cpu_read(cpu_tlbstate_shared.is_lazy);
@@ -504,15 +510,6 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
bool need_flush;
u16 new_asid;
- /*
- * NB: The scheduler will call us with prev == next when switching
- * from lazy TLB mode to normal mode if active_mm isn't changing.
- * When this happens, we don't assume that CR3 (and hence
- * cpu_tlbstate.loaded_mm) matches next.
- *
- * NB: leave_mm() calls us with prev == NULL and tsk == NULL.
- */
-
/* We don't want flush_tlb_func() to run concurrently with us. */
if (IS_ENABLED(CONFIG_PROVE_LOCKING))
WARN_ON_ONCE(!irqs_disabled());
@@ -527,7 +524,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
* isn't free.
*/
#ifdef CONFIG_DEBUG_VM
- if (WARN_ON_ONCE(__read_cr3() != build_cr3(real_prev->pgd, prev_asid,
+ if (WARN_ON_ONCE(__read_cr3() != build_cr3(prev->pgd, prev_asid,
tlbstate_lam_cr3_mask()))) {
/*
* If we were to BUG here, we'd be very likely to kill
@@ -559,7 +556,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
* provides that full memory barrier and core serializing
* instruction.
*/
- if (real_prev == next) {
+ if (prev == next) {
/* Not actually switching mm's */
VM_WARN_ON(this_cpu_read(cpu_tlbstate.ctxs[prev_asid].ctx_id) !=
next->context.ctx_id);
@@ -574,7 +571,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
* mm_cpumask. The TLB shootdown code can figure out from
* cpu_tlbstate_shared.is_lazy whether or not to send an IPI.
*/
- if (WARN_ON_ONCE(real_prev != &init_mm &&
+ if (WARN_ON_ONCE(prev != &init_mm &&
!cpumask_test_cpu(cpu, mm_cpumask(next))))
cpumask_set_cpu(cpu, mm_cpumask(next));
@@ -616,10 +613,10 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
* Skip kernel threads; we never send init_mm TLB flushing IPIs,
* but the bitmap manipulation can cause cache line contention.
*/
- if (real_prev != &init_mm) {
+ if (prev != &init_mm) {
VM_WARN_ON_ONCE(!cpumask_test_cpu(cpu,
- mm_cpumask(real_prev)));
- cpumask_clear_cpu(cpu, mm_cpumask(real_prev));
+ mm_cpumask(prev)));
+ cpumask_clear_cpu(cpu, mm_cpumask(prev));
}
/*
@@ -656,9 +653,9 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
this_cpu_write(cpu_tlbstate.loaded_mm, next);
this_cpu_write(cpu_tlbstate.loaded_mm_asid, new_asid);
- if (next != real_prev) {
+ if (next != prev) {
cr4_update_pce_mm(next);
- switch_ldt(real_prev, next);
+ switch_ldt(prev, next);
}
}
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
index 919f647c740f..df5fac428408 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -113,6 +113,7 @@ static int bpf_size_to_x86_bytes(int bpf_size)
/* Pick a register outside of BPF range for JIT internal work */
#define AUX_REG (MAX_BPF_JIT_REG + 1)
#define X86_REG_R9 (MAX_BPF_JIT_REG + 2)
+#define X86_REG_R12 (MAX_BPF_JIT_REG + 3)
/*
* The following table maps BPF registers to x86-64 registers.
@@ -139,6 +140,7 @@ static const int reg2hex[] = {
[BPF_REG_AX] = 2, /* R10 temp register */
[AUX_REG] = 3, /* R11 temp register */
[X86_REG_R9] = 1, /* R9 register, 6th function argument */
+ [X86_REG_R12] = 4, /* R12 callee saved */
};
static const int reg2pt_regs[] = {
@@ -167,6 +169,7 @@ static bool is_ereg(u32 reg)
BIT(BPF_REG_8) |
BIT(BPF_REG_9) |
BIT(X86_REG_R9) |
+ BIT(X86_REG_R12) |
BIT(BPF_REG_AX));
}
@@ -205,6 +208,17 @@ static u8 add_2mod(u8 byte, u32 r1, u32 r2)
return byte;
}
+static u8 add_3mod(u8 byte, u32 r1, u32 r2, u32 index)
+{
+ if (is_ereg(r1))
+ byte |= 1;
+ if (is_ereg(index))
+ byte |= 2;
+ if (is_ereg(r2))
+ byte |= 4;
+ return byte;
+}
+
/* Encode 'dst_reg' register into x86-64 opcode 'byte' */
static u8 add_1reg(u8 byte, u32 dst_reg)
{
@@ -466,7 +480,7 @@ static int emit_call(u8 **pprog, void *func, void *ip)
static int emit_rsb_call(u8 **pprog, void *func, void *ip)
{
OPTIMIZER_HIDE_VAR(func);
- x86_call_depth_emit_accounting(pprog, func);
+ ip += x86_call_depth_emit_accounting(pprog, func, ip);
return emit_patch(pprog, func, ip, 0xE8);
}
@@ -553,7 +567,7 @@ static void emit_indirect_jump(u8 **pprog, int reg, u8 *ip)
emit_jump(&prog, &__x86_indirect_thunk_array[reg], ip);
} else {
EMIT2(0xFF, 0xE0 + reg); /* jmp *%\reg */
- if (IS_ENABLED(CONFIG_RETPOLINE) || IS_ENABLED(CONFIG_SLS))
+ if (IS_ENABLED(CONFIG_MITIGATION_RETPOLINE) || IS_ENABLED(CONFIG_MITIGATION_SLS))
EMIT1(0xCC); /* int3 */
}
@@ -568,7 +582,7 @@ static void emit_return(u8 **pprog, u8 *ip)
emit_jump(&prog, x86_return_thunk, ip);
} else {
EMIT1(0xC3); /* ret */
- if (IS_ENABLED(CONFIG_SLS))
+ if (IS_ENABLED(CONFIG_MITIGATION_SLS))
EMIT1(0xCC); /* int3 */
}
@@ -645,6 +659,8 @@ static void emit_bpf_tail_call_indirect(struct bpf_prog *bpf_prog,
pop_r12(&prog);
} else {
pop_callee_regs(&prog, callee_regs_used);
+ if (bpf_arena_get_kern_vm_start(bpf_prog->aux->arena))
+ pop_r12(&prog);
}
EMIT1(0x58); /* pop rax */
@@ -704,6 +720,8 @@ static void emit_bpf_tail_call_direct(struct bpf_prog *bpf_prog,
pop_r12(&prog);
} else {
pop_callee_regs(&prog, callee_regs_used);
+ if (bpf_arena_get_kern_vm_start(bpf_prog->aux->arena))
+ pop_r12(&prog);
}
EMIT1(0x58); /* pop rax */
@@ -887,6 +905,18 @@ static void emit_insn_suffix(u8 **pprog, u32 ptr_reg, u32 val_reg, int off)
*pprog = prog;
}
+static void emit_insn_suffix_SIB(u8 **pprog, u32 ptr_reg, u32 val_reg, u32 index_reg, int off)
+{
+ u8 *prog = *pprog;
+
+ if (is_imm8(off)) {
+ EMIT3(add_2reg(0x44, BPF_REG_0, val_reg), add_2reg(0, ptr_reg, index_reg) /* SIB */, off);
+ } else {
+ EMIT2_off32(add_2reg(0x84, BPF_REG_0, val_reg), add_2reg(0, ptr_reg, index_reg) /* SIB */, off);
+ }
+ *pprog = prog;
+}
+
/*
* Emit a REX byte if it will be necessary to address these registers
*/
@@ -968,6 +998,37 @@ static void emit_ldsx(u8 **pprog, u32 size, u32 dst_reg, u32 src_reg, int off)
*pprog = prog;
}
+static void emit_ldx_index(u8 **pprog, u32 size, u32 dst_reg, u32 src_reg, u32 index_reg, int off)
+{
+ u8 *prog = *pprog;
+
+ switch (size) {
+ case BPF_B:
+ /* movzx rax, byte ptr [rax + r12 + off] */
+ EMIT3(add_3mod(0x40, src_reg, dst_reg, index_reg), 0x0F, 0xB6);
+ break;
+ case BPF_H:
+ /* movzx rax, word ptr [rax + r12 + off] */
+ EMIT3(add_3mod(0x40, src_reg, dst_reg, index_reg), 0x0F, 0xB7);
+ break;
+ case BPF_W:
+ /* mov eax, dword ptr [rax + r12 + off] */
+ EMIT2(add_3mod(0x40, src_reg, dst_reg, index_reg), 0x8B);
+ break;
+ case BPF_DW:
+ /* mov rax, qword ptr [rax + r12 + off] */
+ EMIT2(add_3mod(0x48, src_reg, dst_reg, index_reg), 0x8B);
+ break;
+ }
+ emit_insn_suffix_SIB(&prog, src_reg, dst_reg, index_reg, off);
+ *pprog = prog;
+}
+
+static void emit_ldx_r12(u8 **pprog, u32 size, u32 dst_reg, u32 src_reg, int off)
+{
+ emit_ldx_index(pprog, size, dst_reg, src_reg, X86_REG_R12, off);
+}
+
/* STX: *(u8*)(dst_reg + off) = src_reg */
static void emit_stx(u8 **pprog, u32 size, u32 dst_reg, u32 src_reg, int off)
{
@@ -1002,6 +1063,71 @@ static void emit_stx(u8 **pprog, u32 size, u32 dst_reg, u32 src_reg, int off)
*pprog = prog;
}
+/* STX: *(u8*)(dst_reg + index_reg + off) = src_reg */
+static void emit_stx_index(u8 **pprog, u32 size, u32 dst_reg, u32 src_reg, u32 index_reg, int off)
+{
+ u8 *prog = *pprog;
+
+ switch (size) {
+ case BPF_B:
+ /* mov byte ptr [rax + r12 + off], al */
+ EMIT2(add_3mod(0x40, dst_reg, src_reg, index_reg), 0x88);
+ break;
+ case BPF_H:
+ /* mov word ptr [rax + r12 + off], ax */
+ EMIT3(0x66, add_3mod(0x40, dst_reg, src_reg, index_reg), 0x89);
+ break;
+ case BPF_W:
+ /* mov dword ptr [rax + r12 + 1], eax */
+ EMIT2(add_3mod(0x40, dst_reg, src_reg, index_reg), 0x89);
+ break;
+ case BPF_DW:
+ /* mov qword ptr [rax + r12 + 1], rax */
+ EMIT2(add_3mod(0x48, dst_reg, src_reg, index_reg), 0x89);
+ break;
+ }
+ emit_insn_suffix_SIB(&prog, dst_reg, src_reg, index_reg, off);
+ *pprog = prog;
+}
+
+static void emit_stx_r12(u8 **pprog, u32 size, u32 dst_reg, u32 src_reg, int off)
+{
+ emit_stx_index(pprog, size, dst_reg, src_reg, X86_REG_R12, off);
+}
+
+/* ST: *(u8*)(dst_reg + index_reg + off) = imm32 */
+static void emit_st_index(u8 **pprog, u32 size, u32 dst_reg, u32 index_reg, int off, int imm)
+{
+ u8 *prog = *pprog;
+
+ switch (size) {
+ case BPF_B:
+ /* mov byte ptr [rax + r12 + off], imm8 */
+ EMIT2(add_3mod(0x40, dst_reg, 0, index_reg), 0xC6);
+ break;
+ case BPF_H:
+ /* mov word ptr [rax + r12 + off], imm16 */
+ EMIT3(0x66, add_3mod(0x40, dst_reg, 0, index_reg), 0xC7);
+ break;
+ case BPF_W:
+ /* mov dword ptr [rax + r12 + 1], imm32 */
+ EMIT2(add_3mod(0x40, dst_reg, 0, index_reg), 0xC7);
+ break;
+ case BPF_DW:
+ /* mov qword ptr [rax + r12 + 1], imm32 */
+ EMIT2(add_3mod(0x48, dst_reg, 0, index_reg), 0xC7);
+ break;
+ }
+ emit_insn_suffix_SIB(&prog, dst_reg, 0, index_reg, off);
+ EMIT(imm, bpf_size_to_x86_bytes(size));
+ *pprog = prog;
+}
+
+static void emit_st_r12(u8 **pprog, u32 size, u32 dst_reg, int off, int imm)
+{
+ emit_st_index(pprog, size, dst_reg, X86_REG_R12, off, imm);
+}
+
static int emit_atomic(u8 **pprog, u8 atomic_op,
u32 dst_reg, u32 src_reg, s16 off, u8 bpf_size)
{
@@ -1043,12 +1169,15 @@ static int emit_atomic(u8 **pprog, u8 atomic_op,
return 0;
}
+#define DONT_CLEAR 1
+
bool ex_handler_bpf(const struct exception_table_entry *x, struct pt_regs *regs)
{
u32 reg = x->fixup >> 8;
/* jump over faulting load and clear dest register */
- *(unsigned long *)((void *)regs + reg) = 0;
+ if (reg != DONT_CLEAR)
+ *(unsigned long *)((void *)regs + reg) = 0;
regs->ip += x->fixup & 0xff;
return true;
}
@@ -1147,11 +1276,15 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, u8 *rw_image
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;
int i, excnt = 0;
int ilen, proglen = 0;
u8 *prog = temp;
int err;
+ 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);
@@ -1172,8 +1305,13 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, u8 *rw_image
push_r12(&prog);
push_callee_regs(&prog, all_callee_regs_used);
} else {
+ if (arena_vm_start)
+ push_r12(&prog);
push_callee_regs(&prog, callee_regs_used);
}
+ if (arena_vm_start)
+ emit_mov_imm64(&prog, X86_REG_R12,
+ arena_vm_start >> 32, (u32) arena_vm_start);
ilen = prog - temp;
if (rw_image)
@@ -1213,6 +1351,40 @@ 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 (dst_reg != src_reg)
+ /* 32-bit mov */
+ emit_mov_reg(&prog, false, dst_reg, src_reg);
+ /* shl dst_reg, 32 */
+ maybe_emit_1mod(&prog, dst_reg, true);
+ EMIT3(0xC1, add_1reg(0xE0, dst_reg), 32);
+
+ /* or dst_reg, user_vm_start */
+ maybe_emit_1mod(&prog, dst_reg, true);
+ if (is_axreg(dst_reg))
+ EMIT1_off32(0x0D, user_vm_start >> 32);
+ else
+ EMIT2_off32(0x81, add_1reg(0xC8, dst_reg), user_vm_start >> 32);
+
+ /* rol dst_reg, 32 */
+ maybe_emit_1mod(&prog, dst_reg, true);
+ EMIT3(0xC1, add_1reg(0xC0, dst_reg), 32);
+
+ /* xor r11, r11 */
+ EMIT3(0x4D, 0x31, 0xDB);
+
+ /* test dst_reg32, dst_reg32; check if lower 32-bit are zero */
+ maybe_emit_mod(&prog, dst_reg, dst_reg, false);
+ EMIT2(0x85, add_2reg(0xC0, dst_reg, dst_reg));
+
+ /* cmove r11, dst_reg; if so, set dst_reg to zero */
+ /* WARNING: Intel swapped src/dst register encoding in CMOVcc !!! */
+ maybe_emit_mod(&prog, AUX_REG, dst_reg, true);
+ EMIT3(0x0F, 0x44, add_2reg(0xC0, AUX_REG, dst_reg));
+ break;
+ }
+ fallthrough;
case BPF_ALU | BPF_MOV | BPF_X:
if (insn->off == 0)
emit_mov_reg(&prog,
@@ -1564,6 +1736,56 @@ st: if (is_imm8(insn->off))
emit_stx(&prog, BPF_SIZE(insn->code), dst_reg, src_reg, insn->off);
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:
+ start_of_ldx = prog;
+ emit_st_r12(&prog, BPF_SIZE(insn->code), dst_reg, insn->off, insn->imm);
+ goto populate_extable;
+
+ /* LDX: dst_reg = *(u8*)(src_reg + r12 + 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:
+ 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:
+ start_of_ldx = prog;
+ if (BPF_CLASS(insn->code) == BPF_LDX)
+ emit_ldx_r12(&prog, BPF_SIZE(insn->code), dst_reg, src_reg, insn->off);
+ else
+ emit_stx_r12(&prog, BPF_SIZE(insn->code), dst_reg, src_reg, insn->off);
+populate_extable:
+ {
+ struct exception_table_entry *ex;
+ u8 *_insn = image + proglen + (start_of_ldx - temp);
+ s64 delta;
+
+ if (!bpf_prog->aux->extable)
+ break;
+
+ if (excnt >= bpf_prog->aux->num_exentries) {
+ pr_err("mem32 extable bug\n");
+ return -EFAULT;
+ }
+ ex = &bpf_prog->aux->extable[excnt++];
+
+ delta = _insn - (u8 *)&ex->insn;
+ /* switch ex to rw buffer for writes */
+ ex = (void *)rw_image + ((void *)ex - (void *)image);
+
+ ex->insn = delta;
+
+ ex->data = EX_TYPE_BPF;
+
+ ex->fixup = (prog - start_of_ldx) |
+ ((BPF_CLASS(insn->code) == BPF_LDX ? reg2pt_regs[dst_reg] : DONT_CLEAR) << 8);
+ }
+ break;
+
/* LDX: dst_reg = *(u8*)(src_reg + off) */
case BPF_LDX | BPF_MEM | BPF_B:
case BPF_LDX | BPF_PROBE_MEM | BPF_B:
@@ -1750,20 +1972,17 @@ st: if (is_imm8(insn->off))
/* call */
case BPF_JMP | BPF_CALL: {
- int offs;
+ u8 *ip = image + addrs[i - 1];
func = (u8 *) __bpf_call_base + imm32;
if (tail_call_reachable) {
RESTORE_TAIL_CALL_CNT(bpf_prog->aux->stack_depth);
- if (!imm32)
- return -EINVAL;
- offs = 7 + x86_call_depth_emit_accounting(&prog, func);
- } else {
- if (!imm32)
- return -EINVAL;
- offs = x86_call_depth_emit_accounting(&prog, func);
+ ip += 7;
}
- if (emit_call(&prog, func, image + addrs[i - 1] + offs))
+ if (!imm32)
+ return -EINVAL;
+ ip += x86_call_depth_emit_accounting(&prog, func, ip);
+ if (emit_call(&prog, func, ip))
return -EINVAL;
break;
}
@@ -2036,6 +2255,8 @@ emit_jmp:
pop_r12(&prog);
} else {
pop_callee_regs(&prog, callee_regs_used);
+ if (arena_vm_start)
+ pop_r12(&prog);
}
EMIT1(0xC9); /* leave */
emit_return(&prog, image + addrs[i - 1] + (prog - temp));
@@ -2611,7 +2832,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
* Direct-call fentry stub, as such it needs accounting for the
* __fentry__ call.
*/
- x86_call_depth_emit_accounting(&prog, NULL);
+ x86_call_depth_emit_accounting(&prog, NULL, image);
}
EMIT1(0x55); /* push rbp */
EMIT3(0x48, 0x89, 0xE5); /* mov rbp, rsp */
@@ -3242,3 +3463,13 @@ void bpf_arch_poke_desc_update(struct bpf_jit_poke_descriptor *poke,
BUG_ON(ret < 0);
}
}
+
+bool bpf_jit_supports_arena(void)
+{
+ 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 b18ce19981ec..c10083a8e68e 100644
--- a/arch/x86/net/bpf_jit_comp32.c
+++ b/arch/x86/net/bpf_jit_comp32.c
@@ -1273,7 +1273,7 @@ static int emit_jmp_edx(u8 **pprog, u8 *ip)
u8 *prog = *pprog;
int cnt = 0;
-#ifdef CONFIG_RETPOLINE
+#ifdef CONFIG_MITIGATION_RETPOLINE
EMIT1_off32(0xE9, (u8 *)__x86_indirect_thunk_edx - (ip + 5));
#else
EMIT2(0xFF, 0xE2);
diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c
index f347c20247d3..b33afb240601 100644
--- a/arch/x86/pci/fixup.c
+++ b/arch/x86/pci/fixup.c
@@ -907,6 +907,54 @@ static void chromeos_fixup_apl_pci_l1ss_capability(struct pci_dev *dev)
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x5ad6, chromeos_save_apl_pci_l1ss_capability);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, 0x5ad6, chromeos_fixup_apl_pci_l1ss_capability);
+/*
+ * Disable D3cold on Asus B1400 PCI-NVMe bridge
+ *
+ * On this platform with VMD off, the NVMe device cannot successfully power
+ * back on from D3cold. This appears to be an untested transition by the
+ * vendor: Windows leaves the NVMe and parent bridge in D0 during suspend.
+ *
+ * We disable D3cold on the parent bridge for simplicity, and the fact that
+ * both parent bridge and NVMe device share the same power resource.
+ *
+ * This is only needed on BIOS versions before 308; the newer versions flip
+ * StorageD3Enable from 1 to 0.
+ */
+static const struct dmi_system_id asus_nvme_broken_d3cold_table[] = {
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_BIOS_VERSION, "B1400CEAE.304"),
+ },
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_BIOS_VERSION, "B1400CEAE.305"),
+ },
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_BIOS_VERSION, "B1400CEAE.306"),
+ },
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_BIOS_VERSION, "B1400CEAE.307"),
+ },
+ },
+ {}
+};
+
+static void asus_disable_nvme_d3cold(struct pci_dev *pdev)
+{
+ if (dmi_check_system(asus_nvme_broken_d3cold_table) > 0)
+ pci_d3cold_disable(pdev);
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x9a09, asus_disable_nvme_d3cold);
+
#ifdef CONFIG_SUSPEND
/*
* Root Ports on some AMD SoCs advertise PME_Support for D3hot and D3cold, but
diff --git a/arch/x86/platform/atom/punit_atom_debug.c b/arch/x86/platform/atom/punit_atom_debug.c
index f8ed5f66cd20..6b9c6deca8ba 100644
--- a/arch/x86/platform/atom/punit_atom_debug.c
+++ b/arch/x86/platform/atom/punit_atom_debug.c
@@ -7,6 +7,9 @@
* Copyright (c) 2015, Intel Corporation.
*/
+#define pr_fmt(fmt) "punit_atom: " fmt
+
+#include <linux/acpi.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
@@ -117,6 +120,51 @@ static void punit_dbgfs_unregister(void)
debugfs_remove_recursive(punit_dbg_file);
}
+#if defined(CONFIG_ACPI) && defined(CONFIG_SUSPEND)
+static const struct punit_device *punit_dev;
+
+static void punit_s2idle_check(void)
+{
+ const struct punit_device *punit_devp;
+ u32 punit_pwr_status, dstate;
+ int status;
+
+ for (punit_devp = punit_dev; punit_devp->name; punit_devp++) {
+ /* Skip MIO, it is on till the very last moment */
+ if (punit_devp->reg == MIO_SS_PM)
+ continue;
+
+ status = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ,
+ punit_devp->reg, &punit_pwr_status);
+ if (status) {
+ pr_err("%s read failed\n", punit_devp->name);
+ } else {
+ dstate = (punit_pwr_status >> punit_devp->sss_pos) & 3;
+ if (!dstate)
+ pr_err("%s is in D0 prior to s2idle\n", punit_devp->name);
+ }
+ }
+}
+
+static struct acpi_s2idle_dev_ops punit_s2idle_ops = {
+ .check = punit_s2idle_check,
+};
+
+static void punit_s2idle_check_register(struct punit_device *punit_device)
+{
+ punit_dev = punit_device;
+ acpi_register_lps0_dev(&punit_s2idle_ops);
+}
+
+static void punit_s2idle_check_unregister(void)
+{
+ acpi_unregister_lps0_dev(&punit_s2idle_ops);
+}
+#else
+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)
@@ -131,19 +179,23 @@ MODULE_DEVICE_TABLE(x86cpu, intel_punit_cpu_ids);
static int __init punit_atom_debug_init(void)
{
+ struct punit_device *punit_device;
const struct x86_cpu_id *id;
id = x86_match_cpu(intel_punit_cpu_ids);
if (!id)
return -ENODEV;
- punit_dbgfs_register((struct punit_device *)id->driver_data);
+ punit_device = (struct punit_device *)id->driver_data;
+ punit_dbgfs_register(punit_device);
+ punit_s2idle_check_register(punit_device);
return 0;
}
static void __exit punit_atom_debug_exit(void)
{
+ punit_s2idle_check_unregister();
punit_dbgfs_unregister();
}
diff --git a/arch/x86/platform/ce4100/ce4100.c b/arch/x86/platform/ce4100/ce4100.c
index 40745664d92f..f32451bdcfdd 100644
--- a/arch/x86/platform/ce4100/ce4100.c
+++ b/arch/x86/platform/ce4100/ce4100.c
@@ -135,13 +135,13 @@ static void sdv_pci_init(void)
*/
void __init x86_ce4100_early_setup(void)
{
- x86_init.oem.arch_setup = sdv_arch_setup;
- x86_init.resources.probe_roms = x86_init_noop;
- x86_init.mpparse.get_smp_config = x86_init_uint_noop;
- x86_init.mpparse.find_smp_config = x86_init_noop;
- x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc_nocheck;
- x86_init.pci.init = ce4100_pci_init;
- x86_init.pci.init_irq = sdv_pci_init;
+ x86_init.oem.arch_setup = sdv_arch_setup;
+ 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;
/*
* By default, the reboot method is ACPI which is supported by the
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index e9f99c56f3ce..f090ec972d7b 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -950,3 +950,8 @@ umode_t efi_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n)
}
return attr->mode;
}
+
+enum efi_secureboot_mode __x86_ima_efi_boot_mode(void)
+{
+ return boot_params.secure_boot;
+}
diff --git a/arch/x86/platform/intel-mid/intel-mid.c b/arch/x86/platform/intel-mid/intel-mid.c
index f4592dc7a1c1..7be71c2cdc83 100644
--- a/arch/x86/platform/intel-mid/intel-mid.c
+++ b/arch/x86/platform/intel-mid/intel-mid.c
@@ -118,7 +118,8 @@ void __init x86_intel_mid_early_setup(void)
machine_ops.emergency_restart = intel_mid_reboot;
/* Avoid searching for BIOS MP tables */
- x86_init.mpparse.find_smp_config = x86_init_noop;
- x86_init.mpparse.get_smp_config = x86_init_uint_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_init_noop;
set_bit(MP_BUS_ISA, mp_bus_not_pci);
}
diff --git a/arch/x86/platform/pvh/enlighten.c b/arch/x86/platform/pvh/enlighten.c
index 00a92cb2c814..8c2d4b8de25d 100644
--- a/arch/x86/platform/pvh/enlighten.c
+++ b/arch/x86/platform/pvh/enlighten.c
@@ -3,6 +3,7 @@
#include <xen/hvc-console.h>
+#include <asm/bootparam.h>
#include <asm/io_apic.h>
#include <asm/hypervisor.h>
#include <asm/e820/api.h>
@@ -74,6 +75,9 @@ static void __init init_pvh_bootparams(bool xen_guest)
} else
xen_raw_printk("Warning: Can fit ISA range into e820\n");
+ if (xen_guest)
+ xen_reserve_extra_memory(&pvh_bootparams);
+
pvh_bootparams.hdr.cmd_line_ptr =
pvh_start_info.cmdline_paddr;
diff --git a/arch/x86/power/Makefile b/arch/x86/power/Makefile
index 379777572bc9..e0cd7afd5302 100644
--- a/arch/x86/power/Makefile
+++ b/arch/x86/power/Makefile
@@ -5,7 +5,7 @@
CFLAGS_cpu.o := -fno-stack-protector
# Clang may incorrectly inline functions with stack protector enabled into
-# __restore_processor_state(): https://bugs.llvm.org/show_bug.cgi?id=47479
+# __restore_processor_state(): https://llvm.org/pr47479
CFLAGS_REMOVE_cpu.o := $(CC_FLAGS_LTO)
obj-$(CONFIG_PM_SLEEP) += cpu.o
diff --git a/arch/x86/power/hibernate.c b/arch/x86/power/hibernate.c
index 6f955eb1e163..5b81d19cd114 100644
--- a/arch/x86/power/hibernate.c
+++ b/arch/x86/power/hibernate.c
@@ -165,17 +165,17 @@ int relocate_restore_code(void)
pgd = (pgd_t *)__va(read_cr3_pa()) +
pgd_index(relocated_restore_code);
p4d = p4d_offset(pgd, relocated_restore_code);
- if (p4d_large(*p4d)) {
+ if (p4d_leaf(*p4d)) {
set_p4d(p4d, __p4d(p4d_val(*p4d) & ~_PAGE_NX));
goto out;
}
pud = pud_offset(p4d, relocated_restore_code);
- if (pud_large(*pud)) {
+ if (pud_leaf(*pud)) {
set_pud(pud, __pud(pud_val(*pud) & ~_PAGE_NX));
goto out;
}
pmd = pmd_offset(pud, relocated_restore_code);
- if (pmd_large(*pmd)) {
+ if (pmd_leaf(*pmd)) {
set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_NX));
goto out;
}
diff --git a/arch/x86/purgatory/Makefile b/arch/x86/purgatory/Makefile
index 08aa0f25f12a..bc31863c5ee6 100644
--- a/arch/x86/purgatory/Makefile
+++ b/arch/x86/purgatory/Makefile
@@ -61,7 +61,7 @@ ifdef CONFIG_STACKPROTECTOR_STRONG
PURGATORY_CFLAGS_REMOVE += -fstack-protector-strong
endif
-ifdef CONFIG_RETPOLINE
+ifdef CONFIG_MITIGATION_RETPOLINE
PURGATORY_CFLAGS_REMOVE += $(RETPOLINE_CFLAGS)
endif
diff --git a/arch/x86/realmode/rm/trampoline_64.S b/arch/x86/realmode/rm/trampoline_64.S
index c9f76fae902e..14d9c7daf90f 100644
--- a/arch/x86/realmode/rm/trampoline_64.S
+++ b/arch/x86/realmode/rm/trampoline_64.S
@@ -37,13 +37,15 @@
.text
.code16
-.macro LOCK_AND_LOAD_REALMODE_ESP lock_pa=0
+.macro LOCK_AND_LOAD_REALMODE_ESP lock_pa=0 lock_rip=0
/*
* Make sure only one CPU fiddles with the realmode stack
*/
.Llock_rm\@:
.if \lock_pa
lock btsl $0, pa_tr_lock
+ .elseif \lock_rip
+ lock btsl $0, tr_lock(%rip)
.else
lock btsl $0, tr_lock
.endif
@@ -220,6 +222,35 @@ SYM_CODE_START(trampoline_start64)
lidt tr_idt(%rip)
lgdt tr_gdt64(%rip)
+ /* Check if paging mode has to be changed */
+ movq %cr4, %rax
+ xorl tr_cr4(%rip), %eax
+ testl $X86_CR4_LA57, %eax
+ jnz .L_switch_paging
+
+ /* Paging mode is correct proceed in 64-bit mode */
+
+ LOCK_AND_LOAD_REALMODE_ESP lock_rip=1
+
+ movw $__KERNEL_DS, %dx
+ movl %edx, %ss
+ addl $pa_real_mode_base, %esp
+ movl %edx, %ds
+ movl %edx, %es
+ movl %edx, %fs
+ movl %edx, %gs
+
+ movl $pa_trampoline_pgd, %eax
+ movq %rax, %cr3
+
+ pushq $__KERNEL_CS
+ pushq tr_start(%rip)
+ lretq
+.L_switch_paging:
+ /*
+ * To switch between 4- and 5-level paging modes, it is necessary
+ * to disable paging. This must be done in the compatibility mode.
+ */
ljmpl *tr_compat(%rip)
SYM_CODE_END(trampoline_start64)
diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c
index a3bae2b24626..b029fb81ebee 100644
--- a/arch/x86/tools/relocs.c
+++ b/arch/x86/tools/relocs.c
@@ -653,6 +653,14 @@ static void print_absolute_relocs(void)
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) {
+ continue;
+ }
sh_symtab = sec_symtab->symtab;
sym_strtab = sec_symtab->link->strtab;
for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) {
diff --git a/arch/x86/virt/Makefile b/arch/x86/virt/Makefile
index 1e36502cd738..ea343fc392dc 100644
--- a/arch/x86/virt/Makefile
+++ b/arch/x86/virt/Makefile
@@ -1,2 +1,2 @@
# SPDX-License-Identifier: GPL-2.0-only
-obj-y += vmx/
+obj-y += svm/ vmx/
diff --git a/arch/x86/virt/svm/Makefile b/arch/x86/virt/svm/Makefile
new file mode 100644
index 000000000000..ef2a31bdcc70
--- /dev/null
+++ b/arch/x86/virt/svm/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_KVM_AMD_SEV) += sev.o
diff --git a/arch/x86/virt/svm/sev.c b/arch/x86/virt/svm/sev.c
new file mode 100644
index 000000000000..ab0e8448bb6e
--- /dev/null
+++ b/arch/x86/virt/svm/sev.c
@@ -0,0 +1,570 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * AMD SVM-SEV Host Support.
+ *
+ * Copyright (C) 2023 Advanced Micro Devices, Inc.
+ *
+ * Author: Ashish Kalra <ashish.kalra@amd.com>
+ *
+ */
+
+#include <linux/cc_platform.h>
+#include <linux/printk.h>
+#include <linux/mm_types.h>
+#include <linux/set_memory.h>
+#include <linux/memblock.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/cpumask.h>
+#include <linux/iommu.h>
+#include <linux/amd-iommu.h>
+
+#include <asm/sev.h>
+#include <asm/processor.h>
+#include <asm/setup.h>
+#include <asm/svm.h>
+#include <asm/smp.h>
+#include <asm/cpu.h>
+#include <asm/apic.h>
+#include <asm/cpuid.h>
+#include <asm/cmdline.h>
+#include <asm/iommu.h>
+
+/*
+ * The RMP entry format is not architectural. The format is defined in PPR
+ * Family 19h Model 01h, Rev B1 processor.
+ */
+struct rmpentry {
+ union {
+ struct {
+ u64 assigned : 1,
+ pagesize : 1,
+ immutable : 1,
+ rsvd1 : 9,
+ gpa : 39,
+ asid : 10,
+ vmsa : 1,
+ validated : 1,
+ rsvd2 : 1;
+ };
+ u64 lo;
+ };
+ u64 hi;
+} __packed;
+
+/*
+ * The first 16KB from the RMP_BASE is used by the processor for the
+ * bookkeeping, the range needs to be added during the RMP entry lookup.
+ */
+#define RMPTABLE_CPU_BOOKKEEPING_SZ 0x4000
+
+/* Mask to apply to a PFN to get the first PFN of a 2MB page */
+#define PFN_PMD_MASK GENMASK_ULL(63, PMD_SHIFT - PAGE_SHIFT)
+
+static u64 probed_rmp_base, probed_rmp_size;
+static struct rmpentry *rmptable __ro_after_init;
+static u64 rmptable_max_pfn __ro_after_init;
+
+static LIST_HEAD(snp_leaked_pages_list);
+static DEFINE_SPINLOCK(snp_leaked_pages_list_lock);
+
+static unsigned long snp_nr_leaked_pages;
+
+#undef pr_fmt
+#define pr_fmt(fmt) "SEV-SNP: " fmt
+
+static int __mfd_enable(unsigned int cpu)
+{
+ u64 val;
+
+ if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP))
+ return 0;
+
+ rdmsrl(MSR_AMD64_SYSCFG, val);
+
+ val |= MSR_AMD64_SYSCFG_MFDM;
+
+ wrmsrl(MSR_AMD64_SYSCFG, val);
+
+ return 0;
+}
+
+static __init void mfd_enable(void *arg)
+{
+ __mfd_enable(smp_processor_id());
+}
+
+static int __snp_enable(unsigned int cpu)
+{
+ u64 val;
+
+ if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP))
+ return 0;
+
+ rdmsrl(MSR_AMD64_SYSCFG, val);
+
+ val |= MSR_AMD64_SYSCFG_SNP_EN;
+ val |= MSR_AMD64_SYSCFG_SNP_VMPL_EN;
+
+ wrmsrl(MSR_AMD64_SYSCFG, val);
+
+ return 0;
+}
+
+static __init void snp_enable(void *arg)
+{
+ __snp_enable(smp_processor_id());
+}
+
+#define RMP_ADDR_MASK GENMASK_ULL(51, 13)
+
+bool snp_probe_rmptable_info(void)
+{
+ u64 max_rmp_pfn, calc_rmp_sz, rmp_sz, rmp_base, rmp_end;
+
+ rdmsrl(MSR_AMD64_RMP_BASE, rmp_base);
+ rdmsrl(MSR_AMD64_RMP_END, rmp_end);
+
+ if (!(rmp_base & RMP_ADDR_MASK) || !(rmp_end & RMP_ADDR_MASK)) {
+ pr_err("Memory for the RMP table has not been reserved by BIOS\n");
+ return false;
+ }
+
+ if (rmp_base > rmp_end) {
+ pr_err("RMP configuration not valid: base=%#llx, end=%#llx\n", rmp_base, rmp_end);
+ return false;
+ }
+
+ 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);
+
+ return true;
+}
+
+/*
+ * Do the necessary preparations which are verified by the firmware as
+ * described in the SNP_INIT_EX firmware command description in the SNP
+ * firmware ABI spec.
+ */
+static int __init snp_rmptable_init(void)
+{
+ void *rmptable_start;
+ u64 rmptable_size;
+ u64 val;
+
+ if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP))
+ return 0;
+
+ if (!amd_iommu_snp_en)
+ goto nosnp;
+
+ if (!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;
+ }
+
+ /*
+ * Check if SEV-SNP is already enabled, this can happen in case of
+ * kexec boot.
+ */
+ rdmsrl(MSR_AMD64_SYSCFG, val);
+ if (val & MSR_AMD64_SYSCFG_SNP_EN)
+ goto skip_enable;
+
+ memset(rmptable_start, 0, probed_rmp_size);
+
+ /* Flush the caches to ensure that data is written before SNP is enabled. */
+ wbinvd_on_all_cpus();
+
+ /* MtrrFixDramModEn must be enabled on all the CPUs prior to enabling SNP. */
+ on_each_cpu(mfd_enable, NULL, 1);
+
+ on_each_cpu(snp_enable, NULL, 1);
+
+skip_enable:
+ rmptable_start += RMPTABLE_CPU_BOOKKEEPING_SZ;
+ rmptable_size = probed_rmp_size - RMPTABLE_CPU_BOOKKEEPING_SZ;
+
+ rmptable = (struct rmpentry *)rmptable_start;
+ rmptable_max_pfn = rmptable_size / sizeof(struct rmpentry) - 1;
+
+ cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "x86/rmptable_init:online", __snp_enable, NULL);
+
+ /*
+ * Setting crash_kexec_post_notifiers to 'true' to ensure that SNP panic
+ * notifier is invoked to do SNP IOMMU shutdown before kdump.
+ */
+ crash_kexec_post_notifiers = true;
+
+ return 0;
+
+nosnp:
+ cc_platform_clear(CC_ATTR_HOST_SEV_SNP);
+ return -ENOSYS;
+}
+
+/*
+ * This must be called after the IOMMU has been initialized.
+ */
+device_initcall(snp_rmptable_init);
+
+static struct rmpentry *get_rmpentry(u64 pfn)
+{
+ if (WARN_ON_ONCE(pfn > rmptable_max_pfn))
+ return ERR_PTR(-EFAULT);
+
+ return &rmptable[pfn];
+}
+
+static struct rmpentry *__snp_lookup_rmpentry(u64 pfn, int *level)
+{
+ struct rmpentry *large_entry, *entry;
+
+ if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP))
+ return ERR_PTR(-ENODEV);
+
+ entry = get_rmpentry(pfn);
+ if (IS_ERR(entry))
+ return entry;
+
+ /*
+ * Find the authoritative RMP entry for a PFN. This can be either a 4K
+ * RMP entry or a special large RMP entry that is authoritative for a
+ * whole 2M area.
+ */
+ large_entry = get_rmpentry(pfn & PFN_PMD_MASK);
+ if (IS_ERR(large_entry))
+ return large_entry;
+
+ *level = RMP_TO_PG_LEVEL(large_entry->pagesize);
+
+ return entry;
+}
+
+int snp_lookup_rmpentry(u64 pfn, bool *assigned, int *level)
+{
+ struct rmpentry *e;
+
+ e = __snp_lookup_rmpentry(pfn, level);
+ if (IS_ERR(e))
+ return PTR_ERR(e);
+
+ *assigned = !!e->assigned;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(snp_lookup_rmpentry);
+
+/*
+ * Dump the raw RMP entry for a particular PFN. These bits are documented in the
+ * PPR for a particular CPU model and provide useful information about how a
+ * particular PFN is being utilized by the kernel/firmware at the time certain
+ * unexpected events occur, such as RMP faults.
+ */
+static void dump_rmpentry(u64 pfn)
+{
+ u64 pfn_i, pfn_end;
+ struct rmpentry *e;
+ int level;
+
+ e = __snp_lookup_rmpentry(pfn, &level);
+ if (IS_ERR(e)) {
+ pr_err("Failed to read RMP entry for PFN 0x%llx, error %ld\n",
+ pfn, PTR_ERR(e));
+ return;
+ }
+
+ if (e->assigned) {
+ pr_info("PFN 0x%llx, RMP entry: [0x%016llx - 0x%016llx]\n",
+ pfn, e->lo, e->hi);
+ return;
+ }
+
+ /*
+ * If the RMP entry for a particular PFN is not in an assigned state,
+ * then it is sometimes useful to get an idea of whether or not any RMP
+ * entries for other PFNs within the same 2MB region are assigned, since
+ * those too can affect the ability to access a particular PFN in
+ * certain situations, such as when the PFN is being accessed via a 2MB
+ * mapping in the host page table.
+ */
+ pfn_i = ALIGN_DOWN(pfn, PTRS_PER_PMD);
+ pfn_end = pfn_i + PTRS_PER_PMD;
+
+ pr_info("PFN 0x%llx unassigned, dumping non-zero entries in 2M PFN region: [0x%llx - 0x%llx]\n",
+ pfn, pfn_i, pfn_end);
+
+ while (pfn_i < pfn_end) {
+ e = __snp_lookup_rmpentry(pfn_i, &level);
+ if (IS_ERR(e)) {
+ pr_err("Error %ld reading RMP entry for PFN 0x%llx\n",
+ PTR_ERR(e), pfn_i);
+ pfn_i++;
+ continue;
+ }
+
+ if (e->lo || e->hi)
+ pr_info("PFN: 0x%llx, [0x%016llx - 0x%016llx]\n", pfn_i, e->lo, e->hi);
+ pfn_i++;
+ }
+}
+
+void snp_dump_hva_rmpentry(unsigned long hva)
+{
+ unsigned long paddr;
+ unsigned int level;
+ pgd_t *pgd;
+ pte_t *pte;
+
+ pgd = __va(read_cr3_pa());
+ pgd += pgd_index(hva);
+ pte = lookup_address_in_pgd(pgd, hva, &level);
+
+ if (!pte) {
+ pr_err("Can't dump RMP entry for HVA %lx: no PTE/PFN found\n", hva);
+ return;
+ }
+
+ paddr = PFN_PHYS(pte_pfn(*pte)) | (hva & ~page_level_mask(level));
+ dump_rmpentry(PHYS_PFN(paddr));
+}
+
+/*
+ * PSMASH a 2MB aligned page into 4K pages in the RMP table while preserving the
+ * Validated bit.
+ */
+int psmash(u64 pfn)
+{
+ unsigned long paddr = pfn << PAGE_SHIFT;
+ int ret;
+
+ if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP))
+ return -ENODEV;
+
+ if (!pfn_valid(pfn))
+ return -EINVAL;
+
+ /* Binutils version 2.36 supports the PSMASH mnemonic. */
+ asm volatile(".byte 0xF3, 0x0F, 0x01, 0xFF"
+ : "=a" (ret)
+ : "a" (paddr)
+ : "memory", "cc");
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(psmash);
+
+/*
+ * If the kernel uses a 2MB or larger directmap mapping to write to an address,
+ * and that mapping contains any 4KB pages that are set to private in the RMP
+ * table, an RMP #PF will trigger and cause a host crash. Hypervisor code that
+ * owns the PFNs being transitioned will never attempt such a write, but other
+ * kernel tasks writing to other PFNs in the range may trigger these checks
+ * inadvertently due a large directmap mapping that happens to overlap such a
+ * PFN.
+ *
+ * Prevent this by splitting any 2MB+ mappings that might end up containing a
+ * mix of private/shared PFNs as a result of a subsequent RMPUPDATE for the
+ * PFN/rmp_level passed in.
+ *
+ * Note that there is no attempt here to scan all the RMP entries for the 2MB
+ * physical range, since it would only be worthwhile in determining if a
+ * subsequent RMPUPDATE for a 4KB PFN would result in all the entries being of
+ * the same shared/private state, thus avoiding the need to split the mapping.
+ * But that would mean the entries are currently in a mixed state, and so the
+ * mapping would have already been split as a result of prior transitions.
+ * And since the 4K split is only done if the mapping is 2MB+, and there isn't
+ * currently a mechanism in place to restore 2MB+ mappings, such a check would
+ * not provide any usable benefit.
+ *
+ * More specifics on how these checks are carried out can be found in APM
+ * Volume 2, "RMP and VMPL Access Checks".
+ */
+static int adjust_direct_map(u64 pfn, int rmp_level)
+{
+ unsigned long vaddr;
+ unsigned int level;
+ int npages, ret;
+ pte_t *pte;
+
+ /*
+ * pfn_to_kaddr() will return a vaddr only within the direct
+ * map range.
+ */
+ vaddr = (unsigned long)pfn_to_kaddr(pfn);
+
+ /* Only 4KB/2MB RMP entries are supported by current hardware. */
+ if (WARN_ON_ONCE(rmp_level > PG_LEVEL_2M))
+ return -EINVAL;
+
+ if (!pfn_valid(pfn))
+ return -EINVAL;
+
+ if (rmp_level == PG_LEVEL_2M &&
+ (!IS_ALIGNED(pfn, PTRS_PER_PMD) || !pfn_valid(pfn + PTRS_PER_PMD - 1)))
+ return -EINVAL;
+
+ /*
+ * If an entire 2MB physical range is being transitioned, then there is
+ * no risk of RMP #PFs due to write accesses from overlapping mappings,
+ * since even accesses from 1GB mappings will be treated as 2MB accesses
+ * as far as RMP table checks are concerned.
+ */
+ if (rmp_level == PG_LEVEL_2M)
+ return 0;
+
+ pte = lookup_address(vaddr, &level);
+ if (!pte || pte_none(*pte))
+ return 0;
+
+ if (level == PG_LEVEL_4K)
+ return 0;
+
+ npages = page_level_size(rmp_level) / PAGE_SIZE;
+ ret = set_memory_4k(vaddr, npages);
+ if (ret)
+ pr_warn("Failed to split direct map for PFN 0x%llx, ret: %d\n",
+ pfn, ret);
+
+ return ret;
+}
+
+/*
+ * It is expected that those operations are seldom enough so that no mutual
+ * exclusion of updaters is needed and thus the overlap error condition below
+ * should happen very rarely and would get resolved relatively quickly by
+ * the firmware.
+ *
+ * If not, one could consider introducing a mutex or so here to sync concurrent
+ * RMP updates and thus diminish the amount of cases where firmware needs to
+ * lock 2M ranges to protect against concurrent updates.
+ *
+ * The optimal solution would be range locking to avoid locking disjoint
+ * regions unnecessarily but there's no support for that yet.
+ */
+static int rmpupdate(u64 pfn, struct rmp_state *state)
+{
+ unsigned long paddr = pfn << PAGE_SHIFT;
+ int ret, level;
+
+ if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP))
+ return -ENODEV;
+
+ level = RMP_TO_PG_LEVEL(state->pagesize);
+
+ if (adjust_direct_map(pfn, level))
+ return -EFAULT;
+
+ do {
+ /* Binutils version 2.36 supports the RMPUPDATE mnemonic. */
+ asm volatile(".byte 0xF2, 0x0F, 0x01, 0xFE"
+ : "=a" (ret)
+ : "a" (paddr), "c" ((unsigned long)state)
+ : "memory", "cc");
+ } while (ret == RMPUPDATE_FAIL_OVERLAP);
+
+ if (ret) {
+ pr_err("RMPUPDATE failed for PFN %llx, pg_level: %d, ret: %d\n",
+ pfn, level, ret);
+ dump_rmpentry(pfn);
+ dump_stack();
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+/* Transition a page to guest-owned/private state in the RMP table. */
+int rmp_make_private(u64 pfn, u64 gpa, enum pg_level level, u32 asid, bool immutable)
+{
+ struct rmp_state state;
+
+ memset(&state, 0, sizeof(state));
+ state.assigned = 1;
+ state.asid = asid;
+ state.immutable = immutable;
+ state.gpa = gpa;
+ state.pagesize = PG_LEVEL_TO_RMP(level);
+
+ return rmpupdate(pfn, &state);
+}
+EXPORT_SYMBOL_GPL(rmp_make_private);
+
+/* Transition a page to hypervisor-owned/shared state in the RMP table. */
+int rmp_make_shared(u64 pfn, enum pg_level level)
+{
+ struct rmp_state state;
+
+ memset(&state, 0, sizeof(state));
+ state.pagesize = PG_LEVEL_TO_RMP(level);
+
+ return rmpupdate(pfn, &state);
+}
+EXPORT_SYMBOL_GPL(rmp_make_shared);
+
+void snp_leak_pages(u64 pfn, unsigned int npages)
+{
+ struct page *page = pfn_to_page(pfn);
+
+ pr_warn("Leaking PFN range 0x%llx-0x%llx\n", pfn, pfn + npages);
+
+ spin_lock(&snp_leaked_pages_list_lock);
+ while (npages--) {
+
+ /*
+ * Reuse the page's buddy list for chaining into the leaked
+ * pages list. This page should not be on a free list currently
+ * and is also unsafe to be added to a free list.
+ */
+ if (likely(!PageCompound(page)) ||
+
+ /*
+ * Skip inserting tail pages of compound page as
+ * page->buddy_list of tail pages is not usable.
+ */
+ (PageHead(page) && compound_nr(page) <= npages))
+ list_add_tail(&page->buddy_list, &snp_leaked_pages_list);
+
+ dump_rmpentry(pfn);
+ snp_nr_leaked_pages++;
+ pfn++;
+ page++;
+ }
+ spin_unlock(&snp_leaked_pages_list_lock);
+}
+EXPORT_SYMBOL_GPL(snp_leak_pages);
+
+void kdump_sev_callback(void)
+{
+ /*
+ * Do wbinvd() on remote CPUs when SNP is enabled in order to
+ * safely do SNP_SHUTDOWN on the local CPU.
+ */
+ if (cc_platform_has(CC_ATTR_HOST_SEV_SNP))
+ wbinvd();
+}
diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig
index a65fc2ae15b4..77e788e928cd 100644
--- a/arch/x86/xen/Kconfig
+++ b/arch/x86/xen/Kconfig
@@ -81,7 +81,6 @@ config XEN_PVH
bool "Xen PVH guest support"
depends on XEN && XEN_PVHVM && ACPI
select PVH
- def_bool n
help
Support for running as a Xen PVH guest.
diff --git a/arch/x86/xen/apic.c b/arch/x86/xen/apic.c
index 9dd5490b3318..8b045dd25196 100644
--- a/arch/x86/xen/apic.c
+++ b/arch/x86/xen/apic.c
@@ -33,12 +33,6 @@ static unsigned int xen_io_apic_read(unsigned apic, unsigned reg)
return 0xfd;
}
-static u32 xen_set_apic_id(u32 x)
-{
- WARN_ON(1);
- return x;
-}
-
static u32 xen_get_apic_id(u32 x)
{
return ((x)>>24) & 0xFFu;
@@ -49,20 +43,20 @@ static u32 xen_apic_read(u32 reg)
struct xen_platform_op op = {
.cmd = XENPF_get_cpuinfo,
.interface_version = XENPF_INTERFACE_VERSION,
- .u.pcpu_info.xen_cpuid = 0,
};
- int ret;
-
- /* Shouldn't need this as APIC is turned off for PV, and we only
- * get called on the bootup processor. But just in case. */
- if (!xen_initial_domain() || smp_processor_id())
- return 0;
+ int ret, cpu;
if (reg == APIC_LVR)
return 0x14;
if (reg != APIC_ID)
return 0;
+ cpu = smp_processor_id();
+ if (!xen_initial_domain())
+ return cpu ? cpuid_to_apicid[cpu] << 24 : 0;
+
+ op.u.pcpu_info.xen_cpuid = cpu;
+
ret = HYPERVISOR_platform_op(&op);
if (ret)
op.u.pcpu_info.apic_id = BAD_APICID;
@@ -110,11 +104,6 @@ static int xen_madt_oem_check(char *oem_id, char *oem_table_id)
return xen_pv_domain();
}
-static u32 xen_phys_pkg_id(u32 initial_apic_id, int index_msb)
-{
- return initial_apic_id >> index_msb;
-}
-
static u32 xen_cpu_present_to_apicid(int cpu)
{
if (cpu_present(cpu))
@@ -133,11 +122,9 @@ static struct apic xen_pv_apic __ro_after_init = {
.disable_esr = 0,
.cpu_present_to_apicid = xen_cpu_present_to_apicid,
- .phys_pkg_id = xen_phys_pkg_id, /* detect_ht */
.max_apic_id = UINT_MAX,
.get_apic_id = xen_get_apic_id,
- .set_apic_id = xen_set_apic_id,
.calc_dest_apicid = apic_flat_calc_apicid,
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 3c61bb98c10e..a01ca255b0c6 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -6,6 +6,7 @@
#include <linux/console.h>
#include <linux/cpu.h>
#include <linux/kexec.h>
+#include <linux/memblock.h>
#include <linux/slab.h>
#include <linux/panic_notifier.h>
@@ -350,3 +351,34 @@ void xen_arch_unregister_cpu(int num)
}
EXPORT_SYMBOL(xen_arch_unregister_cpu);
#endif
+
+/* Amount of extra memory space we add to the e820 ranges */
+struct xen_memory_region xen_extra_mem[XEN_EXTRA_MEM_MAX_REGIONS] __initdata;
+
+void __init xen_add_extra_mem(unsigned long start_pfn, unsigned long n_pfns)
+{
+ unsigned int i;
+
+ /*
+ * No need to check for zero size, should happen rarely and will only
+ * write a new entry regarded to be unused due to zero size.
+ */
+ for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) {
+ /* Add new region. */
+ if (xen_extra_mem[i].n_pfns == 0) {
+ xen_extra_mem[i].start_pfn = start_pfn;
+ xen_extra_mem[i].n_pfns = n_pfns;
+ break;
+ }
+ /* Append to existing region. */
+ if (xen_extra_mem[i].start_pfn + xen_extra_mem[i].n_pfns ==
+ start_pfn) {
+ xen_extra_mem[i].n_pfns += n_pfns;
+ break;
+ }
+ }
+ if (i == XEN_EXTRA_MEM_MAX_REGIONS)
+ printk(KERN_WARNING "Warning: not enough extra memory regions\n");
+
+ memblock_reserve(PFN_PHYS(start_pfn), PFN_PHYS(n_pfns));
+}
diff --git a/arch/x86/xen/enlighten_hvm.c b/arch/x86/xen/enlighten_hvm.c
index 3f8c34707c50..c001a2296582 100644
--- a/arch/x86/xen/enlighten_hvm.c
+++ b/arch/x86/xen/enlighten_hvm.c
@@ -148,7 +148,9 @@ static void xen_hvm_shutdown(void)
if (kexec_in_progress)
xen_reboot(SHUTDOWN_soft_reset);
}
+#endif
+#ifdef CONFIG_CRASH_DUMP
static void xen_hvm_crash_shutdown(struct pt_regs *regs)
{
native_machine_crash_shutdown(regs);
@@ -168,7 +170,7 @@ static int xen_cpu_up_prepare_hvm(unsigned int cpu)
*/
xen_uninit_lock_cpu(cpu);
- if (cpu_acpi_id(cpu) != U32_MAX)
+ if (cpu_acpi_id(cpu) != CPU_ACPIID_INVALID)
per_cpu(xen_vcpu_id, cpu) = cpu_acpi_id(cpu);
else
per_cpu(xen_vcpu_id, cpu) = cpu;
@@ -236,6 +238,8 @@ static void __init xen_hvm_guest_init(void)
#ifdef CONFIG_KEXEC_CORE
machine_ops.shutdown = xen_hvm_shutdown;
+#endif
+#ifdef CONFIG_CRASH_DUMP
machine_ops.crash_shutdown = xen_hvm_crash_shutdown;
#endif
}
diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
index aeb33e0a3f76..ace2eb054053 100644
--- a/arch/x86/xen/enlighten_pv.c
+++ b/arch/x86/xen/enlighten_pv.c
@@ -200,6 +200,9 @@ static void __init xen_pv_init_platform(void)
xen_set_mtrr_data();
else
mtrr_overwrite_state(NULL, 0, MTRR_TYPE_WRBACK);
+
+ /* Adjust nr_cpu_ids before "enumeration" happens */
+ xen_smp_count_cpus();
}
static void __init xen_pv_guest_late_init(void)
diff --git a/arch/x86/xen/enlighten_pvh.c b/arch/x86/xen/enlighten_pvh.c
index ada3868c02c2..27a2a02ef8fb 100644
--- a/arch/x86/xen/enlighten_pvh.c
+++ b/arch/x86/xen/enlighten_pvh.c
@@ -1,9 +1,11 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/acpi.h>
#include <linux/export.h>
+#include <linux/mm.h>
#include <xen/hvc-console.h>
+#include <asm/bootparam.h>
#include <asm/io_apic.h>
#include <asm/hypervisor.h>
#include <asm/e820/api.h>
@@ -72,3 +74,70 @@ void __init mem_map_via_hcall(struct boot_params *boot_params_p)
}
boot_params_p->e820_entries = memmap.nr_entries;
}
+
+/*
+ * Reserve e820 UNUSABLE regions to inflate the memory balloon.
+ *
+ * On PVH dom0 the host memory map is used, RAM regions available to dom0 are
+ * located as the same place as in the native memory map, but since dom0 gets
+ * less memory than the total amount of host RAM the ranges that can't be
+ * populated are converted from RAM -> UNUSABLE. Use such regions (up to the
+ * ratio signaled in EXTRA_MEM_RATIO) in order to inflate the balloon driver at
+ * boot. Doing so prevents the guest (even if just temporary) from using holes
+ * in the memory map in order to map grants or foreign addresses, and
+ * hopefully limits the risk of a clash with a device MMIO region. Ideally the
+ * hypervisor should notify us which memory ranges are suitable for creating
+ * foreign mappings, but that's not yet implemented.
+ */
+void __init xen_reserve_extra_memory(struct boot_params *bootp)
+{
+ unsigned int i, ram_pages = 0, extra_pages;
+
+ for (i = 0; i < bootp->e820_entries; i++) {
+ struct boot_e820_entry *e = &bootp->e820_table[i];
+
+ if (e->type != E820_TYPE_RAM)
+ continue;
+ ram_pages += PFN_DOWN(e->addr + e->size) - PFN_UP(e->addr);
+ }
+
+ /* Max amount of extra memory. */
+ extra_pages = EXTRA_MEM_RATIO * ram_pages;
+
+ /*
+ * Convert UNUSABLE ranges to RAM and reserve them for foreign mapping
+ * purposes.
+ */
+ for (i = 0; i < bootp->e820_entries && extra_pages; i++) {
+ struct boot_e820_entry *e = &bootp->e820_table[i];
+ unsigned long pages;
+
+ if (e->type != E820_TYPE_UNUSABLE)
+ continue;
+
+ pages = min(extra_pages,
+ PFN_DOWN(e->addr + e->size) - PFN_UP(e->addr));
+
+ if (pages != (PFN_DOWN(e->addr + e->size) - PFN_UP(e->addr))) {
+ struct boot_e820_entry *next;
+
+ if (bootp->e820_entries ==
+ ARRAY_SIZE(bootp->e820_table))
+ /* No space left to split - skip region. */
+ continue;
+
+ /* Split entry. */
+ next = e + 1;
+ memmove(next, e,
+ (bootp->e820_entries - i) * sizeof(*e));
+ bootp->e820_entries++;
+ next->addr = PAGE_ALIGN(e->addr) + PFN_PHYS(pages);
+ e->size = next->addr - e->addr;
+ next->size -= e->size;
+ }
+ e->type = E820_TYPE_RAM;
+ extra_pages -= pages;
+
+ xen_add_extra_mem(PFN_UP(e->addr), pages);
+ }
+}
diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c
index 72af496a160c..54e0d311dcc9 100644
--- a/arch/x86/xen/mmu_pv.c
+++ b/arch/x86/xen/mmu_pv.c
@@ -913,7 +913,7 @@ static void drop_mm_ref_this_cpu(void *info)
struct mm_struct *mm = info;
if (this_cpu_read(cpu_tlbstate.loaded_mm) == mm)
- leave_mm(smp_processor_id());
+ leave_mm();
/*
* If this cpu still has a stale cr3 reference, then make sure
@@ -1059,7 +1059,7 @@ static void __init xen_cleanmfnmap_pmd(pmd_t *pmd, bool unpin)
pte_t *pte_tbl;
int i;
- if (pmd_large(*pmd)) {
+ if (pmd_leaf(*pmd)) {
pa = pmd_val(*pmd) & PHYSICAL_PAGE_MASK;
xen_free_ro_pages(pa, PMD_SIZE);
return;
@@ -1082,7 +1082,7 @@ static void __init xen_cleanmfnmap_pud(pud_t *pud, bool unpin)
pmd_t *pmd_tbl;
int i;
- if (pud_large(*pud)) {
+ if (pud_leaf(*pud)) {
pa = pud_val(*pud) & PHYSICAL_PAGE_MASK;
xen_free_ro_pages(pa, PUD_SIZE);
return;
@@ -1104,7 +1104,7 @@ static void __init xen_cleanmfnmap_p4d(p4d_t *p4d, bool unpin)
pud_t *pud_tbl;
int i;
- if (p4d_large(*p4d)) {
+ if (p4d_leaf(*p4d)) {
pa = p4d_val(*p4d) & PHYSICAL_PAGE_MASK;
xen_free_ro_pages(pa, P4D_SIZE);
return;
@@ -1863,7 +1863,7 @@ static phys_addr_t __init xen_early_virt_to_phys(unsigned long vaddr)
if (!pud_present(pud))
return 0;
pa = pud_val(pud) & PTE_PFN_MASK;
- if (pud_large(pud))
+ if (pud_leaf(pud))
return pa + (vaddr & ~PUD_MASK);
pmd = native_make_pmd(xen_read_phys_ulong(pa + pmd_index(vaddr) *
@@ -1871,7 +1871,7 @@ static phys_addr_t __init xen_early_virt_to_phys(unsigned long vaddr)
if (!pmd_present(pmd))
return 0;
pa = pmd_val(pmd) & PTE_PFN_MASK;
- if (pmd_large(pmd))
+ if (pmd_leaf(pmd))
return pa + (vaddr & ~PMD_MASK);
pte = native_make_pte(xen_read_phys_ulong(pa + pte_index(vaddr) *
@@ -2520,7 +2520,7 @@ out:
}
EXPORT_SYMBOL_GPL(xen_remap_pfn);
-#ifdef CONFIG_KEXEC_CORE
+#ifdef CONFIG_VMCORE_INFO
phys_addr_t paddr_vmcoreinfo_note(void)
{
if (xen_pv_domain())
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index b3e37961065a..380591028cb8 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -38,9 +38,6 @@
#define GB(x) ((uint64_t)(x) * 1024 * 1024 * 1024)
-/* Amount of extra memory space we add to the e820 ranges */
-struct xen_memory_region xen_extra_mem[XEN_EXTRA_MEM_MAX_REGIONS] __initdata;
-
/* Number of pages released from the initial allocation. */
unsigned long xen_released_pages;
@@ -64,18 +61,6 @@ static struct {
} xen_remap_buf __initdata __aligned(PAGE_SIZE);
static unsigned long xen_remap_mfn __initdata = INVALID_P2M_ENTRY;
-/*
- * The maximum amount of extra memory compared to the base size. The
- * main scaling factor is the size of struct page. At extreme ratios
- * of base:extra, all the base memory can be filled with page
- * structures for the extra memory, leaving no space for anything
- * else.
- *
- * 10x seems like a reasonable balance between scaling flexibility and
- * leaving a practically usable system.
- */
-#define EXTRA_MEM_RATIO (10)
-
static bool xen_512gb_limit __initdata = IS_ENABLED(CONFIG_XEN_512GB);
static void __init xen_parse_512gb(void)
@@ -96,35 +81,6 @@ static void __init xen_parse_512gb(void)
xen_512gb_limit = val;
}
-static void __init xen_add_extra_mem(unsigned long start_pfn,
- unsigned long n_pfns)
-{
- int i;
-
- /*
- * No need to check for zero size, should happen rarely and will only
- * write a new entry regarded to be unused due to zero size.
- */
- for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) {
- /* Add new region. */
- if (xen_extra_mem[i].n_pfns == 0) {
- xen_extra_mem[i].start_pfn = start_pfn;
- xen_extra_mem[i].n_pfns = n_pfns;
- break;
- }
- /* Append to existing region. */
- if (xen_extra_mem[i].start_pfn + xen_extra_mem[i].n_pfns ==
- start_pfn) {
- xen_extra_mem[i].n_pfns += n_pfns;
- break;
- }
- }
- if (i == XEN_EXTRA_MEM_MAX_REGIONS)
- printk(KERN_WARNING "Warning: not enough extra memory regions\n");
-
- memblock_reserve(PFN_PHYS(start_pfn), PFN_PHYS(n_pfns));
-}
-
static void __init xen_del_extra_mem(unsigned long start_pfn,
unsigned long n_pfns)
{
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 1fb9a1644d94..935771726f9c 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -135,8 +135,6 @@ void __init xen_smp_cpus_done(unsigned int max_cpus)
{
if (xen_hvm_domain())
native_smp_cpus_done(max_cpus);
- else
- calculate_max_logical_packages();
}
void xen_smp_send_reschedule(int cpu)
diff --git a/arch/x86/xen/smp.h b/arch/x86/xen/smp.h
index c20cbb14c82b..b8efdbc693f7 100644
--- a/arch/x86/xen/smp.h
+++ b/arch/x86/xen/smp.h
@@ -19,6 +19,7 @@ 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);
@@ -44,6 +45,7 @@ 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_pv.c b/arch/x86/xen/smp_pv.c
index a0f07bbfcd6e..27d1a5b7f571 100644
--- a/arch/x86/xen/smp_pv.c
+++ b/arch/x86/xen/smp_pv.c
@@ -29,6 +29,7 @@
#include <asm/idtentry.h>
#include <asm/desc.h>
#include <asm/cpu.h>
+#include <asm/apic.h>
#include <asm/io_apic.h>
#include <xen/interface/xen.h>
@@ -73,7 +74,6 @@ static void cpu_bringup(void)
}
cpu = smp_processor_id();
smp_store_cpu_info(cpu);
- cpu_data(cpu).x86_max_cores = 1;
set_cpu_sibling_map(cpu);
speculative_store_bypass_ht_init();
@@ -149,39 +149,16 @@ int xen_smp_intr_init_pv(unsigned int cpu)
return rc;
}
-static void __init _get_smp_config(unsigned int early)
+static void __init xen_pv_smp_config(void)
{
- int i, rc;
- unsigned int subtract = 0;
-
- if (early)
- return;
-
- num_processors = 0;
- disabled_cpus = 0;
- for (i = 0; i < nr_cpu_ids; i++) {
- rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL);
- if (rc >= 0) {
- num_processors++;
- set_cpu_possible(i, true);
- } else {
- set_cpu_possible(i, false);
- set_cpu_present(i, false);
- subtract++;
- }
- }
-#ifdef CONFIG_HOTPLUG_CPU
- /* This is akin to using 'nr_cpus' on the Linux command line.
- * Which is OK as when we use 'dom0_max_vcpus=X' we can only
- * have up to X, while nr_cpu_ids is greater than X. This
- * normally is not a problem, except when CPU hotplugging
- * is involved and then there might be more than X CPUs
- * in the guest - which will not work as there is no
- * hypercall to expand the max number of VCPUs an already
- * running guest has. So cap it up to X. */
- if (subtract)
- set_nr_cpu_ids(nr_cpu_ids - subtract);
-#endif
+ u32 apicid = 0;
+ int i;
+
+ topology_register_boot_apic(apicid++);
+
+ for (i = 1; i < nr_cpu_ids; i++)
+ topology_register_apic(apicid++, CPU_ACPIID_INVALID, true);
+
/* Pretend to be a proper enumerated system */
smp_found_config = 1;
}
@@ -224,8 +201,6 @@ static void __init xen_pv_smp_prepare_cpus(unsigned int max_cpus)
smp_prepare_cpus_common();
- cpu_data(0).x86_max_cores = 1;
-
speculative_store_bypass_ht_init();
xen_pmu_init(0);
@@ -434,6 +409,20 @@ static irqreturn_t xen_irq_work_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
+void __init xen_smp_count_cpus(void)
+{
+ unsigned int cpus;
+
+ for (cpus = 0; cpus < nr_cpu_ids; cpus++) {
+ if (HYPERVISOR_vcpu_op(VCPUOP_is_up, cpus, NULL) < 0)
+ break;
+ }
+
+ pr_info("Xen PV: Detected %u vCPUS\n", cpus);
+ if (cpus < nr_cpu_ids)
+ set_nr_cpu_ids(cpus);
+}
+
static const struct smp_ops xen_smp_ops __initconst = {
.smp_prepare_boot_cpu = xen_pv_smp_prepare_boot_cpu,
.smp_prepare_cpus = xen_pv_smp_prepare_cpus,
@@ -458,6 +447,12 @@ void __init xen_smp_init(void)
smp_ops = xen_smp_ops;
/* Avoid searching for BIOS MP tables */
- x86_init.mpparse.find_smp_config = x86_init_noop;
- x86_init.mpparse.get_smp_config = _get_smp_config;
+ x86_init.mpparse.find_mptable = x86_init_noop;
+ x86_init.mpparse.early_parse_smp_cfg = x86_init_noop;
+
+ /* XEN/PV Dom0 has halfways sane topology information via CPUID/MADT */
+ if (xen_initial_domain())
+ x86_init.mpparse.parse_smp_cfg = x86_init_noop;
+ else
+ x86_init.mpparse.parse_smp_cfg = xen_pv_smp_config;
}
diff --git a/arch/x86/xen/vga.c b/arch/x86/xen/vga.c
index d97adab8420f..f7547807b0bd 100644
--- a/arch/x86/xen/vga.c
+++ b/arch/x86/xen/vga.c
@@ -2,7 +2,6 @@
#include <linux/screen_info.h>
#include <linux/init.h>
-#include <asm/bootparam.h>
#include <asm/setup.h>
#include <xen/interface/xen.h>
diff --git a/arch/x86/xen/xen-asm.S b/arch/x86/xen/xen-asm.S
index 1a9cd18dfbd3..83189cf5cdce 100644
--- a/arch/x86/xen/xen-asm.S
+++ b/arch/x86/xen/xen-asm.S
@@ -28,7 +28,7 @@
* non-zero.
*/
SYM_FUNC_START(xen_irq_disable_direct)
- movb $1, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
+ movb $1, PER_CPU_VAR(xen_vcpu_info + XEN_vcpu_info_mask)
RET
SYM_FUNC_END(xen_irq_disable_direct)
@@ -69,7 +69,7 @@ SYM_FUNC_END(check_events)
SYM_FUNC_START(xen_irq_enable_direct)
FRAME_BEGIN
/* Unmask events */
- movb $0, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
+ movb $0, PER_CPU_VAR(xen_vcpu_info + XEN_vcpu_info_mask)
/*
* Preempt here doesn't matter because that will deal with any
@@ -78,7 +78,7 @@ SYM_FUNC_START(xen_irq_enable_direct)
*/
/* Test for pending */
- testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_pending
+ testb $0xff, PER_CPU_VAR(xen_vcpu_info + XEN_vcpu_info_pending)
jz 1f
call check_events
@@ -97,7 +97,7 @@ SYM_FUNC_END(xen_irq_enable_direct)
* x86 use opposite senses (mask vs enable).
*/
SYM_FUNC_START(xen_save_fl_direct)
- testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
+ testb $0xff, PER_CPU_VAR(xen_vcpu_info + XEN_vcpu_info_mask)
setz %ah
addb %ah, %ah
RET
@@ -113,7 +113,7 @@ SYM_FUNC_END(xen_read_cr2);
SYM_FUNC_START(xen_read_cr2_direct)
FRAME_BEGIN
- _ASM_MOV PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_arch_cr2, %_ASM_AX
+ _ASM_MOV PER_CPU_VAR(xen_vcpu_info + XEN_vcpu_info_arch_cr2), %_ASM_AX
FRAME_END
RET
SYM_FUNC_END(xen_read_cr2_direct);
diff --git a/arch/x86/xen/xen-head.S b/arch/x86/xen/xen-head.S
index a0ea285878db..04101b984f24 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 - PTREGS_SIZE)(%rip), %rsp
+ leaq (__end_init_task - TOP_OF_KERNEL_STACK_PADDING - PTREGS_SIZE)(%rip), %rsp
/* Set up %gs.
*
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
index a87ab36889e7..79cf93f2c92f 100644
--- a/arch/x86/xen/xen-ops.h
+++ b/arch/x86/xen/xen-ops.h
@@ -163,4 +163,18 @@ void xen_hvm_post_suspend(int suspend_cancelled);
static inline void xen_hvm_post_suspend(int suspend_cancelled) {}
#endif
+/*
+ * The maximum amount of extra memory compared to the base size. The
+ * main scaling factor is the size of struct page. At extreme ratios
+ * of base:extra, all the base memory can be filled with page
+ * structures for the extra memory, leaving no space for anything
+ * else.
+ *
+ * 10x seems like a reasonable balance between scaling flexibility and
+ * leaving a practically usable system.
+ */
+#define EXTRA_MEM_RATIO (10)
+
+void xen_add_extra_mem(unsigned long start_pfn, unsigned long n_pfns);
+
#endif /* XEN_OPS_H */
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 6f248d87e496..f200a4ec044e 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -2,6 +2,7 @@
config XTENSA
def_bool y
select ARCH_32BIT_OFF_T
+ select ARCH_HAS_CPU_CACHE_ALIASING
select ARCH_HAS_BINFMT_FLAT if !MMU
select ARCH_HAS_CURRENT_STACK_POINTER
select ARCH_HAS_DEBUG_VM_PGTABLE
@@ -44,6 +45,7 @@ config XTENSA
select HAVE_GCC_PLUGINS if GCC_VERSION >= 120000
select HAVE_HW_BREAKPOINT if PERF_EVENTS
select HAVE_IRQ_TIME_ACCOUNTING
+ select HAVE_PAGE_SIZE_4KB
select HAVE_PCI
select HAVE_PERF_EVENTS
select HAVE_STACKPROTECTOR
diff --git a/arch/xtensa/include/asm/cachetype.h b/arch/xtensa/include/asm/cachetype.h
new file mode 100644
index 000000000000..51bd49e2a1c5
--- /dev/null
+++ b/arch/xtensa/include/asm/cachetype.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_XTENSA_CACHETYPE_H
+#define __ASM_XTENSA_CACHETYPE_H
+
+#include <asm/cache.h>
+#include <asm/page.h>
+
+#define cpu_dcache_is_aliasing() (DCACHE_WAY_SIZE > PAGE_SIZE)
+
+#endif
diff --git a/arch/xtensa/include/asm/page.h b/arch/xtensa/include/asm/page.h
index a77d04972eb9..4db56ef052d2 100644
--- a/arch/xtensa/include/asm/page.h
+++ b/arch/xtensa/include/asm/page.h
@@ -22,7 +22,7 @@
* PAGE_SHIFT determines the page size
*/
-#define PAGE_SHIFT 12
+#define PAGE_SHIFT CONFIG_PAGE_SHIFT
#define PAGE_SIZE (__XTENSA_UL_CONST(1) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
diff --git a/arch/xtensa/platforms/iss/simdisk.c b/arch/xtensa/platforms/iss/simdisk.c
index 178cf96ca10a..defc67909a9c 100644
--- a/arch/xtensa/platforms/iss/simdisk.c
+++ b/arch/xtensa/platforms/iss/simdisk.c
@@ -264,16 +264,18 @@ static int __init simdisk_setup(struct simdisk *dev, int which,
struct proc_dir_entry *procdir)
{
char tmp[2] = { '0' + which, 0 };
- int err = -ENOMEM;
+ int err;
dev->fd = -1;
dev->filename = NULL;
spin_lock_init(&dev->lock);
dev->users = 0;
- dev->gd = blk_alloc_disk(NUMA_NO_NODE);
- if (!dev->gd)
+ dev->gd = blk_alloc_disk(NULL, NUMA_NO_NODE);
+ if (IS_ERR(dev->gd)) {
+ err = PTR_ERR(dev->gd);
goto out;
+ }
dev->gd->major = simdisk_major;
dev->gd->first_minor = which;
dev->gd->minors = SIMDISK_MINORS;